@aerokit/sdk 12.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +277 -0
- package/README.md +170 -0
- package/dist/cjs/bpm/deployer.js +57 -0
- package/dist/cjs/bpm/index.js +35 -0
- package/dist/cjs/bpm/process.js +636 -0
- package/dist/cjs/bpm/tasks.js +973 -0
- package/dist/cjs/bpm/values.js +82 -0
- package/dist/cjs/cache/cache.js +64 -0
- package/dist/cjs/cache/index.js +26 -0
- package/dist/cjs/cms/cmis.js +689 -0
- package/dist/cjs/cms/index.js +26 -0
- package/dist/cjs/component/decorators.js +126 -0
- package/dist/cjs/component/index.js +36 -0
- package/dist/cjs/core/configurations.js +110 -0
- package/dist/cjs/core/context.js +47 -0
- package/dist/cjs/core/env.js +45 -0
- package/dist/cjs/core/globals.js +54 -0
- package/dist/cjs/core/index.js +35 -0
- package/dist/cjs/db/dao.js +795 -0
- package/dist/cjs/db/database.js +904 -0
- package/dist/cjs/db/decorators.js +167 -0
- package/dist/cjs/db/index.js +72 -0
- package/dist/cjs/db/insert.js +51 -0
- package/dist/cjs/db/orm.js +245 -0
- package/dist/cjs/db/ormstatements.js +243 -0
- package/dist/cjs/db/procedure.js +112 -0
- package/dist/cjs/db/query.js +57 -0
- package/dist/cjs/db/repository.js +148 -0
- package/dist/cjs/db/sequence.js +59 -0
- package/dist/cjs/db/sql.js +516 -0
- package/dist/cjs/db/store.js +172 -0
- package/dist/cjs/db/translator.js +100 -0
- package/dist/cjs/db/update.js +43 -0
- package/dist/cjs/etcd/client.js +174 -0
- package/dist/cjs/etcd/index.js +26 -0
- package/dist/cjs/extensions/decorators.js +40 -0
- package/dist/cjs/extensions/extensions.js +108 -0
- package/dist/cjs/extensions/index.js +39 -0
- package/dist/cjs/git/client.js +277 -0
- package/dist/cjs/git/index.js +26 -0
- package/dist/cjs/http/client-async.js +224 -0
- package/dist/cjs/http/client.js +145 -0
- package/dist/cjs/http/decorators.js +76 -0
- package/dist/cjs/http/errors/ForbiddenError.js +41 -0
- package/dist/cjs/http/errors/ValidationError.js +41 -0
- package/dist/cjs/http/errors.js +26 -0
- package/dist/cjs/http/index.js +59 -0
- package/dist/cjs/http/request.js +281 -0
- package/dist/cjs/http/response.js +452 -0
- package/dist/cjs/http/rs/resource-common.js +32 -0
- package/dist/cjs/http/rs/resource-http-controller.js +306 -0
- package/dist/cjs/http/rs/resource-mappings.js +130 -0
- package/dist/cjs/http/rs/resource-method.js +218 -0
- package/dist/cjs/http/rs/resource.js +232 -0
- package/dist/cjs/http/rs.js +31 -0
- package/dist/cjs/http/session.js +124 -0
- package/dist/cjs/http/upload.js +144 -0
- package/dist/cjs/http/utils.js +106 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/indexing/index.js +29 -0
- package/dist/cjs/indexing/searcher.js +70 -0
- package/dist/cjs/indexing/writer.js +45 -0
- package/dist/cjs/integrations/index.js +26 -0
- package/dist/cjs/integrations/integrations.js +55 -0
- package/dist/cjs/io/bytes.js +101 -0
- package/dist/cjs/io/files.js +344 -0
- package/dist/cjs/io/image.js +43 -0
- package/dist/cjs/io/index.js +38 -0
- package/dist/cjs/io/streams.js +243 -0
- package/dist/cjs/io/zip.js +251 -0
- package/dist/cjs/job/decorators.js +40 -0
- package/dist/cjs/job/index.js +39 -0
- package/dist/cjs/job/scheduler.js +347 -0
- package/dist/cjs/junit/index.js +18 -0
- package/dist/cjs/junit/junit.js +67 -0
- package/dist/cjs/kafka/consumer.js +70 -0
- package/dist/cjs/kafka/index.js +29 -0
- package/dist/cjs/kafka/producer.js +70 -0
- package/dist/cjs/log/index.js +26 -0
- package/dist/cjs/log/logging.js +174 -0
- package/dist/cjs/mail/client.js +153 -0
- package/dist/cjs/mail/index.js +26 -0
- package/dist/cjs/messaging/consumer.js +83 -0
- package/dist/cjs/messaging/decorators.js +40 -0
- package/dist/cjs/messaging/index.js +42 -0
- package/dist/cjs/messaging/producer.js +81 -0
- package/dist/cjs/mongodb/client.js +627 -0
- package/dist/cjs/mongodb/dao.js +390 -0
- package/dist/cjs/mongodb/index.js +36 -0
- package/dist/cjs/net/decorators.js +40 -0
- package/dist/cjs/net/index.js +42 -0
- package/dist/cjs/net/soap.js +228 -0
- package/dist/cjs/net/websockets.js +151 -0
- package/dist/cjs/net/wrappers/onClose.js +2 -0
- package/dist/cjs/net/wrappers/onError.js +2 -0
- package/dist/cjs/net/wrappers/onMessage.js +2 -0
- package/dist/cjs/net/wrappers/onOpen.js +2 -0
- package/dist/cjs/pdf/index.js +26 -0
- package/dist/cjs/pdf/pdf.js +160 -0
- package/dist/cjs/platform/command.js +47 -0
- package/dist/cjs/platform/engines.js +70 -0
- package/dist/cjs/platform/index.js +47 -0
- package/dist/cjs/platform/lifecycle.js +49 -0
- package/dist/cjs/platform/os.js +51 -0
- package/dist/cjs/platform/problems.js +127 -0
- package/dist/cjs/platform/registry.js +319 -0
- package/dist/cjs/platform/repository.js +498 -0
- package/dist/cjs/platform/workspace.js +574 -0
- package/dist/cjs/qldb/index.js +26 -0
- package/dist/cjs/qldb/qldb.js +24 -0
- package/dist/cjs/rabbitmq/consumer.js +50 -0
- package/dist/cjs/rabbitmq/index.js +29 -0
- package/dist/cjs/rabbitmq/producer.js +38 -0
- package/dist/cjs/redis/client.js +190 -0
- package/dist/cjs/redis/index.js +26 -0
- package/dist/cjs/security/decorators.js +48 -0
- package/dist/cjs/security/index.js +40 -0
- package/dist/cjs/security/oauth.js +75 -0
- package/dist/cjs/security/user.js +88 -0
- package/dist/cjs/template/engines.js +139 -0
- package/dist/cjs/template/index.js +26 -0
- package/dist/cjs/utils/alphanumeric.js +107 -0
- package/dist/cjs/utils/base64.js +104 -0
- package/dist/cjs/utils/converter.js +78 -0
- package/dist/cjs/utils/digest.js +167 -0
- package/dist/cjs/utils/escape.js +160 -0
- package/dist/cjs/utils/hex.js +104 -0
- package/dist/cjs/utils/index.js +68 -0
- package/dist/cjs/utils/jsonpath.js +489 -0
- package/dist/cjs/utils/qrcode.js +41 -0
- package/dist/cjs/utils/url.js +82 -0
- package/dist/cjs/utils/utf8.js +61 -0
- package/dist/cjs/utils/uuid.js +48 -0
- package/dist/cjs/utils/xml.js +57 -0
- package/dist/dts/bpm/deployer.d.ts +29 -0
- package/dist/dts/bpm/index.d.ts +8 -0
- package/dist/dts/bpm/process.d.ts +433 -0
- package/dist/dts/bpm/tasks.d.ts +2022 -0
- package/dist/dts/bpm/values.d.ts +38 -0
- package/dist/dts/cache/cache.d.ts +30 -0
- package/dist/dts/cache/index.d.ts +2 -0
- package/dist/dts/cms/cmis.d.ts +413 -0
- package/dist/dts/cms/index.d.ts +2 -0
- package/dist/dts/component/decorators.d.ts +52 -0
- package/dist/dts/component/index.d.ts +2 -0
- package/dist/dts/core/configurations.d.ts +65 -0
- package/dist/dts/core/context.d.ts +19 -0
- package/dist/dts/core/env.d.ts +23 -0
- package/dist/dts/core/globals.d.ts +30 -0
- package/dist/dts/core/index.d.ts +8 -0
- package/dist/dts/db/dao.d.ts +8 -0
- package/dist/dts/db/database.d.ts +507 -0
- package/dist/dts/db/decorators.d.ts +89 -0
- package/dist/dts/db/index.d.ts +25 -0
- package/dist/dts/db/insert.d.ts +32 -0
- package/dist/dts/db/orm.d.ts +44 -0
- package/dist/dts/db/ormstatements.d.ts +4 -0
- package/dist/dts/db/procedure.d.ts +25 -0
- package/dist/dts/db/query.d.ts +48 -0
- package/dist/dts/db/repository.d.ts +64 -0
- package/dist/dts/db/sequence.d.ts +34 -0
- package/dist/dts/db/sql.d.ts +267 -0
- package/dist/dts/db/store.d.ts +138 -0
- package/dist/dts/db/translator.d.ts +26 -0
- package/dist/dts/db/update.d.ts +21 -0
- package/dist/dts/etcd/client.d.ts +92 -0
- package/dist/dts/etcd/index.d.ts +2 -0
- package/dist/dts/extensions/decorators.d.ts +11 -0
- package/dist/dts/extensions/extensions.d.ts +41 -0
- package/dist/dts/extensions/index.d.ts +4 -0
- package/dist/dts/git/client.d.ts +478 -0
- package/dist/dts/git/index.d.ts +2 -0
- package/dist/dts/http/client-async.d.ts +158 -0
- package/dist/dts/http/client.d.ts +180 -0
- package/dist/dts/http/decorators.d.ts +11 -0
- package/dist/dts/http/errors/ForbiddenError.d.ts +20 -0
- package/dist/dts/http/errors/ValidationError.d.ts +20 -0
- package/dist/dts/http/errors.d.ts +2 -0
- package/dist/dts/http/index.d.ts +16 -0
- package/dist/dts/http/request.d.ts +158 -0
- package/dist/dts/http/response.d.ts +281 -0
- package/dist/dts/http/rs/resource-common.d.ts +11 -0
- package/dist/dts/http/rs/resource-http-controller.d.ts +43 -0
- package/dist/dts/http/rs/resource-mappings.d.ts +70 -0
- package/dist/dts/http/rs/resource-method.d.ts +206 -0
- package/dist/dts/http/rs/resource.d.ts +126 -0
- package/dist/dts/http/rs.d.ts +4 -0
- package/dist/dts/http/session.d.ts +81 -0
- package/dist/dts/http/upload.d.ts +100 -0
- package/dist/dts/http/utils.d.ts +54 -0
- package/dist/dts/index.d.ts +0 -0
- package/dist/dts/indexing/index.d.ts +4 -0
- package/dist/dts/indexing/searcher.d.ts +47 -0
- package/dist/dts/indexing/writer.d.ts +22 -0
- package/dist/dts/integrations/index.d.ts +2 -0
- package/dist/dts/integrations/integrations.d.ts +118 -0
- package/dist/dts/io/bytes.d.ts +56 -0
- package/dist/dts/io/files.d.ts +261 -0
- package/dist/dts/io/image.d.ts +22 -0
- package/dist/dts/io/index.d.ts +10 -0
- package/dist/dts/io/streams.d.ts +172 -0
- package/dist/dts/io/zip.d.ts +178 -0
- package/dist/dts/job/decorators.d.ts +11 -0
- package/dist/dts/job/index.d.ts +4 -0
- package/dist/dts/job/scheduler.d.ts +250 -0
- package/dist/dts/junit/index.d.ts +1 -0
- package/dist/dts/junit/junit.d.ts +50 -0
- package/dist/dts/kafka/consumer.d.ts +48 -0
- package/dist/dts/kafka/index.d.ts +4 -0
- package/dist/dts/kafka/producer.d.ts +50 -0
- package/dist/dts/log/index.d.ts +2 -0
- package/dist/dts/log/logging.d.ts +102 -0
- package/dist/dts/mail/client.d.ts +90 -0
- package/dist/dts/mail/index.d.ts +2 -0
- package/dist/dts/messaging/consumer.d.ts +61 -0
- package/dist/dts/messaging/decorators.d.ts +11 -0
- package/dist/dts/messaging/index.d.ts +6 -0
- package/dist/dts/messaging/producer.d.ts +59 -0
- package/dist/dts/mongodb/client.d.ts +367 -0
- package/dist/dts/mongodb/dao.d.ts +24 -0
- package/dist/dts/mongodb/index.d.ts +2 -0
- package/dist/dts/net/decorators.d.ts +11 -0
- package/dist/dts/net/index.d.ts +6 -0
- package/dist/dts/net/soap.d.ts +115 -0
- package/dist/dts/net/websockets.d.ts +100 -0
- package/dist/dts/net/wrappers/onClose.d.ts +0 -0
- package/dist/dts/net/wrappers/onError.d.ts +0 -0
- package/dist/dts/net/wrappers/onMessage.d.ts +0 -0
- package/dist/dts/net/wrappers/onOpen.d.ts +0 -0
- package/dist/dts/pdf/index.d.ts +2 -0
- package/dist/dts/pdf/pdf.d.ts +72 -0
- package/dist/dts/platform/command.d.ts +41 -0
- package/dist/dts/platform/engines.d.ts +35 -0
- package/dist/dts/platform/index.d.ts +16 -0
- package/dist/dts/platform/lifecycle.d.ts +22 -0
- package/dist/dts/platform/os.d.ts +23 -0
- package/dist/dts/platform/problems.d.ts +114 -0
- package/dist/dts/platform/registry.d.ts +227 -0
- package/dist/dts/platform/repository.d.ts +354 -0
- package/dist/dts/platform/workspace.d.ts +421 -0
- package/dist/dts/qldb/index.d.ts +2 -0
- package/dist/dts/qldb/qldb.d.ts +1 -0
- package/dist/dts/rabbitmq/consumer.d.ts +25 -0
- package/dist/dts/rabbitmq/index.d.ts +4 -0
- package/dist/dts/rabbitmq/producer.d.ts +15 -0
- package/dist/dts/redis/client.d.ts +134 -0
- package/dist/dts/redis/index.d.ts +2 -0
- package/dist/dts/security/decorators.d.ts +4 -0
- package/dist/dts/security/index.d.ts +5 -0
- package/dist/dts/security/oauth.d.ts +39 -0
- package/dist/dts/security/user.d.ts +51 -0
- package/dist/dts/template/engines.d.ts +98 -0
- package/dist/dts/template/index.d.ts +2 -0
- package/dist/dts/utils/alphanumeric.d.ts +39 -0
- package/dist/dts/utils/base64.d.ts +48 -0
- package/dist/dts/utils/converter.d.ts +44 -0
- package/dist/dts/utils/digest.d.ts +50 -0
- package/dist/dts/utils/escape.d.ts +110 -0
- package/dist/dts/utils/hex.d.ts +48 -0
- package/dist/dts/utils/index.d.ts +23 -0
- package/dist/dts/utils/jsonpath.d.ts +22 -0
- package/dist/dts/utils/qrcode.d.ts +16 -0
- package/dist/dts/utils/url.d.ts +50 -0
- package/dist/dts/utils/utf8.d.ts +33 -0
- package/dist/dts/utils/uuid.d.ts +21 -0
- package/dist/dts/utils/xml.d.ts +22 -0
- package/dist/esm/bpm/deployer.mjs +38 -0
- package/dist/esm/bpm/index.mjs +15 -0
- package/dist/esm/bpm/process.mjs +617 -0
- package/dist/esm/bpm/tasks.mjs +954 -0
- package/dist/esm/bpm/values.mjs +63 -0
- package/dist/esm/cache/cache.mjs +45 -0
- package/dist/esm/cache/index.mjs +6 -0
- package/dist/esm/cms/cmis.mjs +660 -0
- package/dist/esm/cms/index.mjs +6 -0
- package/dist/esm/component/decorators.mjs +107 -0
- package/dist/esm/component/index.mjs +6 -0
- package/dist/esm/core/configurations.mjs +91 -0
- package/dist/esm/core/context.mjs +28 -0
- package/dist/esm/core/env.mjs +26 -0
- package/dist/esm/core/globals.mjs +35 -0
- package/dist/esm/core/index.mjs +15 -0
- package/dist/esm/db/dao.mjs +775 -0
- package/dist/esm/db/database.mjs +885 -0
- package/dist/esm/db/decorators.mjs +148 -0
- package/dist/esm/db/index.mjs +42 -0
- package/dist/esm/db/insert.mjs +32 -0
- package/dist/esm/db/orm.mjs +225 -0
- package/dist/esm/db/ormstatements.mjs +223 -0
- package/dist/esm/db/procedure.mjs +93 -0
- package/dist/esm/db/query.mjs +38 -0
- package/dist/esm/db/repository.mjs +129 -0
- package/dist/esm/db/sequence.mjs +40 -0
- package/dist/esm/db/sql.mjs +497 -0
- package/dist/esm/db/store.mjs +153 -0
- package/dist/esm/db/translator.mjs +81 -0
- package/dist/esm/db/update.mjs +24 -0
- package/dist/esm/etcd/client.mjs +155 -0
- package/dist/esm/etcd/index.mjs +6 -0
- package/dist/esm/extensions/decorators.mjs +21 -0
- package/dist/esm/extensions/extensions.mjs +89 -0
- package/dist/esm/extensions/index.mjs +9 -0
- package/dist/esm/git/client.mjs +258 -0
- package/dist/esm/git/index.mjs +6 -0
- package/dist/esm/http/client-async.mjs +205 -0
- package/dist/esm/http/client.mjs +126 -0
- package/dist/esm/http/decorators.mjs +47 -0
- package/dist/esm/http/errors/ForbiddenError.mjs +22 -0
- package/dist/esm/http/errors/ValidationError.mjs +22 -0
- package/dist/esm/http/errors.mjs +7 -0
- package/dist/esm/http/index.mjs +29 -0
- package/dist/esm/http/request.mjs +262 -0
- package/dist/esm/http/response.mjs +433 -0
- package/dist/esm/http/rs/resource-common.mjs +13 -0
- package/dist/esm/http/rs/resource-http-controller.mjs +287 -0
- package/dist/esm/http/rs/resource-mappings.mjs +111 -0
- package/dist/esm/http/rs/resource-method.mjs +199 -0
- package/dist/esm/http/rs/resource.mjs +213 -0
- package/dist/esm/http/rs.mjs +12 -0
- package/dist/esm/http/session.mjs +105 -0
- package/dist/esm/http/upload.mjs +125 -0
- package/dist/esm/http/utils.mjs +87 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/indexing/index.mjs +9 -0
- package/dist/esm/indexing/searcher.mjs +51 -0
- package/dist/esm/indexing/writer.mjs +26 -0
- package/dist/esm/integrations/index.mjs +6 -0
- package/dist/esm/integrations/integrations.mjs +36 -0
- package/dist/esm/io/bytes.mjs +82 -0
- package/dist/esm/io/files.mjs +325 -0
- package/dist/esm/io/image.mjs +24 -0
- package/dist/esm/io/index.mjs +18 -0
- package/dist/esm/io/streams.mjs +224 -0
- package/dist/esm/io/zip.mjs +232 -0
- package/dist/esm/job/decorators.mjs +21 -0
- package/dist/esm/job/index.mjs +9 -0
- package/dist/esm/job/scheduler.mjs +328 -0
- package/dist/esm/junit/index.mjs +2 -0
- package/dist/esm/junit/junit.mjs +48 -0
- package/dist/esm/kafka/consumer.mjs +51 -0
- package/dist/esm/kafka/index.mjs +9 -0
- package/dist/esm/kafka/producer.mjs +51 -0
- package/dist/esm/log/index.mjs +6 -0
- package/dist/esm/log/logging.mjs +155 -0
- package/dist/esm/mail/client.mjs +134 -0
- package/dist/esm/mail/index.mjs +6 -0
- package/dist/esm/messaging/consumer.mjs +64 -0
- package/dist/esm/messaging/decorators.mjs +21 -0
- package/dist/esm/messaging/index.mjs +12 -0
- package/dist/esm/messaging/producer.mjs +62 -0
- package/dist/esm/mongodb/client.mjs +608 -0
- package/dist/esm/mongodb/dao.mjs +360 -0
- package/dist/esm/mongodb/index.mjs +7 -0
- package/dist/esm/net/decorators.mjs +21 -0
- package/dist/esm/net/index.mjs +12 -0
- package/dist/esm/net/soap.mjs +209 -0
- package/dist/esm/net/websockets.mjs +132 -0
- package/dist/esm/net/wrappers/onClose.mjs +2 -0
- package/dist/esm/net/wrappers/onError.mjs +2 -0
- package/dist/esm/net/wrappers/onMessage.mjs +2 -0
- package/dist/esm/net/wrappers/onOpen.mjs +2 -0
- package/dist/esm/pdf/index.mjs +6 -0
- package/dist/esm/pdf/pdf.mjs +141 -0
- package/dist/esm/platform/command.mjs +28 -0
- package/dist/esm/platform/engines.mjs +51 -0
- package/dist/esm/platform/index.mjs +27 -0
- package/dist/esm/platform/lifecycle.mjs +30 -0
- package/dist/esm/platform/os.mjs +32 -0
- package/dist/esm/platform/problems.mjs +108 -0
- package/dist/esm/platform/registry.mjs +300 -0
- package/dist/esm/platform/repository.mjs +479 -0
- package/dist/esm/platform/workspace.mjs +555 -0
- package/dist/esm/qldb/index.mjs +6 -0
- package/dist/esm/qldb/qldb.mjs +5 -0
- package/dist/esm/rabbitmq/consumer.mjs +31 -0
- package/dist/esm/rabbitmq/index.mjs +9 -0
- package/dist/esm/rabbitmq/producer.mjs +19 -0
- package/dist/esm/redis/client.mjs +171 -0
- package/dist/esm/redis/index.mjs +6 -0
- package/dist/esm/security/decorators.mjs +29 -0
- package/dist/esm/security/index.mjs +10 -0
- package/dist/esm/security/oauth.mjs +56 -0
- package/dist/esm/security/user.mjs +69 -0
- package/dist/esm/template/engines.mjs +120 -0
- package/dist/esm/template/index.mjs +6 -0
- package/dist/esm/utils/alphanumeric.mjs +88 -0
- package/dist/esm/utils/base64.mjs +85 -0
- package/dist/esm/utils/converter.mjs +59 -0
- package/dist/esm/utils/digest.mjs +148 -0
- package/dist/esm/utils/escape.mjs +141 -0
- package/dist/esm/utils/hex.mjs +85 -0
- package/dist/esm/utils/index.mjs +38 -0
- package/dist/esm/utils/jsonpath.mjs +470 -0
- package/dist/esm/utils/qrcode.mjs +22 -0
- package/dist/esm/utils/url.mjs +63 -0
- package/dist/esm/utils/utf8.mjs +42 -0
- package/dist/esm/utils/uuid.mjs +29 -0
- package/dist/esm/utils/xml.mjs +38 -0
- package/package.json +58 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var dao_exports = {};
|
|
20
|
+
__export(dao_exports, {
|
|
21
|
+
DAO: () => DAO,
|
|
22
|
+
create: () => create,
|
|
23
|
+
dao: () => dao
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(dao_exports);
|
|
26
|
+
var import_orm = require("./orm");
|
|
27
|
+
var import_ormstatements = require("./ormstatements");
|
|
28
|
+
var import_sequence = require("./sequence");
|
|
29
|
+
var import_database = require("./database");
|
|
30
|
+
var import_db = require("@aerokit/sdk/db");
|
|
31
|
+
var import_update = require("./update");
|
|
32
|
+
var import_insert = require("./insert");
|
|
33
|
+
var import_log = require("@aerokit/sdk/log");
|
|
34
|
+
var import_core = require("@aerokit/sdk/core");
|
|
35
|
+
function DAO(orm, logCtxName, dataSourceName) {
|
|
36
|
+
if (orm === void 0)
|
|
37
|
+
throw Error("Illegal argument: orm[" + orm + "]");
|
|
38
|
+
this.orm = (0, import_orm.get)(orm);
|
|
39
|
+
this.sequenceName = this.orm.table + "_" + this.orm.getPrimaryKey().name.toUpperCase();
|
|
40
|
+
this.dropIdGenerator = function() {
|
|
41
|
+
return import_sequence.Sequence.drop(this.sequenceName, dataSourceName);
|
|
42
|
+
};
|
|
43
|
+
this.generateId = function() {
|
|
44
|
+
return import_sequence.Sequence.nextval(this.sequenceName, this.orm.table, dataSourceName);
|
|
45
|
+
};
|
|
46
|
+
const conn = import_database.Database.getConnection(dataSourceName);
|
|
47
|
+
try {
|
|
48
|
+
this.ormstatements = (0, import_ormstatements.create)(this.orm, conn);
|
|
49
|
+
} finally {
|
|
50
|
+
conn.close();
|
|
51
|
+
}
|
|
52
|
+
let loggerName = logCtxName;
|
|
53
|
+
if (!loggerName) {
|
|
54
|
+
loggerName = "db.dao";
|
|
55
|
+
if (this.orm.table)
|
|
56
|
+
loggerName = "db.dao." + this.orm.table.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
this.$log = import_log.Logging.getLogger(loggerName);
|
|
59
|
+
this.execute = function(sqlBuilder, parameterBindings) {
|
|
60
|
+
const sql = sqlBuilder.build();
|
|
61
|
+
if (sql === void 0 || sql.length < 1)
|
|
62
|
+
throw Error("Illegal argument: sql from statement builder is invalid[" + sql + "]");
|
|
63
|
+
this.$log.trace("Executing SQL Statement: {}", sql);
|
|
64
|
+
const parameters = sqlBuilder.parameters && sqlBuilder.parameters();
|
|
65
|
+
const _parameterBindings = [];
|
|
66
|
+
if (parameterBindings?.$filter && parameters && parameters.length > 0) {
|
|
67
|
+
if (parameterBindings.$filter.equals) {
|
|
68
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.equals);
|
|
69
|
+
const addedPropertiesKeys = [];
|
|
70
|
+
parameters.forEach((e) => {
|
|
71
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
72
|
+
const value = parameterBindings.$filter.equals[e.name];
|
|
73
|
+
if (Array.isArray(value)) {
|
|
74
|
+
value.forEach((v) => {
|
|
75
|
+
_parameterBindings.push({
|
|
76
|
+
type: e.type,
|
|
77
|
+
value: parseValue(e.type, v)
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
_parameterBindings.push({
|
|
82
|
+
type: e.type,
|
|
83
|
+
value: parseValue(e.type, value)
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
addedPropertiesKeys.push(e.name);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (parameterBindings.$filter.notEquals) {
|
|
91
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.notEquals);
|
|
92
|
+
const addedPropertiesKeys = [];
|
|
93
|
+
parameters.forEach((e) => {
|
|
94
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
95
|
+
const value = parameterBindings.$filter.notEquals[e.name];
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
value.forEach((v) => {
|
|
98
|
+
_parameterBindings.push({
|
|
99
|
+
type: e.type,
|
|
100
|
+
value: parseValue(e.type, v)
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
_parameterBindings.push({
|
|
105
|
+
type: e.type,
|
|
106
|
+
value: parseValue(e.type, value)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
addedPropertiesKeys.push(e.name);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (parameterBindings.$filter.contains) {
|
|
114
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.contains);
|
|
115
|
+
const addedPropertiesKeys = [];
|
|
116
|
+
parameters.forEach((e) => {
|
|
117
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
118
|
+
_parameterBindings.push({
|
|
119
|
+
type: e.type,
|
|
120
|
+
value: `%${parameterBindings.$filter.contains[e.name]}%`
|
|
121
|
+
});
|
|
122
|
+
addedPropertiesKeys.push(e.name);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (parameterBindings.$filter.greaterThan) {
|
|
127
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.greaterThan);
|
|
128
|
+
const addedPropertiesKeys = [];
|
|
129
|
+
parameters.forEach((e) => {
|
|
130
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
131
|
+
_parameterBindings.push({
|
|
132
|
+
type: e.type,
|
|
133
|
+
value: parseValue(e.type, parameterBindings.$filter.greaterThan[e.name])
|
|
134
|
+
});
|
|
135
|
+
addedPropertiesKeys.push(e.name);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (parameterBindings.$filter.lessThan) {
|
|
140
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.lessThan);
|
|
141
|
+
const addedPropertiesKeys = [];
|
|
142
|
+
parameters.forEach((e) => {
|
|
143
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
144
|
+
_parameterBindings.push({
|
|
145
|
+
type: e.type,
|
|
146
|
+
value: parseValue(e.type, parameterBindings.$filter.lessThan[e.name])
|
|
147
|
+
});
|
|
148
|
+
addedPropertiesKeys.push(e.name);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (parameterBindings.$filter.greaterThanOrEqual) {
|
|
153
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.greaterThanOrEqual);
|
|
154
|
+
const addedPropertiesKeys = [];
|
|
155
|
+
parameters.forEach((e) => {
|
|
156
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
157
|
+
_parameterBindings.push({
|
|
158
|
+
type: e.type,
|
|
159
|
+
value: parseValue(e.type, parameterBindings.$filter.greaterThanOrEqual[e.name])
|
|
160
|
+
});
|
|
161
|
+
addedPropertiesKeys.push(e.name);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (parameterBindings.$filter.lessThanOrEqual) {
|
|
166
|
+
const propertiesKeys = Object.keys(parameterBindings.$filter.lessThanOrEqual);
|
|
167
|
+
const addedPropertiesKeys = [];
|
|
168
|
+
parameters.forEach((e) => {
|
|
169
|
+
if (propertiesKeys.includes(e.name) && !addedPropertiesKeys.includes(e.name)) {
|
|
170
|
+
_parameterBindings.push({
|
|
171
|
+
type: e.type,
|
|
172
|
+
value: parseValue(e.type, parameterBindings.$filter.lessThanOrEqual[e.name])
|
|
173
|
+
});
|
|
174
|
+
addedPropertiesKeys.push(e.name);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (parameters && parameters.length > 0) {
|
|
180
|
+
for (var i = 0; i < parameters.length; i++) {
|
|
181
|
+
var val;
|
|
182
|
+
if (parameterBindings) {
|
|
183
|
+
if (Array.isArray(parameterBindings)) {
|
|
184
|
+
val = parameterBindings[i];
|
|
185
|
+
} else {
|
|
186
|
+
val = parameterBindings[parameters[i].name];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if ((val === null || val === void 0) && sql.toLowerCase().startsWith("select")) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const index = i + 1;
|
|
193
|
+
this.$log.trace("Binding to parameter[{}]: {}", index, val);
|
|
194
|
+
_parameterBindings.push({
|
|
195
|
+
"type": parameters[i].type,
|
|
196
|
+
"value": parseValue(parameters[i].type, val)
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
let result;
|
|
201
|
+
if (sql.toLowerCase().startsWith("select")) {
|
|
202
|
+
result = import_db.Query.execute(sql, _parameterBindings, dataSourceName);
|
|
203
|
+
} else if (sql.toLowerCase().startsWith("insert")) {
|
|
204
|
+
result = import_insert.Insert.execute(sql, _parameterBindings, dataSourceName);
|
|
205
|
+
} else {
|
|
206
|
+
result = import_update.Update.execute(sql, _parameterBindings, dataSourceName);
|
|
207
|
+
}
|
|
208
|
+
return result !== null ? result : [];
|
|
209
|
+
};
|
|
210
|
+
function parseValue(type, value) {
|
|
211
|
+
switch (type.toUpperCase()) {
|
|
212
|
+
case "INTEGER":
|
|
213
|
+
return parseInt(value);
|
|
214
|
+
case "DOUBLE":
|
|
215
|
+
case "FLOAT":
|
|
216
|
+
return parseFloat(value);
|
|
217
|
+
case "BOOLEAN":
|
|
218
|
+
return value ? "true" : "false";
|
|
219
|
+
default:
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
;
|
|
225
|
+
DAO.prototype.notify = function(event) {
|
|
226
|
+
const func = this[event];
|
|
227
|
+
if (!this[event])
|
|
228
|
+
return;
|
|
229
|
+
if (typeof func !== "function")
|
|
230
|
+
throw Error("Illegal argument. Not a function: " + func);
|
|
231
|
+
const args = [].slice.call(arguments);
|
|
232
|
+
func.apply(this, args.slice(1));
|
|
233
|
+
};
|
|
234
|
+
DAO.prototype.createSQLEntity = function(entity) {
|
|
235
|
+
let i;
|
|
236
|
+
const persistentItem = {};
|
|
237
|
+
const mandatories = this.orm.getMandatoryProperties();
|
|
238
|
+
for (i = 0; i < mandatories.length; i++) {
|
|
239
|
+
if (mandatories[i].dbValue) {
|
|
240
|
+
persistentItem[mandatories[i].name] = mandatories[i].dbValue.apply(this, [entity[mandatories[i].name], entity]);
|
|
241
|
+
} else {
|
|
242
|
+
persistentItem[mandatories[i].name] = entity[mandatories[i].name];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const optionals = this.orm.getOptionalProperties();
|
|
246
|
+
for (i = 0; i < optionals.length; i++) {
|
|
247
|
+
if (optionals[i].dbValue !== void 0) {
|
|
248
|
+
persistentItem[optionals[i].name] = optionals[i].dbValue.apply(this, [entity[optionals[i].name], entity]);
|
|
249
|
+
} else {
|
|
250
|
+
persistentItem[optionals[i].name] = entity[optionals[i].name] === void 0 ? null : entity[optionals[i].name];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return persistentItem;
|
|
254
|
+
};
|
|
255
|
+
DAO.prototype.createEntity = function(resultSetEntry, entityPropertyNames) {
|
|
256
|
+
const entity = {};
|
|
257
|
+
let properties = this.orm.properties;
|
|
258
|
+
if (entityPropertyNames && entityPropertyNames.length > 0) {
|
|
259
|
+
properties = properties.filter(function(prop) {
|
|
260
|
+
return entityPropertyNames.indexOf(prop.name) > -1;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
for (let i = 0; i < properties.length; i++) {
|
|
264
|
+
const prop = properties[i];
|
|
265
|
+
entity[prop.name] = resultSetEntry[prop.columnName];
|
|
266
|
+
if (prop.value) {
|
|
267
|
+
entity[prop.name] = prop.value(entity[prop.name]);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
Object.keys(entity).forEach(function(propertyName) {
|
|
271
|
+
if (entity[propertyName] === null)
|
|
272
|
+
entity[propertyName] = void 0;
|
|
273
|
+
});
|
|
274
|
+
let entitySegment = "";
|
|
275
|
+
if (entity[this.orm.getPrimaryKey().name]) {
|
|
276
|
+
entitySegment = "[" + entity[this.orm.getPrimaryKey().name] + "]";
|
|
277
|
+
}
|
|
278
|
+
return entity;
|
|
279
|
+
};
|
|
280
|
+
DAO.prototype.validateEntity = function(entity, skip) {
|
|
281
|
+
if (entity === void 0 || entity === null) {
|
|
282
|
+
throw new Error("Illegal argument: entity is " + entity);
|
|
283
|
+
}
|
|
284
|
+
if (skip) {
|
|
285
|
+
if (skip.constructor !== Array) {
|
|
286
|
+
skip = [skip];
|
|
287
|
+
}
|
|
288
|
+
for (var j = 0; j < skip.length; j++) {
|
|
289
|
+
skip[j];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const mandatories = this.orm.getMandatoryProperties();
|
|
293
|
+
for (let i = 0; i < mandatories.length; i++) {
|
|
294
|
+
const propName = mandatories[i].name;
|
|
295
|
+
if (skip && skip.indexOf(propName) > -1 || mandatories[i].type.toUpperCase() === "BOOLEAN")
|
|
296
|
+
continue;
|
|
297
|
+
const propValue = entity[propName];
|
|
298
|
+
if (propValue === void 0 || propValue === null) {
|
|
299
|
+
throw new Error("Illegal " + propName + " attribute value in " + this.orm.table + " entity: " + propValue);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
DAO.prototype.insert = function(_entity) {
|
|
304
|
+
const ids = [];
|
|
305
|
+
let entities = _entity;
|
|
306
|
+
if (_entity.constructor !== Array) {
|
|
307
|
+
entities = [_entity];
|
|
308
|
+
}
|
|
309
|
+
this.$log.trace("Inserting {} {}", this.orm.table, entities.length === 1 ? "entity" : "entities");
|
|
310
|
+
for (let i = 0; i < entities.length; i++) {
|
|
311
|
+
let entity = entities[i];
|
|
312
|
+
entity = entities[i];
|
|
313
|
+
this.validateEntity(entity, [this.orm.getPrimaryKey().name]);
|
|
314
|
+
const uniques = this.orm.getUniqueProperties();
|
|
315
|
+
for (let _i = 0; _i < uniques.length; _i++) {
|
|
316
|
+
const prop = uniques[_i];
|
|
317
|
+
const st = this.ormstatements.dialect.select(prop.column).from(this.orm.table).where(prop.column + "=?", [prop]);
|
|
318
|
+
const params = {};
|
|
319
|
+
params[prop.name] = entity[prop.name];
|
|
320
|
+
const rs = this.execute(st, params);
|
|
321
|
+
if (rs.length > 0)
|
|
322
|
+
throw Error("Unique constraint violation for " + prop.name + "[" + entity[prop.name] + "]");
|
|
323
|
+
}
|
|
324
|
+
const dbEntity = this.createSQLEntity(entity);
|
|
325
|
+
try {
|
|
326
|
+
const parametericStatement = this.ormstatements.insert.apply(this.ormstatements);
|
|
327
|
+
if (this.orm.isAutoIncrementPrimaryKey()) {
|
|
328
|
+
const id = this.generateId();
|
|
329
|
+
dbEntity[this.orm.getPrimaryKey().name] = id;
|
|
330
|
+
}
|
|
331
|
+
const updatedRecordCount = this.execute(parametericStatement, dbEntity);
|
|
332
|
+
if (!this.orm.isAutoIncrementPrimaryKey() && isNotEmptyArray(updatedRecordCount)) {
|
|
333
|
+
const id = updatedRecordCount[0];
|
|
334
|
+
dbEntity[this.orm.getPrimaryKey().name] = id;
|
|
335
|
+
}
|
|
336
|
+
this.notify("afterInsert", dbEntity);
|
|
337
|
+
this.notify("beforeInsertAssociationSets", dbEntity);
|
|
338
|
+
if ((updatedRecordCount > 0 || isNotEmptyArray(updatedRecordCount)) && this.orm.associations && Object.keys(this.orm.associations).length) {
|
|
339
|
+
this.$log.trace("Inserting association sets for {}[{}]", this.orm.table, dbEntity[this.orm.getPrimaryKey().name]);
|
|
340
|
+
for (const idx in Object.keys(this.orm.associations)) {
|
|
341
|
+
const association = this.orm.associations[idx];
|
|
342
|
+
const associationName = association["name"];
|
|
343
|
+
if ([this.orm.ASSOCIATION_TYPES["MANY-TO-MANY"], this.orm.ASSOCIATION_TYPES["MANY-TO-ONE"]].indexOf(association.type) < 0) {
|
|
344
|
+
if (entity[associationName] && entity[associationName].length > 0) {
|
|
345
|
+
const associationDaoFactoryFunc = association.targetDao || this;
|
|
346
|
+
if (associationDaoFactoryFunc.constructor !== Function)
|
|
347
|
+
throw Error("Invalid ORM: Association " + associationName + " dao property is expected to be function. Instead, it is: " + typeof associationDaoFactoryFunc);
|
|
348
|
+
const associationDAO = associationDaoFactoryFunc.apply(this);
|
|
349
|
+
this.notify("beforeInsertAssociationSet", entity[associationName], entity);
|
|
350
|
+
this.$log.trace("Inserting {} inline entities into association set {}", entity[associationName].length, associationName);
|
|
351
|
+
for (let j = 0; j < entity[associationName].length; j++) {
|
|
352
|
+
const associatedEntity = entity[associationName][j];
|
|
353
|
+
const associatedEntityJoinKey = association.joinKey;
|
|
354
|
+
const key = association.key || this.orm.getPrimaryKey().name;
|
|
355
|
+
associatedEntity[associatedEntityJoinKey] = entity[key];
|
|
356
|
+
this.notify("beforeInsertAssociationSetEntity", entity[associationName], dbEntity);
|
|
357
|
+
associationDAO.insert.apply(associationDAO, [associatedEntity]);
|
|
358
|
+
}
|
|
359
|
+
this.$log.trace("Inserting {} inline entities into association set {} finsihed", entity[associationName].length, associationName);
|
|
360
|
+
this.notify("afterInsertAssociationSet", entity[associationName], dbEntity);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (updatedRecordCount > 0 || isNotEmptyArray(updatedRecordCount)) {
|
|
366
|
+
ids.push(dbEntity[this.orm.getPrimaryKey().name]);
|
|
367
|
+
this.$log.trace("{}[] entity inserted", this.orm.table, dbEntity[this.orm.getPrimaryKey().name]);
|
|
368
|
+
} else {
|
|
369
|
+
this.$log.trace("No changes incurred in {}", this.orm.table);
|
|
370
|
+
}
|
|
371
|
+
} catch (e) {
|
|
372
|
+
this.$log.error("Inserting {} {} failed", this.orm.table, entities.length === 1 ? "entity" : "entities", e);
|
|
373
|
+
this.$log.trace("Rolling back changes after failed {}[{}] insert. ", this.orm.table, dbEntity[this.orm.getPrimaryKey().name]);
|
|
374
|
+
if (dbEntity[this.orm.getPrimaryKey().name]) {
|
|
375
|
+
try {
|
|
376
|
+
this.remove(dbEntity[this.orm.getPrimaryKey().name]);
|
|
377
|
+
} catch (err) {
|
|
378
|
+
this.$log.error("Could not rollback changes after failed {}[{}] insert. ", this.orm.table, dbEntity[this.orm.getPrimaryKey().name], err);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
throw e;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (_entity.constructor !== Array)
|
|
385
|
+
return ids[0];
|
|
386
|
+
else
|
|
387
|
+
return ids;
|
|
388
|
+
};
|
|
389
|
+
function isNotEmptyArray(array) {
|
|
390
|
+
return Array.isArray(array) && array.length > 0;
|
|
391
|
+
}
|
|
392
|
+
DAO.prototype.update = function(entity) {
|
|
393
|
+
this.$log.trace("Updating {}[{}] entity", this.orm.table, entity !== void 0 ? entity[this.orm.getPrimaryKey().name] : entity);
|
|
394
|
+
if (entity === void 0 || entity === null) {
|
|
395
|
+
throw new Error("Illegal argument: entity is " + entity);
|
|
396
|
+
}
|
|
397
|
+
const ignoredProperties = this.orm.getMandatoryProperties().filter(function(property) {
|
|
398
|
+
return property.allowedOps && property.allowedOps.indexOf("update") < 0;
|
|
399
|
+
}).map(function(property) {
|
|
400
|
+
return property.name;
|
|
401
|
+
});
|
|
402
|
+
this.validateEntity(entity, ignoredProperties);
|
|
403
|
+
const parametericStatement = this.ormstatements.update.apply(this.ormstatements, [entity]);
|
|
404
|
+
const dbEntity = this.createSQLEntity(entity);
|
|
405
|
+
try {
|
|
406
|
+
this.notify("beforeUpdateEntity", dbEntity);
|
|
407
|
+
const updatedRecordsCount = this.execute(parametericStatement, dbEntity);
|
|
408
|
+
if (updatedRecordsCount > 0)
|
|
409
|
+
this.$log.trace("{}[{}] entity updated", this.orm.table, dbEntity[this.orm.getPrimaryKey().name]);
|
|
410
|
+
else
|
|
411
|
+
this.$log.trace("No changes incurred in {}", this.orm.table);
|
|
412
|
+
return this;
|
|
413
|
+
} catch (e) {
|
|
414
|
+
this.$log.error("Updating {}[{}] failed", this.orm.table, entity !== void 0 ? entity[this.orm.getPrimaryKey().name] : entity, e);
|
|
415
|
+
throw e;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
DAO.prototype.remove = function() {
|
|
419
|
+
let ids = [];
|
|
420
|
+
if (arguments.length === 0) {
|
|
421
|
+
ids = this.list({
|
|
422
|
+
"$select": [this.orm.getPrimaryKey().name]
|
|
423
|
+
}).map(function(ent) {
|
|
424
|
+
return ent[this.orm.getPrimaryKey().name];
|
|
425
|
+
}.bind(this));
|
|
426
|
+
} else {
|
|
427
|
+
if (arguments[0].constructor !== Array) {
|
|
428
|
+
ids = [arguments[0]];
|
|
429
|
+
} else {
|
|
430
|
+
ids = arguments[0];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
this.$log.trace("Deleting " + this.orm.table + (ids !== void 0 && ids.length === 1 ? "[" + ids[0] + "] entity" : ids.length + " entities"));
|
|
434
|
+
for (let i = 0; i < ids.length; i++) {
|
|
435
|
+
let id = ids[i];
|
|
436
|
+
if (this.orm.getPrimaryKey().type.toUpperCase() !== "VARCHAR")
|
|
437
|
+
id = parseInt(id, 10);
|
|
438
|
+
if (ids.length > 1)
|
|
439
|
+
this.$log.trace("Deleting {}[{}] entity", this.orm.table, id);
|
|
440
|
+
if (id === void 0 || id === null) {
|
|
441
|
+
throw new Error("Illegal argument for id parameter:" + id);
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
this.notify("beforeRemoveEntity", id);
|
|
445
|
+
if (this.orm.associations) {
|
|
446
|
+
for (const idx in Object.keys(this.orm.associations)) {
|
|
447
|
+
const association = this.orm.associations[idx];
|
|
448
|
+
const associationName = association["name"];
|
|
449
|
+
if ([this.orm.ASSOCIATION_TYPES["MANY-TO-MANY"], this.orm.ASSOCIATION_TYPES["MANY-TO-ONE"]].indexOf(association.type) < 0) {
|
|
450
|
+
this.$log.trace("Inspecting {}[{}}] entity's dependency '{}' for entities to delete.", this.orm.table, id, associationName);
|
|
451
|
+
const associationDAO = association.targetDao ? association.targetDao() : this;
|
|
452
|
+
const settings = {};
|
|
453
|
+
let joinId = id;
|
|
454
|
+
if (association.key !== void 0) {
|
|
455
|
+
var ctxEntity = this.find(id);
|
|
456
|
+
joinId = ctxEntity[association.key];
|
|
457
|
+
}
|
|
458
|
+
settings[association.joinKey] = joinId;
|
|
459
|
+
let associatedEntities;
|
|
460
|
+
associatedEntities = associationDAO.list(settings);
|
|
461
|
+
if (associatedEntities && associatedEntities.length > 0) {
|
|
462
|
+
this.$log.trace("Deleting {}[{}] entity's {} dependent {}", this.orm.table, id, associatedEntities.length, associationName);
|
|
463
|
+
this.notify("beforeRemoveAssociationSet", associatedEntities, id);
|
|
464
|
+
for (let j = 0; j < associatedEntities.length; j++) {
|
|
465
|
+
const associatedEntity = associatedEntities[j];
|
|
466
|
+
this.notify("beforeRemoveAssociationSetEntity", associatedEntity, associatedEntities, id);
|
|
467
|
+
associationDAO.remove.apply(associationDAO, [associatedEntity[associationDAO.orm.getPrimaryKey().name]]);
|
|
468
|
+
}
|
|
469
|
+
this.$log.trace("{}[{}] entity's {} dependent {} {} deleted.", this.orm.table, id, associatedEntities.length, associationName, associatedEntities.length > 1 ? "entities" : "entity");
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const parametericStatement = this.ormstatements["delete"].apply(this.ormstatements, [this.orm.getPrimaryKey().name]);
|
|
475
|
+
let params = {};
|
|
476
|
+
params[this.orm.getPrimaryKey().name] = id;
|
|
477
|
+
const updatedRecordsCount = this.execute(parametericStatement, params);
|
|
478
|
+
if (updatedRecordsCount > 0)
|
|
479
|
+
this.$log.trace("{}[{}] entity deleted", this.orm.table, id);
|
|
480
|
+
else
|
|
481
|
+
this.$log.trace("No changes incurred in {}", this.orm.table);
|
|
482
|
+
} catch (e) {
|
|
483
|
+
this.$log.error("Deleting {}[{}] entity failed", this.orm.table, id, e);
|
|
484
|
+
throw e;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
DAO.prototype.expand = function(expansionPath, context) {
|
|
489
|
+
let i;
|
|
490
|
+
let settings;
|
|
491
|
+
let key;
|
|
492
|
+
let joinId;
|
|
493
|
+
this.$log.trace("Expanding for association path {} and context entity {}", expansionPath, (typeof arguments[1] !== "object" ? "id " : "") + JSON.stringify(arguments[1]));
|
|
494
|
+
if (!expansionPath || !expansionPath.length) {
|
|
495
|
+
throw new Error("Illegal argument: expansionPath[" + expansionPath + "]");
|
|
496
|
+
}
|
|
497
|
+
if (!context) {
|
|
498
|
+
throw new Error("Illegal argument: context[" + context + "]");
|
|
499
|
+
}
|
|
500
|
+
const associationName = expansionPath.splice ? expansionPath.splice(0, 1)[0] : expansionPath;
|
|
501
|
+
const association = this.orm.getAssociation(associationName);
|
|
502
|
+
if (!associationName || !association)
|
|
503
|
+
throw new Error("Illegal argument: Unknown association for this DAO [" + associationName + "]");
|
|
504
|
+
const joinKey = association.joinKey;
|
|
505
|
+
let contextEntity;
|
|
506
|
+
if (context[this.orm.getPrimaryKey().name] !== void 0) {
|
|
507
|
+
contextEntity = context;
|
|
508
|
+
} else {
|
|
509
|
+
contextEntity = this.find(context);
|
|
510
|
+
}
|
|
511
|
+
if (!contextEntity) {
|
|
512
|
+
throw Error("No record found for context entity [" + context + "]");
|
|
513
|
+
}
|
|
514
|
+
const associationTargetDAO = association.targetDao ? association.targetDao.apply(this) : this;
|
|
515
|
+
if (!associationTargetDAO)
|
|
516
|
+
throw Error("No target association DAO instance available for association " + associationName);
|
|
517
|
+
let expansion;
|
|
518
|
+
let associationEntities = [];
|
|
519
|
+
if (association.type === this.orm.ASSOCIATION_TYPES["ONE-TO-ONE"] || association.type === this.orm.ASSOCIATION_TYPES["MANY-TO-ONE"]) {
|
|
520
|
+
joinId = contextEntity[joinKey];
|
|
521
|
+
this.$log.trace("Expanding association type {} on {}[{}]", association.type, joinKey, joinId);
|
|
522
|
+
if (!association.key || association.key === associationTargetDAO.orm.getPrimaryKey().name)
|
|
523
|
+
expansion = associationTargetDAO.find.apply(associationTargetDAO, [joinId]);
|
|
524
|
+
else {
|
|
525
|
+
let listSettings = {};
|
|
526
|
+
listSettings["$filter"] = association.key;
|
|
527
|
+
listSettings[association.key] = joinId;
|
|
528
|
+
expansion = associationTargetDAO.list.apply(associationTargetDAO, [listSettings])[0];
|
|
529
|
+
}
|
|
530
|
+
if (expansionPath.length > 0) {
|
|
531
|
+
this.expand(expansionPath, expansion);
|
|
532
|
+
}
|
|
533
|
+
} else if (association.type === this.orm.ASSOCIATION_TYPES["ONE-TO-MANY"]) {
|
|
534
|
+
settings = {};
|
|
535
|
+
if (association.defaults)
|
|
536
|
+
settings = association.defaults;
|
|
537
|
+
key = association.key || this.orm.getPrimaryKey().name;
|
|
538
|
+
joinId = contextEntity[key];
|
|
539
|
+
this.$log.trace("Expanding association type {} on {}[{}]", association.type, joinKey, joinId);
|
|
540
|
+
settings[joinKey] = joinId;
|
|
541
|
+
associationEntities = associationEntities.concat(associationTargetDAO.list.apply(associationTargetDAO, [settings]));
|
|
542
|
+
if (expansionPath.length > 0) {
|
|
543
|
+
for (i = 0; i < associationEntities.length; i++) {
|
|
544
|
+
this.expand(expansionPath, associationEntities[i]);
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
expansion = associationEntities;
|
|
548
|
+
}
|
|
549
|
+
} else if (association.type === this.orm.ASSOCIATION_TYPES["MANY-TO-MANY"]) {
|
|
550
|
+
const joinDAO = association.joinDao();
|
|
551
|
+
if (!joinDAO)
|
|
552
|
+
throw Error("No join DAO instance available for association " + associationName);
|
|
553
|
+
if (!joinDAO.listJoins)
|
|
554
|
+
throw Error("No listJoins function in join DAO instance available for association " + associationName);
|
|
555
|
+
settings = {};
|
|
556
|
+
key = association.key || this.orm.getPrimaryKey().name;
|
|
557
|
+
joinId = contextEntity[key];
|
|
558
|
+
settings[association.joinKey] = joinId;
|
|
559
|
+
associationEntities = associationEntities.concat(joinDAO.listJoins.apply(joinDAO, [settings, { "sourceDao": this, "joinDao": joinDAO, "targetDao": associationTargetDAO }]));
|
|
560
|
+
if (expansionPath.length > 0) {
|
|
561
|
+
for (i = 0; i < associationEntities.length; i++) {
|
|
562
|
+
this.expand(expansionPath, associationEntities[i]);
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
expansion = associationEntities;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return expansion;
|
|
569
|
+
};
|
|
570
|
+
DAO.prototype.find = function(id, expand, select) {
|
|
571
|
+
if (typeof arguments[0] === "object") {
|
|
572
|
+
id = arguments[0].id;
|
|
573
|
+
expand = arguments[0].$expand || arguments[0].expand;
|
|
574
|
+
select = arguments[0].$select || arguments[0].select;
|
|
575
|
+
}
|
|
576
|
+
this.$log.trace("Finding {}[{}] entity with list parameters expand[{}], select[{}]", this.orm.table, id, expand, select);
|
|
577
|
+
if (id === void 0 || id === null) {
|
|
578
|
+
throw new Error("Illegal argument for id parameter:" + id);
|
|
579
|
+
}
|
|
580
|
+
try {
|
|
581
|
+
let entity;
|
|
582
|
+
if (select !== void 0) {
|
|
583
|
+
if (select.constructor !== Array) {
|
|
584
|
+
if (select.constructor === String) {
|
|
585
|
+
select = select.split(",").map(function(sel) {
|
|
586
|
+
if (sel.constructor !== String)
|
|
587
|
+
throw Error("Illegal argument: select array components are expected ot be strings but found " + typeof sel);
|
|
588
|
+
return sel.trim();
|
|
589
|
+
});
|
|
590
|
+
} else {
|
|
591
|
+
throw Error("Illegal argument: select is expected to be string or array of strings but was " + typeof select);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (select !== void 0 && expand !== void 0) {
|
|
596
|
+
select.push(this.orm.getPrimaryKey().name);
|
|
597
|
+
}
|
|
598
|
+
let findQbParams = {
|
|
599
|
+
select
|
|
600
|
+
};
|
|
601
|
+
const parametericStatement = this.ormstatements.find.apply(this.ormstatements, [findQbParams]);
|
|
602
|
+
let params = {};
|
|
603
|
+
if (this.orm.getPrimaryKey().type.toUpperCase() !== "VARCHAR")
|
|
604
|
+
id = parseInt(id, 10);
|
|
605
|
+
params[this.orm.getPrimaryKey().name] = id;
|
|
606
|
+
const resultSet = this.execute(parametericStatement, params);
|
|
607
|
+
if (resultSet[0]) {
|
|
608
|
+
entity = this.createEntity(resultSet[0], select);
|
|
609
|
+
if (entity) {
|
|
610
|
+
this.$log.trace("{}[{}] entity found", this.orm.table, id);
|
|
611
|
+
this.notify("afterFound", entity);
|
|
612
|
+
if (expand !== void 0) {
|
|
613
|
+
if (expand.constructor !== Array) {
|
|
614
|
+
if (expand.constructor === String) {
|
|
615
|
+
expand = String(expand);
|
|
616
|
+
expand = expand.split(",").map(function(exp) {
|
|
617
|
+
if (exp.constructor !== String)
|
|
618
|
+
throw Error("Illegal argument: expand array components are expected ot be strings but found " + typeof exp);
|
|
619
|
+
return exp.trim();
|
|
620
|
+
});
|
|
621
|
+
} else {
|
|
622
|
+
throw Error("Illegal argument: expand is expected to be string or array of strings but was " + typeof expand);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
var associationNames = this.orm.getAssociationNames();
|
|
626
|
+
for (var idx in associationNames) {
|
|
627
|
+
var associationName = associationNames[idx];
|
|
628
|
+
if (expand.indexOf(associationName) > -1) {
|
|
629
|
+
entity[associationName] = this.expand([associationName], entity);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
} else {
|
|
634
|
+
this.$log.trace("{}[{}] entity not found", this.orm.table, id);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return entity;
|
|
638
|
+
} catch (e) {
|
|
639
|
+
this.$log.error("Finding {}[{}] entity failed.", this.orm.table, id, e);
|
|
640
|
+
throw e;
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
DAO.prototype.count = function(settings) {
|
|
644
|
+
settings = settings || {};
|
|
645
|
+
const parametericStatement = this.ormstatements.count.apply(this.ormstatements, [settings]);
|
|
646
|
+
this.$log.trace("Counting " + this.orm.table + " entities");
|
|
647
|
+
let count = 0;
|
|
648
|
+
try {
|
|
649
|
+
const rs = this.execute(parametericStatement, settings);
|
|
650
|
+
if (rs.length > 0) {
|
|
651
|
+
const key = Object.keys(rs[0])[0];
|
|
652
|
+
count = parseInt(rs[0][key], 10);
|
|
653
|
+
}
|
|
654
|
+
} catch (e) {
|
|
655
|
+
this.$log.error("Counting {} entities failed", this.orm.table, e);
|
|
656
|
+
e.errContext = parametericStatement.toString();
|
|
657
|
+
throw e;
|
|
658
|
+
}
|
|
659
|
+
this.$log.trace("{} {} entities counted", String(count), this.orm.table);
|
|
660
|
+
return count;
|
|
661
|
+
};
|
|
662
|
+
DAO.prototype.list = function(settings) {
|
|
663
|
+
let key;
|
|
664
|
+
settings = settings || {};
|
|
665
|
+
const expand = settings.$expand || settings.expand;
|
|
666
|
+
if (expand !== void 0) {
|
|
667
|
+
if (expand.constructor !== Array) {
|
|
668
|
+
if (expand.constructor === String) {
|
|
669
|
+
if (expand.indexOf(",") > -1) {
|
|
670
|
+
settings.$expand = expand.split(",").map(function(exp) {
|
|
671
|
+
if (exp.constructor !== String)
|
|
672
|
+
throw Error("Illegal argument: expand array components are expected ot be strings but found " + typeof exp);
|
|
673
|
+
return exp.trim();
|
|
674
|
+
});
|
|
675
|
+
} else {
|
|
676
|
+
settings.$expand = [expand];
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
throw Error("Illegal argument: expand is expected to be string or array of strings but was " + typeof expand);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
const select = settings.$select || settings.select;
|
|
684
|
+
if (select !== void 0) {
|
|
685
|
+
if (select.constructor !== Array) {
|
|
686
|
+
if (select.constructor === String) {
|
|
687
|
+
if (select.indexOf(",") > -1) {
|
|
688
|
+
settings.$select = select.split(",").map(function(exp) {
|
|
689
|
+
if (exp.constructor !== String)
|
|
690
|
+
throw Error("Illegal argument: select array components are expected ot be strings but found " + typeof exp);
|
|
691
|
+
return exp.trim();
|
|
692
|
+
});
|
|
693
|
+
} else {
|
|
694
|
+
settings.$select = [select];
|
|
695
|
+
}
|
|
696
|
+
} else {
|
|
697
|
+
throw Error("Illegal argument: select is expected to be string or array of strings but was " + typeof expand);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
const listArgs = [];
|
|
702
|
+
for (key in settings) {
|
|
703
|
+
listArgs.push(" " + key + "[" + settings[key] + "]");
|
|
704
|
+
}
|
|
705
|
+
this.$log.trace("Listing {} entity collection with list operators: {}", this.orm.table, listArgs.join(","));
|
|
706
|
+
if (settings.$select !== void 0 && expand !== void 0) {
|
|
707
|
+
settings.$select.push(this.orm.getPrimaryKey().name);
|
|
708
|
+
}
|
|
709
|
+
var parametericStatement = this.ormstatements.list.apply(this.ormstatements, [settings]);
|
|
710
|
+
try {
|
|
711
|
+
let entities = [];
|
|
712
|
+
const resultSet = this.execute(parametericStatement, settings);
|
|
713
|
+
resultSet.forEach(function(rsEntry) {
|
|
714
|
+
var entity = this.createEntity(rsEntry, settings.$select);
|
|
715
|
+
if (expand) {
|
|
716
|
+
var associationNames = this.orm.getAssociationNames();
|
|
717
|
+
for (var idx = 0; idx < associationNames.length; idx++) {
|
|
718
|
+
var associationName = associationNames[idx];
|
|
719
|
+
if (expand.indexOf(associationName) > -1) {
|
|
720
|
+
entity[associationName] = this.expand([associationName], entity);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
this.notify("afterFound", entity, settings);
|
|
725
|
+
entities.push(entity);
|
|
726
|
+
}.bind(this));
|
|
727
|
+
this.$log.trace("{} {} entities found", entities.length, this.orm.table);
|
|
728
|
+
return entities;
|
|
729
|
+
} catch (e) {
|
|
730
|
+
this.$log.error("Listing {} entities failed.", this.orm.table, e);
|
|
731
|
+
throw e;
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
DAO.prototype.existsTable = function() {
|
|
735
|
+
this.$log.trace("Check exists table " + this.orm.table);
|
|
736
|
+
try {
|
|
737
|
+
const parametericStatement = this.ormstatements.count.apply(this.ormstatements);
|
|
738
|
+
const rs = this.execute(parametericStatement);
|
|
739
|
+
return rs.length > 0;
|
|
740
|
+
} catch (e) {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
DAO.prototype.createTable = function() {
|
|
745
|
+
this.$log.trace("Creating table {}", this.orm.table);
|
|
746
|
+
const parametericStatement = this.ormstatements.createTable.apply(this.ormstatements);
|
|
747
|
+
try {
|
|
748
|
+
this.execute(parametericStatement);
|
|
749
|
+
this.$log.trace("{} table created", this.orm.table);
|
|
750
|
+
return this;
|
|
751
|
+
} catch (e) {
|
|
752
|
+
this.$log.error("Create table {} failed", this.orm.table, e);
|
|
753
|
+
throw e;
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
DAO.prototype.dropTable = function(dropIdSequence) {
|
|
757
|
+
this.$log.trace("Dropping table {}.", this.orm.table);
|
|
758
|
+
const parametericStatement = this.ormstatements.dropTable.apply(this.ormstatements);
|
|
759
|
+
try {
|
|
760
|
+
this.execute(parametericStatement);
|
|
761
|
+
this.$log.trace("Table {} dropped.", this.orm.table);
|
|
762
|
+
} catch (e) {
|
|
763
|
+
this.$log.error("Dropping table {} failed.", this.orm.table, e);
|
|
764
|
+
throw e;
|
|
765
|
+
}
|
|
766
|
+
if (dropIdSequence) {
|
|
767
|
+
this.$log.trace("Dropping table {} sequence {}.", this.orm.table, this.sequenceName);
|
|
768
|
+
try {
|
|
769
|
+
this.dropIdGenerator();
|
|
770
|
+
this.$log.trace("Table {} sequence {} dropped.", this.orm.table, this.sequenceName);
|
|
771
|
+
} catch (e) {
|
|
772
|
+
this.$log.error("Dropping table {} sequence {} failed.", this.orm.table, this.sequenceName, e);
|
|
773
|
+
throw e;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
return this;
|
|
777
|
+
};
|
|
778
|
+
function create(oDefinition, logCtxName, dataSourceName) {
|
|
779
|
+
let orm;
|
|
780
|
+
orm = oDefinition;
|
|
781
|
+
if (!dataSourceName || dataSourceName === null) {
|
|
782
|
+
dataSourceName = import_core.configurations.get("DIRIGIBLE_DATABASE_DATASOURCE_NAME_DEFAULT", "DefaultDB");
|
|
783
|
+
}
|
|
784
|
+
let productName = import_core.globals.get(dataSourceName);
|
|
785
|
+
if (!productName) {
|
|
786
|
+
productName = import_database.Database.getProductName(dataSourceName);
|
|
787
|
+
import_core.globals.set(dataSourceName, productName);
|
|
788
|
+
}
|
|
789
|
+
return new DAO(orm, logCtxName, dataSourceName);
|
|
790
|
+
}
|
|
791
|
+
;
|
|
792
|
+
function dao(oDefinition, logCtxName, dataSourceName) {
|
|
793
|
+
return create(oDefinition, logCtxName, dataSourceName);
|
|
794
|
+
}
|
|
795
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2RiL2Rhby50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7IE9STURlZmluaXRpb24sIGdldCBhcyBnZXRPUk0gfSBmcm9tIFwiLi9vcm1cIjtcbmltcG9ydCB7IGNyZWF0ZSBhcyBjcmVhdGVPUk1TdGF0ZW1lbnRzIH0gZnJvbSBcIi4vb3Jtc3RhdGVtZW50c1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi9zZXF1ZW5jZVwiO1xuaW1wb3J0IHsgRGF0YWJhc2UgfSBmcm9tIFwiLi9kYXRhYmFzZVwiO1xuaW1wb3J0IHsgUXVlcnkgfSBmcm9tIFwiQGFlcm9raXQvc2RrL2RiXCI7XG5pbXBvcnQgeyBVcGRhdGUgfSBmcm9tIFwiLi91cGRhdGVcIjtcbmltcG9ydCB7IEluc2VydCB9IGZyb20gXCIuL2luc2VydFwiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCJAYWVyb2tpdC9zZGsvbG9nXCI7XG5pbXBvcnQgeyBjb25maWd1cmF0aW9ucywgZ2xvYmFscyB9IGZyb20gXCJAYWVyb2tpdC9zZGsvY29yZVwiO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBEQU8ob3JtOiBPUk1EZWZpbml0aW9uLCBsb2dDdHhOYW1lPzogc3RyaW5nLCBkYXRhU291cmNlTmFtZT86IHN0cmluZykge1xuXHRpZiAob3JtID09PSB1bmRlZmluZWQpXG5cdFx0dGhyb3cgRXJyb3IoJ0lsbGVnYWwgYXJndW1lbnQ6IG9ybVsnICsgb3JtICsgJ10nKTtcblxuXHR0aGlzLm9ybSA9IGdldE9STShvcm0pO1xuXHR0aGlzLnNlcXVlbmNlTmFtZSA9IHRoaXMub3JtLnRhYmxlICsgJ18nICsgdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWUudG9VcHBlckNhc2UoKTtcblx0dGhpcy5kcm9wSWRHZW5lcmF0b3IgPSBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIFNlcXVlbmNlLmRyb3AodGhpcy5zZXF1ZW5jZU5hbWUsIGRhdGFTb3VyY2VOYW1lKTtcblx0fTtcblx0dGhpcy5nZW5lcmF0ZUlkID0gZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiBTZXF1ZW5jZS5uZXh0dmFsKHRoaXMuc2VxdWVuY2VOYW1lLCB0aGlzLm9ybS50YWJsZSwgZGF0YVNvdXJjZU5hbWUpO1xuXHR9O1xuXG5cdGNvbnN0IGNvbm4gPSBEYXRhYmFzZS5nZXRDb25uZWN0aW9uKGRhdGFTb3VyY2VOYW1lKTtcblx0dHJ5IHtcblx0XHR0aGlzLm9ybXN0YXRlbWVudHMgPSBjcmVhdGVPUk1TdGF0ZW1lbnRzKHRoaXMub3JtLCBjb25uKTtcblx0fSBmaW5hbGx5IHtcblx0XHRjb25uLmNsb3NlKCk7XG5cdH1cblxuXHQvLyBzZXR1cCBsb2dnZXJOYW1lXG5cdGxldCBsb2dnZXJOYW1lID0gbG9nQ3R4TmFtZTtcblx0aWYgKCFsb2dnZXJOYW1lKSB7XG5cdFx0bG9nZ2VyTmFtZSA9ICdkYi5kYW8nO1xuXHRcdGlmICh0aGlzLm9ybS50YWJsZSlcblx0XHRcdGxvZ2dlck5hbWUgPSAnZGIuZGFvLicgKyAodGhpcy5vcm0udGFibGUudG9Mb3dlckNhc2UoKSk7XG5cdH1cblx0dGhpcy4kbG9nID0gTG9nZ2luZy5nZXRMb2dnZXIobG9nZ2VyTmFtZSk7XG5cblx0dGhpcy5leGVjdXRlID0gZnVuY3Rpb24gKHNxbEJ1aWxkZXIsIHBhcmFtZXRlckJpbmRpbmdzKSB7XG5cdFx0Y29uc3Qgc3FsID0gc3FsQnVpbGRlci5idWlsZCgpO1xuXHRcdGlmIChzcWwgPT09IHVuZGVmaW5lZCB8fCBzcWwubGVuZ3RoIDwgMSlcblx0XHRcdHRocm93IEVycm9yKFwiSWxsZWdhbCBhcmd1bWVudDogc3FsIGZyb20gc3RhdGVtZW50IGJ1aWxkZXIgaXMgaW52YWxpZFtcIiArIHNxbCArIFwiXVwiKTtcblx0XHR0aGlzLiRsb2cudHJhY2UoJ0V4ZWN1dGluZyBTUUwgU3RhdGVtZW50OiB7fScsIHNxbCk7XG5cblx0XHRjb25zdCBwYXJhbWV0ZXJzID0gc3FsQnVpbGRlci5wYXJhbWV0ZXJzICYmIHNxbEJ1aWxkZXIucGFyYW1ldGVycygpO1xuXHRcdGNvbnN0IF9wYXJhbWV0ZXJCaW5kaW5ncyA9IFtdO1xuXHRcdGlmIChwYXJhbWV0ZXJCaW5kaW5ncz8uJGZpbHRlciAmJiBwYXJhbWV0ZXJzICYmIHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0aWYgKHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIuZXF1YWxzKSB7XG5cdFx0XHRcdGNvbnN0IHByb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXMocGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5lcXVhbHMpO1xuXHRcdFx0XHRjb25zdCBhZGRlZFByb3BlcnRpZXNLZXlzID0gW107XG5cdFx0XHRcdHBhcmFtZXRlcnMuZm9yRWFjaChlID0+IHtcblx0XHRcdFx0XHRpZiAocHJvcGVydGllc0tleXMuaW5jbHVkZXMoZS5uYW1lKSAmJiAhYWRkZWRQcm9wZXJ0aWVzS2V5cy5pbmNsdWRlcyhlLm5hbWUpKSB7XG5cdFx0XHRcdFx0XHRjb25zdCB2YWx1ZSA9IHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIuZXF1YWxzW2UubmFtZV07XG5cdFx0XHRcdFx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdFx0dmFsdWUuZm9yRWFjaCh2ID0+IHtcblx0XHRcdFx0XHRcdFx0XHRfcGFyYW1ldGVyQmluZGluZ3MucHVzaCh7XG5cdFx0XHRcdFx0XHRcdFx0XHR0eXBlOiBlLnR5cGUsXG5cdFx0XHRcdFx0XHRcdFx0XHR2YWx1ZTogcGFyc2VWYWx1ZShlLnR5cGUsIHYpXG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0X3BhcmFtZXRlckJpbmRpbmdzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRcdHR5cGU6IGUudHlwZSxcblx0XHRcdFx0XHRcdFx0XHR2YWx1ZTogcGFyc2VWYWx1ZShlLnR5cGUsIHZhbHVlKVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGFkZGVkUHJvcGVydGllc0tleXMucHVzaChlLm5hbWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAocGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5ub3RFcXVhbHMpIHtcblx0XHRcdFx0Y29uc3QgcHJvcGVydGllc0tleXMgPSBPYmplY3Qua2V5cyhwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLm5vdEVxdWFscyk7XG5cdFx0XHRcdGNvbnN0IGFkZGVkUHJvcGVydGllc0tleXMgPSBbXTtcblx0XHRcdFx0cGFyYW1ldGVycy5mb3JFYWNoKGUgPT4ge1xuXHRcdFx0XHRcdGlmIChwcm9wZXJ0aWVzS2V5cy5pbmNsdWRlcyhlLm5hbWUpICYmICFhZGRlZFByb3BlcnRpZXNLZXlzLmluY2x1ZGVzKGUubmFtZSkpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHZhbHVlID0gcGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5ub3RFcXVhbHNbZS5uYW1lXTtcblx0XHRcdFx0XHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0XHRcdFx0XHR2YWx1ZS5mb3JFYWNoKHYgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdF9wYXJhbWV0ZXJCaW5kaW5ncy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGU6IGUudHlwZSxcblx0XHRcdFx0XHRcdFx0XHRcdHZhbHVlOiBwYXJzZVZhbHVlKGUudHlwZSwgdilcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRfcGFyYW1ldGVyQmluZGluZ3MucHVzaCh7XG5cdFx0XHRcdFx0XHRcdFx0dHlwZTogZS50eXBlLFxuXHRcdFx0XHRcdFx0XHRcdHZhbHVlOiBwYXJzZVZhbHVlKGUudHlwZSwgdmFsdWUpXG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0YWRkZWRQcm9wZXJ0aWVzS2V5cy5wdXNoKGUubmFtZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGlmIChwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLmNvbnRhaW5zKSB7XG5cdFx0XHRcdGNvbnN0IHByb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXMocGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5jb250YWlucyk7XG5cdFx0XHRcdGNvbnN0IGFkZGVkUHJvcGVydGllc0tleXMgPSBbXTtcblx0XHRcdFx0cGFyYW1ldGVycy5mb3JFYWNoKGUgPT4ge1xuXHRcdFx0XHRcdGlmIChwcm9wZXJ0aWVzS2V5cy5pbmNsdWRlcyhlLm5hbWUpICYmICFhZGRlZFByb3BlcnRpZXNLZXlzLmluY2x1ZGVzKGUubmFtZSkpIHtcblx0XHRcdFx0XHRcdF9wYXJhbWV0ZXJCaW5kaW5ncy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0dHlwZTogZS50eXBlLFxuXHRcdFx0XHRcdFx0XHR2YWx1ZTogYCUke3BhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIuY29udGFpbnNbZS5uYW1lXX0lYFxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRhZGRlZFByb3BlcnRpZXNLZXlzLnB1c2goZS5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIuZ3JlYXRlclRoYW4pIHtcblx0XHRcdFx0Y29uc3QgcHJvcGVydGllc0tleXMgPSBPYmplY3Qua2V5cyhwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLmdyZWF0ZXJUaGFuKTtcblx0XHRcdFx0Y29uc3QgYWRkZWRQcm9wZXJ0aWVzS2V5cyA9IFtdO1xuXHRcdFx0XHRwYXJhbWV0ZXJzLmZvckVhY2goZSA9PiB7XG5cdFx0XHRcdFx0aWYgKHByb3BlcnRpZXNLZXlzLmluY2x1ZGVzKGUubmFtZSkgJiYgIWFkZGVkUHJvcGVydGllc0tleXMuaW5jbHVkZXMoZS5uYW1lKSkge1xuXHRcdFx0XHRcdFx0X3BhcmFtZXRlckJpbmRpbmdzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHR0eXBlOiBlLnR5cGUsXG5cdFx0XHRcdFx0XHRcdHZhbHVlOiBwYXJzZVZhbHVlKGUudHlwZSwgcGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5ncmVhdGVyVGhhbltlLm5hbWVdKVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRhZGRlZFByb3BlcnRpZXNLZXlzLnB1c2goZS5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIubGVzc1RoYW4pIHtcblx0XHRcdFx0Y29uc3QgcHJvcGVydGllc0tleXMgPSBPYmplY3Qua2V5cyhwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLmxlc3NUaGFuKTtcblx0XHRcdFx0Y29uc3QgYWRkZWRQcm9wZXJ0aWVzS2V5cyA9IFtdO1xuXHRcdFx0XHRwYXJhbWV0ZXJzLmZvckVhY2goZSA9PiB7XG5cdFx0XHRcdFx0aWYgKHByb3BlcnRpZXNLZXlzLmluY2x1ZGVzKGUubmFtZSkgJiYgIWFkZGVkUHJvcGVydGllc0tleXMuaW5jbHVkZXMoZS5uYW1lKSkge1xuXHRcdFx0XHRcdFx0X3BhcmFtZXRlckJpbmRpbmdzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHR0eXBlOiBlLnR5cGUsXG5cdFx0XHRcdFx0XHRcdHZhbHVlOiBwYXJzZVZhbHVlKGUudHlwZSwgcGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5sZXNzVGhhbltlLm5hbWVdKVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRhZGRlZFByb3BlcnRpZXNLZXlzLnB1c2goZS5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIuZ3JlYXRlclRoYW5PckVxdWFsKSB7XG5cdFx0XHRcdGNvbnN0IHByb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXMocGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5ncmVhdGVyVGhhbk9yRXF1YWwpO1xuXHRcdFx0XHRjb25zdCBhZGRlZFByb3BlcnRpZXNLZXlzID0gW107XG5cdFx0XHRcdHBhcmFtZXRlcnMuZm9yRWFjaChlID0+IHtcblx0XHRcdFx0XHRpZiAocHJvcGVydGllc0tleXMuaW5jbHVkZXMoZS5uYW1lKSAmJiAhYWRkZWRQcm9wZXJ0aWVzS2V5cy5pbmNsdWRlcyhlLm5hbWUpKSB7XG5cdFx0XHRcdFx0XHRfcGFyYW1ldGVyQmluZGluZ3MucHVzaCh7XG5cdFx0XHRcdFx0XHRcdHR5cGU6IGUudHlwZSxcblx0XHRcdFx0XHRcdFx0dmFsdWU6IHBhcnNlVmFsdWUoZS50eXBlLCBwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLmdyZWF0ZXJUaGFuT3JFcXVhbFtlLm5hbWVdKVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRhZGRlZFByb3BlcnRpZXNLZXlzLnB1c2goZS5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBhcmFtZXRlckJpbmRpbmdzLiRmaWx0ZXIubGVzc1RoYW5PckVxdWFsKSB7XG5cdFx0XHRcdGNvbnN0IHByb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXMocGFyYW1ldGVyQmluZGluZ3MuJGZpbHRlci5sZXNzVGhhbk9yRXF1YWwpO1xuXHRcdFx0XHRjb25zdCBhZGRlZFByb3BlcnRpZXNLZXlzID0gW107XG5cdFx0XHRcdHBhcmFtZXRlcnMuZm9yRWFjaChlID0+IHtcblx0XHRcdFx0XHRpZiAocHJvcGVydGllc0tleXMuaW5jbHVkZXMoZS5uYW1lKSAmJiAhYWRkZWRQcm9wZXJ0aWVzS2V5cy5pbmNsdWRlcyhlLm5hbWUpKSB7XG5cdFx0XHRcdFx0XHRfcGFyYW1ldGVyQmluZGluZ3MucHVzaCh7XG5cdFx0XHRcdFx0XHRcdHR5cGU6IGUudHlwZSxcblx0XHRcdFx0XHRcdFx0dmFsdWU6IHBhcnNlVmFsdWUoZS50eXBlLCBwYXJhbWV0ZXJCaW5kaW5ncy4kZmlsdGVyLmxlc3NUaGFuT3JFcXVhbFtlLm5hbWVdKVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRhZGRlZFByb3BlcnRpZXNLZXlzLnB1c2goZS5uYW1lKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIExlZnQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgLT4gaXQgc2VlbXMgdGhhdCB0aGUgZmluZCgpIG1ldGhvZCB1c2VzIGl0LCBtaWdodCBiZSByZW1vdmVkIG9uY2UgcmVmYWN0b3JlZFxuXHRcdGlmIChwYXJhbWV0ZXJzICYmIHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHZhciB2YWw7XG5cdFx0XHRcdGlmIChwYXJhbWV0ZXJCaW5kaW5ncykge1xuXHRcdFx0XHRcdGlmIChBcnJheS5pc0FycmF5KHBhcmFtZXRlckJpbmRpbmdzKSkge1xuXHRcdFx0XHRcdFx0dmFsID0gcGFyYW1ldGVyQmluZGluZ3NbaV07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHZhbCA9IHBhcmFtZXRlckJpbmRpbmdzW3BhcmFtZXRlcnNbaV0ubmFtZV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICgodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSAmJiBzcWwudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCdzZWxlY3QnKSkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnN0IGluZGV4ID0gaSArIDE7XG5cdFx0XHRcdHRoaXMuJGxvZy50cmFjZSgnQmluZGluZyB0byBwYXJhbWV0ZXJbe31dOiB7fScsIGluZGV4LCB2YWwpO1xuXHRcdFx0XHRfcGFyYW1ldGVyQmluZGluZ3MucHVzaCh7XG5cdFx0XHRcdFx0XCJ0eXBlXCI6IHBhcmFtZXRlcnNbaV0udHlwZSxcblx0XHRcdFx0XHRcInZhbHVlXCI6IHBhcnNlVmFsdWUocGFyYW1ldGVyc1tpXS50eXBlLCB2YWwpXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGxldCByZXN1bHQ7XG5cblx0XHRpZiAoc3FsLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgnc2VsZWN0JykpIHtcblx0XHRcdHJlc3VsdCA9IFF1ZXJ5LmV4ZWN1dGUoc3FsLCBfcGFyYW1ldGVyQmluZGluZ3MsIGRhdGFTb3VyY2VOYW1lKTtcblx0XHR9IGVsc2UgaWYgKHNxbC50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoJ2luc2VydCcpKSB7XG5cdFx0XHRyZXN1bHQgPSBJbnNlcnQuZXhlY3V0ZShzcWwsIF9wYXJhbWV0ZXJCaW5kaW5ncywgZGF0YVNvdXJjZU5hbWUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQgPSBVcGRhdGUuZXhlY3V0ZShzcWwsIF9wYXJhbWV0ZXJCaW5kaW5ncywgZGF0YVNvdXJjZU5hbWUpO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXN1bHQgIT09IG51bGwgPyByZXN1bHQgOiBbXTtcblx0fTtcblxuXHRmdW5jdGlvbiBwYXJzZVZhbHVlKHR5cGUsIHZhbHVlKSB7XG5cdFx0c3dpdGNoICh0eXBlLnRvVXBwZXJDYXNlKCkpIHtcblx0XHRcdGNhc2UgJ0lOVEVHRVInOlxuXHRcdFx0XHRyZXR1cm4gcGFyc2VJbnQodmFsdWUpO1xuXHRcdFx0Y2FzZSAnRE9VQkxFJzpcblx0XHRcdGNhc2UgJ0ZMT0FUJzpcblx0XHRcdFx0cmV0dXJuIHBhcnNlRmxvYXQodmFsdWUpO1xuXHRcdFx0Y2FzZSAnQk9PTEVBTic6XG5cdFx0XHRcdHJldHVybiB2YWx1ZSA/ICd0cnVlJyA6ICdmYWxzZSc7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0fVxuXHR9XG59O1xuXG5EQU8ucHJvdG90eXBlLm5vdGlmeSA9IGZ1bmN0aW9uIChldmVudCkge1xuXHRjb25zdCBmdW5jID0gdGhpc1tldmVudF07XG5cdGlmICghdGhpc1tldmVudF0pXG5cdFx0cmV0dXJuO1xuXHRpZiAodHlwZW9mIGZ1bmMgIT09ICdmdW5jdGlvbicpXG5cdFx0dGhyb3cgRXJyb3IoJ0lsbGVnYWwgYXJndW1lbnQuIE5vdCBhIGZ1bmN0aW9uOiAnICsgZnVuYyk7XG5cdGNvbnN0IGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdGZ1bmMuYXBwbHkodGhpcywgYXJncy5zbGljZSgxKSk7XG59O1xuXG4vKipcbiAqIFByZXBhcmUgYSBKU09OIG9iamVjdCBmb3IgaW5zZXJ0IGludG8gREJcbiAqL1xuREFPLnByb3RvdHlwZS5jcmVhdGVTUUxFbnRpdHkgPSBmdW5jdGlvbiAoZW50aXR5KSB7XG5cdGxldCBpO1xuXHRjb25zdCBwZXJzaXN0ZW50SXRlbSA9IHt9O1xuXHRjb25zdCBtYW5kYXRvcmllcyA9IHRoaXMub3JtLmdldE1hbmRhdG9yeVByb3BlcnRpZXMoKTtcblx0Zm9yIChpID0gMDsgaSA8IG1hbmRhdG9yaWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKG1hbmRhdG9yaWVzW2ldLmRiVmFsdWUpIHtcblx0XHRcdHBlcnNpc3RlbnRJdGVtW21hbmRhdG9yaWVzW2ldLm5hbWVdID0gbWFuZGF0b3JpZXNbaV0uZGJWYWx1ZS5hcHBseSh0aGlzLCBbZW50aXR5W21hbmRhdG9yaWVzW2ldLm5hbWVdLCBlbnRpdHldKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cGVyc2lzdGVudEl0ZW1bbWFuZGF0b3JpZXNbaV0ubmFtZV0gPSBlbnRpdHlbbWFuZGF0b3JpZXNbaV0ubmFtZV07XG5cdFx0fVxuXHR9XG5cdGNvbnN0IG9wdGlvbmFscyA9IHRoaXMub3JtLmdldE9wdGlvbmFsUHJvcGVydGllcygpO1xuXHRmb3IgKGkgPSAwOyBpIDwgb3B0aW9uYWxzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKG9wdGlvbmFsc1tpXS5kYlZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHBlcnNpc3RlbnRJdGVtW29wdGlvbmFsc1tpXS5uYW1lXSA9IG9wdGlvbmFsc1tpXS5kYlZhbHVlLmFwcGx5KHRoaXMsIFtlbnRpdHlbb3B0aW9uYWxzW2ldLm5hbWVdLCBlbnRpdHldKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cGVyc2lzdGVudEl0ZW1bb3B0aW9uYWxzW2ldLm5hbWVdID0gZW50aXR5W29wdGlvbmFsc1tpXS5uYW1lXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGVudGl0eVtvcHRpb25hbHNbaV0ubmFtZV07XG5cdFx0fVxuXHR9XG5cdHJldHVybiBwZXJzaXN0ZW50SXRlbTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGVudGl0eSBhcyBKU09OIG9iamVjdCBmcm9tIFJlc3VsdFNldCBjdXJyZW50IFJvd1xuICovXG5EQU8ucHJvdG90eXBlLmNyZWF0ZUVudGl0eSA9IGZ1bmN0aW9uIChyZXN1bHRTZXRFbnRyeSwgZW50aXR5UHJvcGVydHlOYW1lcykge1xuXHRjb25zdCBlbnRpdHkgPSB7fTtcblx0bGV0IHByb3BlcnRpZXMgPSB0aGlzLm9ybS5wcm9wZXJ0aWVzO1xuXHRpZiAoZW50aXR5UHJvcGVydHlOYW1lcyAmJiBlbnRpdHlQcm9wZXJ0eU5hbWVzLmxlbmd0aCA+IDApIHtcblx0XHRwcm9wZXJ0aWVzID0gcHJvcGVydGllcy5maWx0ZXIoZnVuY3Rpb24gKHByb3ApIHtcblx0XHRcdHJldHVybiBlbnRpdHlQcm9wZXJ0eU5hbWVzLmluZGV4T2YocHJvcC5uYW1lKSA+IC0xO1xuXHRcdH0pO1xuXHR9XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcGVydGllcy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IHByb3AgPSBwcm9wZXJ0aWVzW2ldO1xuXHRcdGVudGl0eVtwcm9wLm5hbWVdID0gcmVzdWx0U2V0RW50cnlbcHJvcC5jb2x1bW5OYW1lXTtcblx0XHRpZiAocHJvcC52YWx1ZSkge1xuXHRcdFx0ZW50aXR5W3Byb3AubmFtZV0gPSBwcm9wLnZhbHVlKGVudGl0eVtwcm9wLm5hbWVdKTtcblx0XHR9XG5cdH1cblx0T2JqZWN0LmtleXMoZW50aXR5KS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUpIHtcblx0XHRpZiAoZW50aXR5W3Byb3BlcnR5TmFtZV0gPT09IG51bGwpXG5cdFx0XHRlbnRpdHlbcHJvcGVydHlOYW1lXSA9IHVuZGVmaW5lZDtcblx0fSk7XG5cblx0bGV0IGVudGl0eVNlZ21lbnQgPSBcIlwiO1xuXHRpZiAoZW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSkge1xuXHRcdGVudGl0eVNlZ21lbnQgPSBcIltcIiArIGVudGl0eVt0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV0gKyBcIl1cIjtcblx0fVxuXHQvLyB0aGlzLiRsb2cudHJhY2UoXCJUcmFuc2Zvcm1hdGlvbiBmcm9tIHt9IERCIEpTT04gb2JqZWN0IGZpbmlzaGVkXCIsICh0aGlzLm9ybS50YWJsZSArIGVudGl0eVNlZ21lbnQpKTtcblx0cmV0dXJuIGVudGl0eTtcbn07XG5cbkRBTy5wcm90b3R5cGUudmFsaWRhdGVFbnRpdHkgPSBmdW5jdGlvbiAoZW50aXR5LCBza2lwKSB7XG5cdGlmIChlbnRpdHkgPT09IHVuZGVmaW5lZCB8fCBlbnRpdHkgPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ0lsbGVnYWwgYXJndW1lbnQ6IGVudGl0eSBpcyAnICsgZW50aXR5KTtcblx0fVxuXHRpZiAoc2tpcCkge1xuXHRcdGlmIChza2lwLmNvbnN0cnVjdG9yICE9PSBBcnJheSkge1xuXHRcdFx0c2tpcCA9IFtza2lwXTtcblx0XHR9XG5cdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBza2lwLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRza2lwW2pdO1xuXHRcdH1cblx0fVxuXHRjb25zdCBtYW5kYXRvcmllcyA9IHRoaXMub3JtLmdldE1hbmRhdG9yeVByb3BlcnRpZXMoKTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBtYW5kYXRvcmllcy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IHByb3BOYW1lID0gbWFuZGF0b3JpZXNbaV0ubmFtZTtcblx0XHRpZiAoKHNraXAgJiYgc2tpcC5pbmRleE9mKHByb3BOYW1lKSA+IC0xKSB8fCBtYW5kYXRvcmllc1tpXS50eXBlLnRvVXBwZXJDYXNlKCkgPT09ICdCT09MRUFOJylcblx0XHRcdGNvbnRpbnVlO1xuXHRcdGNvbnN0IHByb3BWYWx1ZSA9IGVudGl0eVtwcm9wTmFtZV07XG5cdFx0aWYgKHByb3BWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHByb3BWYWx1ZSA9PT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsICcgKyBwcm9wTmFtZSArICcgYXR0cmlidXRlIHZhbHVlIGluICcgKyB0aGlzLm9ybS50YWJsZSArICcgZW50aXR5OiAnICsgcHJvcFZhbHVlKTtcblx0XHR9XG5cdH1cbn07XG5cbkRBTy5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKF9lbnRpdHkpIHtcblxuXHRjb25zdCBpZHMgPSBbXTtcblx0bGV0IGVudGl0aWVzID0gX2VudGl0eTtcblx0aWYgKF9lbnRpdHkuY29uc3RydWN0b3IgIT09IEFycmF5KSB7XG5cdFx0ZW50aXRpZXMgPSBbX2VudGl0eV07XG5cdH1cblxuXHR0aGlzLiRsb2cudHJhY2UoJ0luc2VydGluZyB7fSB7fScsIHRoaXMub3JtLnRhYmxlLCAoZW50aXRpZXMubGVuZ3RoID09PSAxID8gJ2VudGl0eScgOiAnZW50aXRpZXMnKSk7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBlbnRpdGllcy5sZW5ndGg7IGkrKykge1xuXHRcdGxldCBlbnRpdHkgPSBlbnRpdGllc1tpXTtcblx0XHRlbnRpdHkgPSBlbnRpdGllc1tpXTtcblxuXHRcdHRoaXMudmFsaWRhdGVFbnRpdHkoZW50aXR5LCBbdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdKTtcblxuXHRcdC8vY2hlY2sgZm9yIHVuaXF1ZSBjb25zdHJhaW50IHZpb2xhdGlvbnNcblx0XHRjb25zdCB1bmlxdWVzID0gdGhpcy5vcm0uZ2V0VW5pcXVlUHJvcGVydGllcygpO1xuXHRcdGZvciAobGV0IF9pID0gMDsgX2kgPCB1bmlxdWVzLmxlbmd0aDsgX2krKykge1xuXHRcdFx0Y29uc3QgcHJvcCA9IHVuaXF1ZXNbX2ldO1xuXHRcdFx0Y29uc3Qgc3QgPSB0aGlzLm9ybXN0YXRlbWVudHMuZGlhbGVjdFxuXHRcdFx0XHQuc2VsZWN0KHByb3AuY29sdW1uKVxuXHRcdFx0XHQuZnJvbSh0aGlzLm9ybS50YWJsZSlcblx0XHRcdFx0LndoZXJlKHByb3AuY29sdW1uICsgJz0/JywgW3Byb3BdKTtcblx0XHRcdGNvbnN0IHBhcmFtcyA9IHt9O1xuXHRcdFx0cGFyYW1zW3Byb3AubmFtZV0gPSBlbnRpdHlbcHJvcC5uYW1lXTtcblx0XHRcdGNvbnN0IHJzID0gdGhpcy5leGVjdXRlKHN0LCBwYXJhbXMpO1xuXHRcdFx0aWYgKHJzLmxlbmd0aCA+IDApXG5cdFx0XHRcdHRocm93IEVycm9yKCdVbmlxdWUgY29uc3RyYWludCB2aW9sYXRpb24gZm9yICcgKyBwcm9wLm5hbWUgKyAnWycgKyBlbnRpdHlbcHJvcC5uYW1lXSArICddJyk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZGJFbnRpdHkgPSB0aGlzLmNyZWF0ZVNRTEVudGl0eShlbnRpdHkpO1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHBhcmFtZXRlcmljU3RhdGVtZW50ID0gdGhpcy5vcm1zdGF0ZW1lbnRzLmluc2VydC5hcHBseSh0aGlzLm9ybXN0YXRlbWVudHMpO1xuXG5cdFx0XHRpZiAodGhpcy5vcm0uaXNBdXRvSW5jcmVtZW50UHJpbWFyeUtleSgpKSB7XG5cdFx0XHRcdGNvbnN0IGlkID0gdGhpcy5nZW5lcmF0ZUlkKCk7XG5cdFx0XHRcdGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSA9IGlkO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCB1cGRhdGVkUmVjb3JkQ291bnQgPSB0aGlzLmV4ZWN1dGUocGFyYW1ldGVyaWNTdGF0ZW1lbnQsIGRiRW50aXR5KTtcblxuXHRcdFx0aWYgKCF0aGlzLm9ybS5pc0F1dG9JbmNyZW1lbnRQcmltYXJ5S2V5KCkgJiYgaXNOb3RFbXB0eUFycmF5KHVwZGF0ZWRSZWNvcmRDb3VudCkpIHtcblx0XHRcdFx0Y29uc3QgaWQgPSB1cGRhdGVkUmVjb3JkQ291bnRbMF07XG5cdFx0XHRcdGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSA9IGlkO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm5vdGlmeSgnYWZ0ZXJJbnNlcnQnLCBkYkVudGl0eSk7XG5cdFx0XHR0aGlzLm5vdGlmeSgnYmVmb3JlSW5zZXJ0QXNzb2NpYXRpb25TZXRzJywgZGJFbnRpdHkpO1xuXHRcdFx0aWYgKCh1cGRhdGVkUmVjb3JkQ291bnQgPiAwIHx8IGlzTm90RW1wdHlBcnJheSh1cGRhdGVkUmVjb3JkQ291bnQpKSAmJiB0aGlzLm9ybS5hc3NvY2lhdGlvbnMgJiYgT2JqZWN0LmtleXModGhpcy5vcm0uYXNzb2NpYXRpb25zKS5sZW5ndGgpIHtcblx0XHRcdFx0Ly9JbnNlcnQgZGVwZW5kZW5jaWVzIGlmIGFueSBhcmUgcHJvdmlkZWQgaW5saW5lIHdpdGggdGhpcyBlbnRpdHlcblx0XHRcdFx0dGhpcy4kbG9nLnRyYWNlKCdJbnNlcnRpbmcgYXNzb2NpYXRpb24gc2V0cyBmb3Ige31be31dJywgdGhpcy5vcm0udGFibGUsIGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSk7XG5cdFx0XHRcdGZvciAoY29uc3QgaWR4IGluIE9iamVjdC5rZXlzKHRoaXMub3JtLmFzc29jaWF0aW9ucykpIHtcblx0XHRcdFx0XHRjb25zdCBhc3NvY2lhdGlvbiA9IHRoaXMub3JtLmFzc29jaWF0aW9uc1tpZHhdO1xuXHRcdFx0XHRcdGNvbnN0IGFzc29jaWF0aW9uTmFtZSA9IGFzc29jaWF0aW9uWyduYW1lJ107XG5cdFx0XHRcdFx0aWYgKFt0aGlzLm9ybS5BU1NPQ0lBVElPTl9UWVBFU1snTUFOWS1UTy1NQU5ZJ10sIHRoaXMub3JtLkFTU09DSUFUSU9OX1RZUEVTWydNQU5ZLVRPLU9ORSddXS5pbmRleE9mKGFzc29jaWF0aW9uLnR5cGUpIDwgMCkge1xuXHRcdFx0XHRcdFx0aWYgKGVudGl0eVthc3NvY2lhdGlvbk5hbWVdICYmIGVudGl0eVthc3NvY2lhdGlvbk5hbWVdLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgYXNzb2NpYXRpb25EYW9GYWN0b3J5RnVuYyA9IGFzc29jaWF0aW9uLnRhcmdldERhbyB8fCB0aGlzO1xuXHRcdFx0XHRcdFx0XHRpZiAoYXNzb2NpYXRpb25EYW9GYWN0b3J5RnVuYy5jb25zdHJ1Y3RvciAhPT0gRnVuY3Rpb24pXG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgT1JNOiBBc3NvY2lhdGlvbiAnICsgYXNzb2NpYXRpb25OYW1lICsgJyBkYW8gcHJvcGVydHkgaXMgZXhwZWN0ZWQgdG8gYmUgZnVuY3Rpb24uIEluc3RlYWQsIGl0IGlzOiAnICsgKHR5cGVvZiBhc3NvY2lhdGlvbkRhb0ZhY3RvcnlGdW5jKSlcblx0XHRcdFx0XHRcdFx0Y29uc3QgYXNzb2NpYXRpb25EQU8gPSBhc3NvY2lhdGlvbkRhb0ZhY3RvcnlGdW5jLmFwcGx5KHRoaXMpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLm5vdGlmeSgnYmVmb3JlSW5zZXJ0QXNzb2NpYXRpb25TZXQnLCBlbnRpdHlbYXNzb2NpYXRpb25OYW1lXSwgZW50aXR5KTtcblx0XHRcdFx0XHRcdFx0dGhpcy4kbG9nLnRyYWNlKCdJbnNlcnRpbmcge30gaW5saW5lIGVudGl0aWVzIGludG8gYXNzb2NpYXRpb24gc2V0IHt9JywgZW50aXR5W2Fzc29jaWF0aW9uTmFtZV0ubGVuZ3RoLCBhc3NvY2lhdGlvbk5hbWUpO1xuXHRcdFx0XHRcdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IGVudGl0eVthc3NvY2lhdGlvbk5hbWVdLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgYXNzb2NpYXRlZEVudGl0eSA9IGVudGl0eVthc3NvY2lhdGlvbk5hbWVdW2pdO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGFzc29jaWF0ZWRFbnRpdHlKb2luS2V5ID0gYXNzb2NpYXRpb24uam9pbktleTtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBrZXkgPSBhc3NvY2lhdGlvbi5rZXkgfHwgdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWU7XG5cdFx0XHRcdFx0XHRcdFx0YXNzb2NpYXRlZEVudGl0eVthc3NvY2lhdGVkRW50aXR5Sm9pbktleV0gPSBlbnRpdHlba2V5XTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLm5vdGlmeSgnYmVmb3JlSW5zZXJ0QXNzb2NpYXRpb25TZXRFbnRpdHknLCBlbnRpdHlbYXNzb2NpYXRpb25OYW1lXSwgZGJFbnRpdHkpO1xuXG5cdFx0XHRcdFx0XHRcdFx0YXNzb2NpYXRpb25EQU8uaW5zZXJ0LmFwcGx5KGFzc29jaWF0aW9uREFPLCBbYXNzb2NpYXRlZEVudGl0eV0pO1xuXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0dGhpcy4kbG9nLnRyYWNlKCdJbnNlcnRpbmcge30gaW5saW5lIGVudGl0aWVzIGludG8gYXNzb2NpYXRpb24gc2V0IHt9IGZpbnNpaGVkJywgZW50aXR5W2Fzc29jaWF0aW9uTmFtZV0ubGVuZ3RoLCBhc3NvY2lhdGlvbk5hbWUpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLm5vdGlmeSgnYWZ0ZXJJbnNlcnRBc3NvY2lhdGlvblNldCcsIGVudGl0eVthc3NvY2lhdGlvbk5hbWVdLCBkYkVudGl0eSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICh1cGRhdGVkUmVjb3JkQ291bnQgPiAwIHx8IGlzTm90RW1wdHlBcnJheSh1cGRhdGVkUmVjb3JkQ291bnQpKSB7XG5cdFx0XHRcdGlkcy5wdXNoKGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSk7XG5cdFx0XHRcdHRoaXMuJGxvZy50cmFjZSgne31bXSBlbnRpdHkgaW5zZXJ0ZWQnLCB0aGlzLm9ybS50YWJsZSwgZGJFbnRpdHlbdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuJGxvZy50cmFjZSgnTm8gY2hhbmdlcyBpbmN1cnJlZCBpbiB7fScsIHRoaXMub3JtLnRhYmxlKTtcblx0XHRcdH1cblxuXG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0dGhpcy4kbG9nLmVycm9yKFwiSW5zZXJ0aW5nIHt9IHt9IGZhaWxlZFwiLCB0aGlzLm9ybS50YWJsZSwgKGVudGl0aWVzLmxlbmd0aCA9PT0gMSA/ICdlbnRpdHknIDogJ2VudGl0aWVzJyksIGUpO1xuXHRcdFx0dGhpcy4kbG9nLnRyYWNlKCdSb2xsaW5nIGJhY2sgY2hhbmdlcyBhZnRlciBmYWlsZWQge31be31dIGluc2VydC4gJywgdGhpcy5vcm0udGFibGUsIGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSk7XG5cdFx0XHRpZiAoZGJFbnRpdHlbdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0dGhpcy5yZW1vdmUoZGJFbnRpdHlbdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdKTtcblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0dGhpcy4kbG9nLmVycm9yKCdDb3VsZCBub3Qgcm9sbGJhY2sgY2hhbmdlcyBhZnRlciBmYWlsZWQge31be31dIGluc2VydC4gJywgdGhpcy5vcm0udGFibGUsIGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSwgZXJyKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhyb3cgZTtcblx0XHR9XG5cdH1cblxuXHRpZiAoX2VudGl0eS5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpXG5cdFx0cmV0dXJuIGlkc1swXTtcblx0ZWxzZVxuXHRcdHJldHVybiBpZHM7XG59O1xuXG5mdW5jdGlvbiBpc05vdEVtcHR5QXJyYXkoYXJyYXkpIHtcblx0cmV0dXJuIEFycmF5LmlzQXJyYXkoYXJyYXkpICYmIGFycmF5Lmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogVXBkYXRlIGVudGl0eSBmcm9tIGEgSlNPTiBvYmplY3QuIFJldHVybnMgdGhlIGlkIG9mIHRoZSB1cGRhdGVkIGVudGl0eS5cbiAqL1xuREFPLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZW50aXR5KSB7XG5cblx0dGhpcy4kbG9nLnRyYWNlKCdVcGRhdGluZyB7fVt7fV0gZW50aXR5JywgdGhpcy5vcm0udGFibGUsIGVudGl0eSAhPT0gdW5kZWZpbmVkID8gZW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSA6IGVudGl0eSk7XG5cblx0aWYgKGVudGl0eSA9PT0gdW5kZWZpbmVkIHx8IGVudGl0eSA9PT0gbnVsbCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignSWxsZWdhbCBhcmd1bWVudDogZW50aXR5IGlzICcgKyBlbnRpdHkpO1xuXHR9XG5cblx0Y29uc3QgaWdub3JlZFByb3BlcnRpZXMgPSB0aGlzLm9ybS5nZXRNYW5kYXRvcnlQcm9wZXJ0aWVzKClcblx0XHQuZmlsdGVyKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuXHRcdFx0cmV0dXJuIHByb3BlcnR5LmFsbG93ZWRPcHMgJiYgcHJvcGVydHkuYWxsb3dlZE9wcy5pbmRleE9mKCd1cGRhdGUnKSA8IDA7XG5cdFx0fSlcblx0XHQubWFwKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuXHRcdFx0cmV0dXJuIHByb3BlcnR5Lm5hbWU7XG5cdFx0fSk7XG5cdHRoaXMudmFsaWRhdGVFbnRpdHkoZW50aXR5LCBpZ25vcmVkUHJvcGVydGllcyk7XG5cblx0Y29uc3QgcGFyYW1ldGVyaWNTdGF0ZW1lbnQgPSB0aGlzLm9ybXN0YXRlbWVudHMudXBkYXRlLmFwcGx5KHRoaXMub3Jtc3RhdGVtZW50cywgW2VudGl0eV0pO1xuXG5cdGNvbnN0IGRiRW50aXR5ID0gdGhpcy5jcmVhdGVTUUxFbnRpdHkoZW50aXR5KTtcblxuXHR0cnkge1xuXHRcdHRoaXMubm90aWZ5KCdiZWZvcmVVcGRhdGVFbnRpdHknLCBkYkVudGl0eSk7XG5cdFx0Y29uc3QgdXBkYXRlZFJlY29yZHNDb3VudCA9IHRoaXMuZXhlY3V0ZShwYXJhbWV0ZXJpY1N0YXRlbWVudCwgZGJFbnRpdHkpO1xuXHRcdGlmICh1cGRhdGVkUmVjb3Jkc0NvdW50ID4gMClcblx0XHRcdHRoaXMuJGxvZy50cmFjZSgne31be31dIGVudGl0eSB1cGRhdGVkJywgdGhpcy5vcm0udGFibGUsIGRiRW50aXR5W3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSk7XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy4kbG9nLnRyYWNlKCdObyBjaGFuZ2VzIGluY3VycmVkIGluIHt9JywgdGhpcy5vcm0udGFibGUpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSBjYXRjaCAoZSkge1xuXHRcdHRoaXMuJGxvZy5lcnJvcignVXBkYXRpbmcge31be31dIGZhaWxlZCcsIHRoaXMub3JtLnRhYmxlLCBlbnRpdHkgIT09IHVuZGVmaW5lZCA/IGVudGl0eVt0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV0gOiBlbnRpdHksIGUpO1xuXHRcdHRocm93IGU7XG5cdH1cbn07XG5cbi8qKlxuICogRGVsZXRlIGVudGl0eSBieSBpZCwgb3IgYXJyYXkgb2YgaWRzLCBvciBkZWxldGUgYWxsIChpZiBub3QgYXJndW1lbnQgaXMgcHJvdmlkZWQpXG4gKi9cbkRBTy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKCkge1xuXG5cdGxldCBpZHMgPSBbXTtcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcblx0XHRpZHMgPSB0aGlzLmxpc3Qoe1xuXHRcdFx0XCIkc2VsZWN0XCI6IFt0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV1cblx0XHR9KS5tYXAoZnVuY3Rpb24gKGVudCkge1xuXHRcdFx0cmV0dXJuIGVudFt0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV07XG5cdFx0fS5iaW5kKHRoaXMpKTtcblx0fSBlbHNlIHtcblx0XHRpZiAoYXJndW1lbnRzWzBdLmNvbnN0cnVjdG9yICE9PSBBcnJheSkge1xuXHRcdFx0aWRzID0gW2FyZ3VtZW50c1swXV07XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlkcyA9IGFyZ3VtZW50c1swXTtcblx0XHR9XG5cdH1cblxuXHR0aGlzLiRsb2cudHJhY2UoJ0RlbGV0aW5nICcgKyB0aGlzLm9ybS50YWJsZSArICgoaWRzICE9PSB1bmRlZmluZWQgJiYgaWRzLmxlbmd0aCA9PT0gMSkgPyAnWycgKyBpZHNbMF0gKyAnXSBlbnRpdHknIDogaWRzLmxlbmd0aCArICcgZW50aXRpZXMnKSk7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBpZHMubGVuZ3RoOyBpKyspIHtcblxuXHRcdGxldCBpZCA9IGlkc1tpXTtcblx0XHQvL3ByZXZlbnQgaW1wbGljaXQgdHlwZSBjb252ZXJ0aW9uXG5cdFx0aWYgKHRoaXMub3JtLmdldFByaW1hcnlLZXkoKS50eXBlLnRvVXBwZXJDYXNlKCkgIT09ICdWQVJDSEFSJylcblx0XHRcdGlkID0gcGFyc2VJbnQoaWQsIDEwKTtcblxuXHRcdGlmIChpZHMubGVuZ3RoID4gMSlcblx0XHRcdHRoaXMuJGxvZy50cmFjZSgnRGVsZXRpbmcge31be31dIGVudGl0eScsIHRoaXMub3JtLnRhYmxlLCBpZCk7XG5cblx0XHRpZiAoaWQgPT09IHVuZGVmaW5lZCB8fCBpZCA9PT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50IGZvciBpZCBwYXJhbWV0ZXI6JyArIGlkKTtcblx0XHR9XG5cblx0XHR0cnkge1xuXG5cdFx0XHR0aGlzLm5vdGlmeSgnYmVmb3JlUmVtb3ZlRW50aXR5JywgaWQpO1xuXG5cdFx0XHQvL2ZpcnN0IHdlIGF0dGVtcHQgdG8gcmVtb3ZlIGRlcG5kZW50cyBpZiBhbnlcblx0XHRcdGlmICh0aGlzLm9ybS5hc3NvY2lhdGlvbnMpIHtcblx0XHRcdFx0Ly9SZW1vdmUgYXNzb2NpYXRlZCBkZXBlbmRlbmNpZXNcblx0XHRcdFx0Zm9yIChjb25zdCBpZHggaW4gT2JqZWN0LmtleXModGhpcy5vcm0uYXNzb2NpYXRpb25zKSkge1xuXHRcdFx0XHRcdGNvbnN0IGFzc29jaWF0aW9uID0gdGhpcy5vcm0uYXNzb2NpYXRpb25zW2lkeF07XG5cdFx0XHRcdFx0Y29uc3QgYXNzb2NpYXRpb25OYW1lID0gYXNzb2NpYXRpb25bJ25hbWUnXTtcblx0XHRcdFx0XHRpZiAoW3RoaXMub3JtLkFTU09DSUFUSU9OX1RZUEVTWydNQU5ZLVRPLU1BTlknXSwgdGhpcy5vcm0uQVNTT0NJQVRJT05fVFlQRVNbJ01BTlktVE8tT05FJ11dLmluZGV4T2YoYXNzb2NpYXRpb24udHlwZSkgPCAwKSB7XG5cdFx0XHRcdFx0XHR0aGlzLiRsb2cudHJhY2UoXCJJbnNwZWN0aW5nIHt9W3t9fV0gZW50aXR5J3MgZGVwZW5kZW5jeSAne30nIGZvciBlbnRpdGllcyB0byBkZWxldGUuXCIsIHRoaXMub3JtLnRhYmxlLCBpZCwgYXNzb2NpYXRpb25OYW1lKTtcblx0XHRcdFx0XHRcdGNvbnN0IGFzc29jaWF0aW9uREFPID0gYXNzb2NpYXRpb24udGFyZ2V0RGFvID8gYXNzb2NpYXRpb24udGFyZ2V0RGFvKCkgOiB0aGlzO1xuXHRcdFx0XHRcdFx0Y29uc3Qgc2V0dGluZ3MgPSB7fTtcblx0XHRcdFx0XHRcdGxldCBqb2luSWQgPSBpZDtcblx0XHRcdFx0XHRcdC8vY2hlY2sgaWYgd2UgYXJlIGpvaW5pbmcgb24gZmllbGQsIG90aGVyIHRoYW4gcGtcblx0XHRcdFx0XHRcdGlmIChhc3NvY2lhdGlvbi5rZXkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHR2YXIgY3R4RW50aXR5ID0gdGhpcy5maW5kKGlkKTtcblx0XHRcdFx0XHRcdFx0am9pbklkID0gY3R4RW50aXR5W2Fzc29jaWF0aW9uLmtleV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRzZXR0aW5nc1thc3NvY2lhdGlvbi5qb2luS2V5XSA9IGpvaW5JZDtcblx0XHRcdFx0XHRcdGxldCBhc3NvY2lhdGVkRW50aXRpZXM7XG5cdFx0XHRcdFx0XHQvL2Fzc29jaWF0ZWRFbnRpdGllcyA9IHRoaXMuZXhwYW5kKGFzc29jaWF0aW9uTmFtZSwgaWQpO1xuXHRcdFx0XHRcdFx0YXNzb2NpYXRlZEVudGl0aWVzID0gYXNzb2NpYXRpb25EQU8ubGlzdChzZXR0aW5ncyk7XG5cdFx0XHRcdFx0XHRpZiAoYXNzb2NpYXRlZEVudGl0aWVzICYmIGFzc29jaWF0ZWRFbnRpdGllcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuJGxvZy50cmFjZShcIkRlbGV0aW5nIHt9W3t9XSBlbnRpdHkncyB7fSBkZXBlbmRlbnQge31cIiwgdGhpcy5vcm0udGFibGUsIGlkLCBhc3NvY2lhdGVkRW50aXRpZXMubGVuZ3RoLCBhc3NvY2lhdGlvbk5hbWUpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLm5vdGlmeSgnYmVmb3JlUmVtb3ZlQXNzb2NpYXRpb25TZXQnLCBhc3NvY2lhdGVkRW50aXRpZXMsIGlkKTtcblx0XHRcdFx0XHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBhc3NvY2lhdGVkRW50aXRpZXMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBhc3NvY2lhdGVkRW50aXR5ID0gYXNzb2NpYXRlZEVudGl0aWVzW2pdO1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMubm90aWZ5KCdiZWZvcmVSZW1vdmVBc3NvY2lhdGlvblNldEVudGl0eScsIGFzc29jaWF0ZWRFbnRpdHksIGFzc29jaWF0ZWRFbnRpdGllcywgaWQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0YXNzb2NpYXRpb25EQU8ucmVtb3ZlLmFwcGx5KGFzc29jaWF0aW9uREFPLCBbYXNzb2NpYXRlZEVudGl0eVthc3NvY2lhdGlvbkRBTy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdXSk7XG5cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR0aGlzLiRsb2cudHJhY2UoXCJ7fVt7fV0gZW50aXR5J3Mge30gZGVwZW5kZW50IHt9IHt9IGRlbGV0ZWQuXCIsIHRoaXMub3JtLnRhYmxlLCBpZCwgYXNzb2NpYXRlZEVudGl0aWVzLmxlbmd0aCwgYXNzb2NpYXRpb25OYW1lLCBhc3NvY2lhdGVkRW50aXRpZXMubGVuZ3RoID4gMSA/ICdlbnRpdGllcycgOiAnZW50aXR5Jyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvL0RlbGV0ZSBieSBwcmltYXJ5IGtleSB2YWx1ZVxuXHRcdFx0Y29uc3QgcGFyYW1ldGVyaWNTdGF0ZW1lbnQgPSB0aGlzLm9ybXN0YXRlbWVudHNbXCJkZWxldGVcIl0uYXBwbHkodGhpcy5vcm1zdGF0ZW1lbnRzLCBbdGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWVdKTtcblx0XHRcdGxldCBwYXJhbXMgPSB7fTtcblx0XHRcdHBhcmFtc1t0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV0gPSBpZDtcblxuXHRcdFx0Y29uc3QgdXBkYXRlZFJlY29yZHNDb3VudCA9IHRoaXMuZXhlY3V0ZShwYXJhbWV0ZXJpY1N0YXRlbWVudCwgcGFyYW1zKTtcblxuXHRcdFx0aWYgKHVwZGF0ZWRSZWNvcmRzQ291bnQgPiAwKVxuXHRcdFx0XHR0aGlzLiRsb2cudHJhY2UoJ3t9W3t9XSBlbnRpdHkgZGVsZXRlZCcsIHRoaXMub3JtLnRhYmxlLCBpZCk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHRoaXMuJGxvZy50cmFjZSgnTm8gY2hhbmdlcyBpbmN1cnJlZCBpbiB7fScsIHRoaXMub3JtLnRhYmxlKTtcblxuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHRoaXMuJGxvZy5lcnJvcignRGVsZXRpbmcge31be31dIGVudGl0eSBmYWlsZWQnLHRoaXMub3JtLnRhYmxlLCBpZCwgZSk7XG5cdFx0XHR0aHJvdyBlO1xuXHRcdH1cblxuXHR9XG5cbn07XG5cbkRBTy5wcm90b3R5cGUuZXhwYW5kID0gZnVuY3Rpb24gKGV4cGFuc2lvblBhdGgsIGNvbnRleHQpIHtcblx0bGV0IGk7XG5cdGxldCBzZXR0aW5ncztcblx0bGV0IGtleTtcblx0bGV0IGpvaW5JZDtcblx0dGhpcy4kbG9nLnRyYWNlKCdFeHBhbmRpbmcgZm9yIGFzc29jaWF0aW9uIHBhdGgge30gYW5kIGNvbnRleHQgZW50aXR5IHt9JywgZXhwYW5zaW9uUGF0aCwgKHR5cGVvZiBhcmd1bWVudHNbMV0gIT09ICdvYmplY3QnID8gJ2lkICcgOiAnJykgKyBKU09OLnN0cmluZ2lmeShhcmd1bWVudHNbMV0pKTtcblx0aWYgKCFleHBhbnNpb25QYXRoIHx8ICFleHBhbnNpb25QYXRoLmxlbmd0aCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignSWxsZWdhbCBhcmd1bWVudDogZXhwYW5zaW9uUGF0aFsnICsgZXhwYW5zaW9uUGF0aCArICddJyk7XG5cdH1cblx0aWYgKCFjb250ZXh0KSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBjb250ZXh0WycgKyBjb250ZXh0ICsgJ10nKTtcblx0fVxuXHRjb25zdCBhc3NvY2lhdGlvbk5hbWUgPSBleHBhbnNpb25QYXRoLnNwbGljZSA/IGV4cGFuc2lvblBhdGguc3BsaWNlKDAsIDEpWzBdIDogZXhwYW5zaW9uUGF0aDtcblx0Y29uc3QgYXNzb2NpYXRpb24gPSB0aGlzLm9ybS5nZXRBc3NvY2lhdGlvbihhc3NvY2lhdGlvbk5hbWUpO1xuXHRpZiAoIWFzc29jaWF0aW9uTmFtZSB8fCAhYXNzb2NpYXRpb24pXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBVbmtub3duIGFzc29jaWF0aW9uIGZvciB0aGlzIERBTyBbJyArIGFzc29jaWF0aW9uTmFtZSArICddJyk7XG5cdGNvbnN0IGpvaW5LZXkgPSBhc3NvY2lhdGlvbi5qb2luS2V5O1xuXG5cdGxldCBjb250ZXh0RW50aXR5O1xuXHRpZiAoY29udGV4dFt0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZV0gIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnRleHRFbnRpdHkgPSBjb250ZXh0O1xuXHR9IGVsc2Uge1xuXHRcdGNvbnRleHRFbnRpdHkgPSB0aGlzLmZpbmQoY29udGV4dCk7XG5cdH1cblxuXHRpZiAoIWNvbnRleHRFbnRpdHkpIHtcblx0XHR0aHJvdyBFcnJvcignTm8gcmVjb3JkIGZvdW5kIGZvciBjb250ZXh0IGVudGl0eSBbJyArIGNvbnRleHQgKyAnXScpO1xuXHR9XG5cblx0Y29uc3QgYXNzb2NpYXRpb25UYXJnZXREQU8gPSBhc3NvY2lhdGlvbi50YXJnZXREYW8gPyBhc3NvY2lhdGlvbi50YXJnZXREYW8uYXBwbHkodGhpcykgOiB0aGlzO1xuXHRpZiAoIWFzc29jaWF0aW9uVGFyZ2V0REFPKVxuXHRcdHRocm93IEVycm9yKCdObyB0YXJnZXQgYXNzb2NpYXRpb24gREFPIGluc3RhbmNlIGF2YWlsYWJsZSBmb3IgYXNzb2NpYXRpb24gJyArIGFzc29jaWF0aW9uTmFtZSk7XG5cblx0bGV0IGV4cGFuc2lvbjtcblx0bGV0IGFzc29jaWF0aW9uRW50aXRpZXMgPSBbXTtcblxuXHRpZiAoYXNzb2NpYXRpb24udHlwZSA9PT0gdGhpcy5vcm0uQVNTT0NJQVRJT05fVFlQRVNbJ09ORS1UTy1PTkUnXSB8fCBhc3NvY2lhdGlvbi50eXBlID09PSB0aGlzLm9ybS5BU1NPQ0lBVElPTl9UWVBFU1snTUFOWS1UTy1PTkUnXSkge1xuXHRcdGpvaW5JZCA9IGNvbnRleHRFbnRpdHlbam9pbktleV07XG5cdFx0dGhpcy4kbG9nLnRyYWNlKCdFeHBhbmRpbmcgYXNzb2NpYXRpb24gdHlwZSB7fSBvbiB7fVt7fV0nLCBhc3NvY2lhdGlvbi50eXBlLCBqb2luS2V5LCBqb2luSWQpO1xuXHRcdGlmICghYXNzb2NpYXRpb24ua2V5IHx8IGFzc29jaWF0aW9uLmtleSA9PT0gYXNzb2NpYXRpb25UYXJnZXREQU8ub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lKVxuXHRcdFx0ZXhwYW5zaW9uID0gYXNzb2NpYXRpb25UYXJnZXREQU8uZmluZC5hcHBseShhc3NvY2lhdGlvblRhcmdldERBTywgW2pvaW5JZF0pO1xuXHRcdGVsc2Uge1xuXHRcdFx0bGV0IGxpc3RTZXR0aW5ncyA9IHt9O1xuXHRcdFx0bGlzdFNldHRpbmdzW1wiJGZpbHRlclwiXSA9IGFzc29jaWF0aW9uLmtleTtcblx0XHRcdGxpc3RTZXR0aW5nc1thc3NvY2lhdGlvbi5rZXldID0gam9pbklkO1xuXHRcdFx0ZXhwYW5zaW9uID0gYXNzb2NpYXRpb25UYXJnZXREQU8ubGlzdC5hcHBseShhc3NvY2lhdGlvblRhcmdldERBTywgW2xpc3RTZXR0aW5nc10pWzBdO1xuXHRcdH1cblxuXHRcdGlmIChleHBhbnNpb25QYXRoLmxlbmd0aCA+IDApIHtcblx0XHRcdHRoaXMuZXhwYW5kKGV4cGFuc2lvblBhdGgsIGV4cGFuc2lvbik7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKGFzc29jaWF0aW9uLnR5cGUgPT09IHRoaXMub3JtLkFTU09DSUFUSU9OX1RZUEVTWydPTkUtVE8tTUFOWSddKSB7XG5cdFx0c2V0dGluZ3MgPSB7fTtcblx0XHRpZiAoYXNzb2NpYXRpb24uZGVmYXVsdHMpXG5cdFx0XHRzZXR0aW5ncyA9IGFzc29jaWF0aW9uLmRlZmF1bHRzO1xuXHRcdGtleSA9IGFzc29jaWF0aW9uLmtleSB8fCB0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZTtcblx0XHRqb2luSWQgPSBjb250ZXh0RW50aXR5W2tleV07XG5cdFx0dGhpcy4kbG9nLnRyYWNlKCdFeHBhbmRpbmcgYXNzb2NpYXRpb24gdHlwZSB7fSBvbiB7fVt7fV0nLCBhc3NvY2lhdGlvbi50eXBlLCBqb2luS2V5LCBqb2luSWQpO1xuXHRcdHNldHRpbmdzW2pvaW5LZXldID0gam9pbklkO1xuXHRcdGFzc29jaWF0aW9uRW50aXRpZXMgPSBhc3NvY2lhdGlvbkVudGl0aWVzLmNvbmNhdChhc3NvY2lhdGlvblRhcmdldERBTy5saXN0LmFwcGx5KGFzc29jaWF0aW9uVGFyZ2V0REFPLCBbc2V0dGluZ3NdKSk7XG5cblx0XHRpZiAoZXhwYW5zaW9uUGF0aC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgYXNzb2NpYXRpb25FbnRpdGllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR0aGlzLmV4cGFuZChleHBhbnNpb25QYXRoLCBhc3NvY2lhdGlvbkVudGl0aWVzW2ldKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0ZXhwYW5zaW9uID0gYXNzb2NpYXRpb25FbnRpdGllcztcblx0XHR9XG5cdH0gZWxzZSBpZiAoYXNzb2NpYXRpb24udHlwZSA9PT0gdGhpcy5vcm0uQVNTT0NJQVRJT05fVFlQRVNbJ01BTlktVE8tTUFOWSddKSB7XG5cdFx0Y29uc3Qgam9pbkRBTyA9IGFzc29jaWF0aW9uLmpvaW5EYW8oKTtcblx0XHRpZiAoIWpvaW5EQU8pXG5cdFx0XHR0aHJvdyBFcnJvcignTm8gam9pbiBEQU8gaW5zdGFuY2UgYXZhaWxhYmxlIGZvciBhc3NvY2lhdGlvbiAnICsgYXNzb2NpYXRpb25OYW1lKTtcblx0XHRpZiAoIWpvaW5EQU8ubGlzdEpvaW5zKVxuXHRcdFx0dGhyb3cgRXJyb3IoJ05vIGxpc3RKb2lucyBmdW5jdGlvbiBpbiBqb2luIERBTyBpbnN0YW5jZSBhdmFpbGFibGUgZm9yIGFzc29jaWF0aW9uICcgKyBhc3NvY2lhdGlvbk5hbWUpO1xuXHRcdHNldHRpbmdzID0ge307XG5cdFx0a2V5ID0gYXNzb2NpYXRpb24ua2V5IHx8IHRoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lO1xuXHRcdGpvaW5JZCA9IGNvbnRleHRFbnRpdHlba2V5XTtcblx0XHRzZXR0aW5nc1thc3NvY2lhdGlvbi5qb2luS2V5XSA9IGpvaW5JZDtcblx0XHRhc3NvY2lhdGlvbkVudGl0aWVzID0gYXNzb2NpYXRpb25FbnRpdGllcy5jb25jYXQoam9pbkRBTy5saXN0Sm9pbnMuYXBwbHkoam9pbkRBTywgW3NldHRpbmdzLCB7IFwic291cmNlRGFvXCI6IHRoaXMsIFwiam9pbkRhb1wiOiBqb2luREFPLCBcInRhcmdldERhb1wiOiBhc3NvY2lhdGlvblRhcmdldERBTyB9XSkpO1xuXHRcdGlmIChleHBhbnNpb25QYXRoLmxlbmd0aCA+IDApIHtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBhc3NvY2lhdGlvbkVudGl0aWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHRoaXMuZXhwYW5kKGV4cGFuc2lvblBhdGgsIGFzc29jaWF0aW9uRW50aXRpZXNbaV0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRleHBhbnNpb24gPSBhc3NvY2lhdGlvbkVudGl0aWVzO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZXhwYW5zaW9uO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHNpbmdsZSBlbnRpdHkgYnkgaWQsIHBhcnNlZCBpbnRvIEpTT04gb2JqZWN0LlxuICogSWYgcmVxdWVzdGVkIGFzIGV4cGFuZGVkIHRoZSByZXR1cm5lZCBlbnRpdHkgd2lsbCBjb21wcmlzZSBhc3NvY2lhdGVkIChkZXBlbmRlbnQpIGVudGl0aWVzIHRvby4gXG4gKiBFeHBhbmQgY2FuIGJlIGEgc3RyaW5nIHRoYSB0aXMgYSB2YWxpZCBhc3NvY2lhdGlvbiBuYW1lIGRlZmluZWQgaW4gdGhpcyBkYW8gb3JtIG9yIGFuIGFycmF5IG9mIHN1Y2ggbmFtZXMuXG4gKi9cbkRBTy5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uIChpZCwgZXhwYW5kLCBzZWxlY3QpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdvYmplY3QnKSB7XG5cdFx0aWQgPSBhcmd1bWVudHNbMF0uaWQ7XG5cdFx0ZXhwYW5kID0gYXJndW1lbnRzWzBdLiRleHBhbmQgfHwgYXJndW1lbnRzWzBdLmV4cGFuZDtcblx0XHRzZWxlY3QgPSBhcmd1bWVudHNbMF0uJHNlbGVjdCB8fCBhcmd1bWVudHNbMF0uc2VsZWN0O1xuXHR9XG5cblx0dGhpcy4kbG9nLnRyYWNlKCdGaW5kaW5nIHt9W3t9XSBlbnRpdHkgd2l0aCBsaXN0IHBhcmFtZXRlcnMgZXhwYW5kW3t9XSwgc2VsZWN0W3t9XScsIHRoaXMub3JtLnRhYmxlLCBpZCwgZXhwYW5kLCBzZWxlY3QpO1xuXG5cdGlmIChpZCA9PT0gdW5kZWZpbmVkIHx8IGlkID09PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50IGZvciBpZCBwYXJhbWV0ZXI6JyArIGlkKTtcblx0fVxuXG5cdHRyeSB7XG5cdFx0bGV0IGVudGl0eTtcblx0XHRpZiAoc2VsZWN0ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdGlmIChzZWxlY3QuY29uc3RydWN0b3IgIT09IEFycmF5KSB7XG5cdFx0XHRcdGlmIChzZWxlY3QuY29uc3RydWN0b3IgPT09IFN0cmluZykge1xuXHRcdFx0XHRcdHNlbGVjdCA9IHNlbGVjdC5zcGxpdCgnLCcpLm1hcChmdW5jdGlvbiAoc2VsKSB7XG5cdFx0XHRcdFx0XHRpZiAoc2VsLmNvbnN0cnVjdG9yICE9PSBTdHJpbmcpXG5cdFx0XHRcdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBzZWxlY3QgYXJyYXkgY29tcG9uZW50cyBhcmUgZXhwZWN0ZWQgb3QgYmUgc3RyaW5ncyBidXQgZm91bmQgJyArICh0eXBlb2Ygc2VsKSk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gc2VsLnRyaW0oKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aHJvdyBFcnJvcignSWxsZWdhbCBhcmd1bWVudDogc2VsZWN0IGlzIGV4cGVjdGVkIHRvIGJlIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmdzIGJ1dCB3YXMgJyArICh0eXBlb2Ygc2VsZWN0KSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0Ly9lbnN1cmUgdGhhdCBqb2lua2V5cyBmb3IgcmVxdWlyZWQgZXhwYW5kcyBhcmUgYXZhaWxhYmxlIGFuZCBub3QgZmlsdGVyZWQgYnkgc2VsZWN0XG5cdFx0aWYgKHNlbGVjdCAhPT0gdW5kZWZpbmVkICYmIGV4cGFuZCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRzZWxlY3QucHVzaCh0aGlzLm9ybS5nZXRQcmltYXJ5S2V5KCkubmFtZSk7XG5cdFx0XHQvL1RPRE86IGNoZWNrc1xuXHRcdFx0Lypmb3IodmFyIGkgaW4gZXhwYW5kKXtcblx0XHRcdFx0dmFyIGFzc29jaWF0aW9uID0gdGhpcy5vcm0uYXNzb2NpYXRpb25zW2V4cGFuZFtpXV07XG5cdFx0XHRcdGlmKGFzc29jaWF0aW9uICYmIHNlbGVjdC5pbmRleE9mKGFzc29jaWF0aW9uLmpvaW5LZXkpPDEpe1xuXHRcdFx0XHRcdHNlbGVjdC5wdXNoKGFzc29jaWF0aW9uLmpvaW5LZXkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9Ki9cblx0XHR9XG5cdFx0bGV0IGZpbmRRYlBhcmFtcyA9IHtcblx0XHRcdHNlbGVjdDogc2VsZWN0XG5cdFx0fTtcblx0XHRjb25zdCBwYXJhbWV0ZXJpY1N0YXRlbWVudCA9IHRoaXMub3Jtc3RhdGVtZW50cy5maW5kLmFwcGx5KHRoaXMub3Jtc3RhdGVtZW50cywgW2ZpbmRRYlBhcmFtc10pO1xuXHRcdGxldCBwYXJhbXMgPSB7fTtcblxuXHRcdC8vcHJldmVudCBpbXBsaWNpdCB0eXBlIGNvbnZlcnRpb25cblx0XHRpZiAodGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLnR5cGUudG9VcHBlckNhc2UoKSAhPT0gJ1ZBUkNIQVInKVxuXHRcdFx0aWQgPSBwYXJzZUludChpZCwgMTApO1xuXG5cdFx0cGFyYW1zW3RoaXMub3JtLmdldFByaW1hcnlLZXkoKS5uYW1lXSA9IGlkO1xuXHRcdGNvbnN0IHJlc3VsdFNldCA9IHRoaXMuZXhlY3V0ZShwYXJhbWV0ZXJpY1N0YXRlbWVudCwgcGFyYW1zKTtcblxuXHRcdGlmIChyZXN1bHRTZXRbMF0pIHtcblx0XHRcdGVudGl0eSA9IHRoaXMuY3JlYXRlRW50aXR5KHJlc3VsdFNldFswXSwgc2VsZWN0KTtcblx0XHRcdGlmIChlbnRpdHkpIHtcblx0XHRcdFx0dGhpcy4kbG9nLnRyYWNlKCd7fVt7fV0gZW50aXR5IGZvdW5kJywgdGhpcy5vcm0udGFibGUsIGlkKTtcblx0XHRcdFx0dGhpcy5ub3RpZnkoJ2FmdGVyRm91bmQnLCBlbnRpdHkpO1xuXHRcdFx0XHRpZiAoZXhwYW5kICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRpZiAoZXhwYW5kLmNvbnN0cnVjdG9yICE9PSBBcnJheSkge1xuXHRcdFx0XHRcdFx0aWYgKGV4cGFuZC5jb25zdHJ1Y3RvciA9PT0gU3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRcdGV4cGFuZCA9IFN0cmluZyhleHBhbmQpO1xuXHRcdFx0XHRcdFx0XHRleHBhbmQgPSBleHBhbmQuc3BsaXQoJywnKS5tYXAoZnVuY3Rpb24gKGV4cCkge1xuXHRcdFx0XHRcdFx0XHRcdGlmIChleHAuY29uc3RydWN0b3IgIT09IFN0cmluZylcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBleHBhbmQgYXJyYXkgY29tcG9uZW50cyBhcmUgZXhwZWN0ZWQgb3QgYmUgc3RyaW5ncyBidXQgZm91bmQgJyArICh0eXBlb2YgZXhwKSk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGV4cC50cmltKCk7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgRXJyb3IoJ0lsbGVnYWwgYXJndW1lbnQ6IGV4cGFuZCBpcyBleHBlY3RlZCB0byBiZSBzdHJpbmcgb3IgYXJyYXkgb2Ygc3RyaW5ncyBidXQgd2FzICcgKyAodHlwZW9mIGV4cGFuZCkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR2YXIgYXNzb2NpYXRpb25OYW1lcyA9IHRoaXMub3JtLmdldEFzc29jaWF0aW9uTmFtZXMoKTtcblx0XHRcdFx0XHRmb3IgKHZhciBpZHggaW4gYXNzb2NpYXRpb25OYW1lcykge1xuXHRcdFx0XHRcdFx0dmFyIGFzc29jaWF0aW9uTmFtZSA9IGFzc29jaWF0aW9uTmFtZXNbaWR4XTtcblx0XHRcdFx0XHRcdGlmIChleHBhbmQuaW5kZXhPZihhc3NvY2lhdGlvbk5hbWUpID4gLTEpIHtcblx0XHRcdFx0XHRcdFx0ZW50aXR5W2Fzc29jaWF0aW9uTmFtZV0gPSB0aGlzLmV4cGFuZChbYXNzb2NpYXRpb25OYW1lXSwgZW50aXR5KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuJGxvZy50cmFjZSgne31be31dIGVudGl0eSBub3QgZm91bmQnLCB0aGlzLm9ybS50YWJsZSwgaWQpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZW50aXR5O1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0dGhpcy4kbG9nLmVycm9yKFwiRmluZGluZyB7fVt7fV0gZW50aXR5IGZhaWxlZC5cIiwgdGhpcy5vcm0udGFibGUsIGlkLCBlKTtcblx0XHR0aHJvdyBlO1xuXHR9XG59O1xuXG5EQU8ucHJvdG90eXBlLmNvdW50ID0gZnVuY3Rpb24gKHNldHRpbmdzPykge1xuXHRzZXR0aW5ncyA9IHNldHRpbmdzIHx8IHt9O1xuXG5cdGNvbnN0IHBhcmFtZXRlcmljU3RhdGVtZW50ID0gdGhpcy5vcm1zdGF0ZW1lbnRzLmNvdW50LmFwcGx5KHRoaXMub3Jtc3RhdGVtZW50cywgW3NldHRpbmdzXSk7XG5cdHRoaXMuJGxvZy50cmFjZSgnQ291bnRpbmcgJyArIHRoaXMub3JtLnRhYmxlICsgJyBlbnRpdGllcycpO1xuXG5cdGxldCBjb3VudCA9IDA7XG5cdHRyeSB7XG5cdFx0Y29uc3QgcnMgPSB0aGlzLmV4ZWN1dGUocGFyYW1ldGVyaWNTdGF0ZW1lbnQsIHNldHRpbmdzKTtcblx0XHRpZiAocnMubGVuZ3RoID4gMCkge1xuXHRcdFx0Ly9leHBlY3RhaW9uIGlzIHRoYXQgdGhlcmUgaXMgYSBzaW5nbGUgb2JqZWN0IGluIHRoZSByZXN1bHQgc2V0IHdpdGggYSBzaW5nbGUgcG9ycGVydHlcblx0XHRcdGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKHJzWzBdKVswXTtcblx0XHRcdGNvdW50ID0gcGFyc2VJbnQocnNbMF1ba2V5XSwgMTApO1xuXHRcdH1cblx0fSBjYXRjaCAoZSkge1xuXHRcdHRoaXMuJGxvZy5lcnJvcignQ291bnRpbmcge30gZW50aXRpZXMgZmFpbGVkJywgdGhpcy5vcm0udGFibGUsIGUpO1xuXHRcdGUuZXJyQ29udGV4dCA9IHBhcmFtZXRlcmljU3RhdGVtZW50LnRvU3RyaW5nKCk7XG5cdFx0dGhyb3cgZTtcblx0fVxuXG5cdHRoaXMuJGxvZy50cmFjZSgne30ge30gZW50aXRpZXMgY291bnRlZCcsIFN0cmluZyhjb3VudCksIHRoaXMub3JtLnRhYmxlKTtcblxuXHRyZXR1cm4gY291bnQ7XG59O1xuXG4vKlxuICogbGlzdCBwYXJhbWV0ZXJzOlxuICogLSAkZXhwYW5kXG4gKiAtICRmaWx0ZXJcbiAqIC0gJHNlbGVjdFxuICogLSAkc29ydFxuICogLSAkb3JkZXJcbiAqIC0gJGxpbWl0XG4gKiAtICRvZmZzZXRcbiAqL1xuREFPLnByb3RvdHlwZS5saXN0ID0gZnVuY3Rpb24gKHNldHRpbmdzKSB7XG5cblx0bGV0IGtleTtcblx0c2V0dGluZ3MgPSBzZXR0aW5ncyB8fCB7fTtcblxuXHRjb25zdCBleHBhbmQgPSBzZXR0aW5ncy4kZXhwYW5kIHx8IHNldHRpbmdzLmV4cGFuZDtcblx0aWYgKGV4cGFuZCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKGV4cGFuZC5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHtcblx0XHRcdGlmIChleHBhbmQuY29uc3RydWN0b3IgPT09IFN0cmluZykge1xuXHRcdFx0XHRpZiAoZXhwYW5kLmluZGV4T2YoJywnKSA+IC0xKSB7XG5cdFx0XHRcdFx0c2V0dGluZ3MuJGV4cGFuZCA9IGV4cGFuZC5zcGxpdCgnLCcpLm1hcChmdW5jdGlvbiAoZXhwKSB7XG5cdFx0XHRcdFx0XHRpZiAoZXhwLmNvbnN0cnVjdG9yICE9PSBTdHJpbmcpXG5cdFx0XHRcdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBleHBhbmQgYXJyYXkgY29tcG9uZW50cyBhcmUgZXhwZWN0ZWQgb3QgYmUgc3RyaW5ncyBidXQgZm91bmQgJyArICh0eXBlb2YgZXhwKSk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZXhwLnRyaW0oKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzZXR0aW5ncy4kZXhwYW5kID0gW2V4cGFuZF07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBleHBhbmQgaXMgZXhwZWN0ZWQgdG8gYmUgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MgYnV0IHdhcyAnICsgKHR5cGVvZiBleHBhbmQpKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRjb25zdCBzZWxlY3QgPSBzZXR0aW5ncy4kc2VsZWN0IHx8IHNldHRpbmdzLnNlbGVjdDtcblx0aWYgKHNlbGVjdCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKHNlbGVjdC5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHtcblx0XHRcdGlmIChzZWxlY3QuY29uc3RydWN0b3IgPT09IFN0cmluZykge1xuXHRcdFx0XHRpZiAoc2VsZWN0LmluZGV4T2YoJywnKSA+IC0xKSB7XG5cdFx0XHRcdFx0c2V0dGluZ3MuJHNlbGVjdCA9IHNlbGVjdC5zcGxpdCgnLCcpLm1hcChmdW5jdGlvbiAoZXhwKSB7XG5cdFx0XHRcdFx0XHRpZiAoZXhwLmNvbnN0cnVjdG9yICE9PSBTdHJpbmcpXG5cdFx0XHRcdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBzZWxlY3QgYXJyYXkgY29tcG9uZW50cyBhcmUgZXhwZWN0ZWQgb3QgYmUgc3RyaW5ncyBidXQgZm91bmQgJyArICh0eXBlb2YgZXhwKSk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZXhwLnRyaW0oKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzZXR0aW5ncy4kc2VsZWN0ID0gW3NlbGVjdF07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IEVycm9yKCdJbGxlZ2FsIGFyZ3VtZW50OiBzZWxlY3QgaXMgZXhwZWN0ZWQgdG8gYmUgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MgYnV0IHdhcyAnICsgKHR5cGVvZiBleHBhbmQpKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXG5cdGNvbnN0IGxpc3RBcmdzID0gW107XG5cdGZvciAoa2V5IGluIHNldHRpbmdzKSB7XG5cdFx0bGlzdEFyZ3MucHVzaCgnICcgKyBrZXkgKyAnWycgKyBzZXR0aW5nc1trZXldICsgJ10nKTtcblx0fVxuXG5cdHRoaXMuJGxvZy50cmFjZSgnTGlzdGluZyB7fSBlbnRpdHkgY29sbGVjdGlvbiB3aXRoIGxpc3Qgb3BlcmF0b3JzOiB7fScsIHRoaXMub3JtLnRhYmxlLCBsaXN0QXJncy5qb2luKCcsJykpO1xuXG5cdGlmIChzZXR0aW5ncy4kc2VsZWN0ICE9PSB1bmRlZmluZWQgJiYgZXhwYW5kICE9PSB1bmRlZmluZWQpIHtcblx0XHRzZXR0aW5ncy4kc2VsZWN0LnB1c2godGhpcy5vcm0uZ2V0UHJpbWFyeUtleSgpLm5hbWUpO1xuXHR9XG5cblx0dmFyIHBhcmFtZXRlcmljU3RhdGVtZW50ID0gdGhpcy5vcm1zdGF0ZW1lbnRzLmxpc3QuYXBwbHkodGhpcy5vcm1zdGF0ZW1lbnRzLCBbc2V0dGluZ3NdKTtcblxuXHR0cnkge1xuXHRcdGxldCBlbnRpdGllcyA9IFtdO1xuXG5cdFx0Y29uc3QgcmVzdWx0U2V0ID0gdGhpcy5leGVjdXRlKHBhcmFtZXRlcmljU3RhdGVtZW50LCBzZXR0aW5ncyk7XG5cblx0XHRyZXN1bHRTZXQuZm9yRWFjaChmdW5jdGlvbiAocnNFbnRyeSkge1xuXHRcdFx0dmFyIGVudGl0eSA9IHRoaXMuY3JlYXRlRW50aXR5KHJzRW50cnksIHNldHRpbmdzLiRzZWxlY3QpO1xuXHRcdFx0aWYgKGV4cGFuZCkge1xuXHRcdFx0XHR2YXIgYXNzb2NpYXRpb25OYW1lcyA9IHRoaXMub3JtLmdldEFzc29jaWF0aW9uTmFtZXMoKTtcblx0XHRcdFx0Zm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgYXNzb2NpYXRpb25OYW1lcy5sZW5ndGg7IGlkeCsrKSB7XG5cdFx0XHRcdFx0dmFyIGFzc29jaWF0aW9uTmFtZSA9IGFzc29jaWF0aW9uTmFtZXNbaWR4XTtcblx0XHRcdFx0XHRpZiAoZXhwYW5kLmluZGV4T2YoYXNzb2NpYXRpb25OYW1lKSA+IC0xKSB7XG5cdFx0XHRcdFx0XHRlbnRpdHlbYXNzb2NpYXRpb25OYW1lXSA9IHRoaXMuZXhwYW5kKFthc3NvY2lhdGlvbk5hbWVdLCBlbnRpdHkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5ub3RpZnkoJ2FmdGVyRm91bmQnLCBlbnRpdHksIHNldHRpbmdzKTtcblx0XHRcdGVudGl0aWVzLnB1c2goZW50aXR5KTtcblx0XHR9LmJpbmQodGhpcykpO1xuXG5cdFx0dGhpcy4kbG9nLnRyYWNlKCd7fSB7fSBlbnRpdGllcyBmb3VuZCcsIGVudGl0aWVzLmxlbmd0aCwgdGhpcy5vcm0udGFibGUpO1xuXG5cdFx0cmV0dXJuIGVudGl0aWVzO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0dGhpcy4kbG9nLmVycm9yKFwiTGlzdGluZyB7fSBlbnRpdGllcyBmYWlsZWQuXCIsIHRoaXMub3JtLnRhYmxlLCBlKTtcblx0XHR0aHJvdyBlO1xuXHR9XG59O1xuXG5EQU8ucHJvdG90eXBlLmV4aXN0c1RhYmxlID0gZnVuY3Rpb24gKCkge1xuXHR0aGlzLiRsb2cudHJhY2UoJ0NoZWNrIGV4aXN0cyB0YWJsZSAnICsgdGhpcy5vcm0udGFibGUpO1xuXHR0cnkge1xuXHRcdGNvbnN0IHBhcmFtZXRlcmljU3RhdGVtZW50ID0gdGhpcy5vcm1zdGF0ZW1lbnRzLmNvdW50LmFwcGx5KHRoaXMub3Jtc3RhdGVtZW50cyk7XG5cdFx0Y29uc3QgcnMgPSB0aGlzLmV4ZWN1dGUocGFyYW1ldGVyaWNTdGF0ZW1lbnQpO1xuXHRcdHJldHVybiBycy5sZW5ndGggPiAwO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG5EQU8ucHJvdG90eXBlLmNyZWF0ZVRhYmxlID0gZnVuY3Rpb24gKCkge1xuXHR0aGlzLiRsb2cudHJhY2UoJ0NyZWF0aW5nIHRhYmxlIHt9JywgdGhpcy5vcm0udGFibGUpO1xuXHRjb25zdCBwYXJhbWV0ZXJpY1N0YXRlbWVudCA9IHRoaXMub3Jtc3RhdGVtZW50cy5jcmVhdGVUYWJsZS5hcHBseSh0aGlzLm9ybXN0YXRlbWVudHMpO1xuXHR0cnkge1xuXHRcdHRoaXMuZXhlY3V0ZShwYXJhbWV0ZXJpY1N0YXRlbWVudCk7XG5cdFx0dGhpcy4kbG9nLnRyYWNlKCd7fSB0YWJsZSBjcmVhdGVkJywgdGhpcy5vcm0udGFibGUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0dGhpcy4kbG9nLmVycm9yKFwiQ3JlYXRlIHRhYmxlIHt9IGZhaWxlZFwiLCB0aGlzLm9ybS50YWJsZSwgZSk7XG5cdFx0dGhyb3cgZTtcblx0fVxufTtcblxuREFPLnByb3RvdHlwZS5kcm9wVGFibGUgPSBmdW5jdGlvbiAoZHJvcElkU2VxdWVuY2UpIHtcblx0dGhpcy4kbG9nLnRyYWNlKCdEcm9wcGluZyB0YWJsZSB7fS4nLCB0aGlzLm9ybS50YWJsZSk7XG5cdGNvbnN0IHBhcmFtZXRlcmljU3RhdGVtZW50ID0gdGhpcy5vcm1zdGF0ZW1lbnRzLmRyb3BUYWJsZS5hcHBseSh0aGlzLm9ybXN0YXRlbWVudHMpO1xuXHR0cnkge1xuXHRcdHRoaXMuZXhlY3V0ZShwYXJhbWV0ZXJpY1N0YXRlbWVudCk7XG5cdFx0dGhpcy4kbG9nLnRyYWNlKCdUYWJsZSB7fSBkcm9wcGVkLicsIHRoaXMub3JtLnRhYmxlKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHRoaXMuJGxvZy5lcnJvcihcIkRyb3BwaW5nIHRhYmxlIHt9IGZhaWxlZC5cIiwgdGhpcy5vcm0udGFibGUsIGUpO1xuXHRcdHRocm93IGU7XG5cdH1cblxuXHRpZiAoZHJvcElkU2VxdWVuY2UpIHtcblx0XHR0aGlzLiRsb2cudHJhY2UoJ0Ryb3BwaW5nIHRhYmxlIHt9IHNlcXVlbmNlIHt9LicsIHRoaXMub3JtLnRhYmxlLCB0aGlzLnNlcXVlbmNlTmFtZSk7XG5cdFx0dHJ5IHtcblx0XHRcdHRoaXMuZHJvcElkR2VuZXJhdG9yKCk7XG5cdFx0XHR0aGlzLiRsb2cudHJhY2UoJ1RhYmxlIHt9IHNlcXVlbmNlIHt9IGRyb3BwZWQuJywgdGhpcy5vcm0udGFibGUsIHRoaXMuc2VxdWVuY2VOYW1lKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHR0aGlzLiRsb2cuZXJyb3IoXCJEcm9wcGluZyB0YWJsZSB7fSBzZXF1ZW5jZSB7fSBmYWlsZWQuXCIsIHRoaXMub3JtLnRhYmxlLCB0aGlzLnNlcXVlbmNlTmFtZSwgZSk7XG5cdFx0XHR0aHJvdyBlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIG9EZWZpbml0aW9uIGNhbiBiZSB0YWJsZSBkZWZpbml0aW9uIG9yIHN0YW5kYXJkIG9ybSBkZWZpbml0aW9uIG9iamVjdC4gT3IgaXQgY2FuIGJlIGEgdmFsaWQgcGF0aCB0b1xuICogYSAudGFibGUgZmlsZSwgb3IgYW55IG90aGVyIHRleHQgZmlsZSBjb250aWFuaW5nIGEgc3RhbmRhcmQgZGFvIG9ybSBkZWZpbml0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKG9EZWZpbml0aW9uLCBsb2dDdHhOYW1lPzogc3RyaW5nLCBkYXRhU291cmNlTmFtZT86IHN0cmluZykge1xuXHRsZXQgb3JtO1xuXHRvcm0gPSBvRGVmaW5pdGlvbjtcblxuXHRpZiAoIWRhdGFTb3VyY2VOYW1lIHx8IGRhdGFTb3VyY2VOYW1lID09PSBudWxsKSB7XG5cdFx0ZGF0YVNvdXJjZU5hbWUgPSBjb25maWd1cmF0aW9ucy5nZXQoXCJESVJJR0lCTEVfREFUQUJBU0VfREFUQVNPVVJDRV9OQU1FX0RFRkFVTFRcIiwgXCJEZWZhdWx0REJcIik7XG5cdH1cblxuXHRsZXQgcHJvZHVjdE5hbWUgPSBnbG9iYWxzLmdldChkYXRhU291cmNlTmFtZSk7XG5cdGlmICghcHJvZHVjdE5hbWUpIHtcblx0XHRwcm9kdWN0TmFtZSA9IERhdGFiYXNlLmdldFByb2R1Y3ROYW1lKGRhdGFTb3VyY2VOYW1lKTtcblx0XHRnbG9iYWxzLnNldChkYXRhU291cmNlTmFtZSwgcHJvZHVjdE5hbWUpO1xuXHR9XG5cblx0Ly9cdH1cblx0cmV0dXJuIG5ldyBEQU8ob3JtLCBsb2dDdHhOYW1lLCBkYXRhU291cmNlTmFtZSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGFvKG9EZWZpbml0aW9uLCBsb2dDdHhOYW1lPzogc3RyaW5nLCBkYXRhU291cmNlTmFtZT86IHN0cmluZykge1xuXHRyZXR1cm4gY3JlYXRlKG9EZWZpbml0aW9uLCBsb2dDdHhOYW1lLCBkYXRhU291cmNlTmFtZSlcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUEsaUJBQTZDO0FBQzdDLDJCQUE4QztBQUM5QyxzQkFBeUI7QUFDekIsc0JBQXlCO0FBQ3pCLGdCQUFzQjtBQUN0QixvQkFBdUI7QUFDdkIsb0JBQXVCO0FBQ3ZCLGlCQUF3QjtBQUN4QixrQkFBd0M7QUFHakMsU0FBUyxJQUFJLEtBQW9CLFlBQXFCLGdCQUF5QjtBQUNyRixNQUFJLFFBQVE7QUFDWCxVQUFNLE1BQU0sMkJBQTJCLE1BQU0sR0FBRztBQUVqRCxPQUFLLFVBQU0sV0FBQUEsS0FBTyxHQUFHO0FBQ3JCLE9BQUssZUFBZSxLQUFL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QUc7QUFDWCxXQUFLLEtBQUssTUFBTSx5Q0FBeUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxjQUFjLENBQUM7QUFDN0YsWUFBTTtBQUFBLElBQ1A7QUFBQSxFQUNEO0FBRUEsU0FBTztBQUNSO0FBT08sU0FBUyxPQUFPLGFBQWEsWUFBcUIsZ0JBQXlCO0FBQ2pGLE1BQUk7QUFDSixRQUFNO0FBRU4sTUFBSSxDQUFDLGtCQUFrQixtQkFBbUIsTUFBTTtBQUMvQyxxQkFBaUIsMkJBQWUsSUFBSSw4Q0FBOEMsV0FBVztBQUFBLEVBQzlGO0FBRUEsTUFBSSxjQUFjLG9CQUFRLElBQUksY0FBYztBQUM1QyxNQUFJLENBQUMsYUFBYTtBQUNqQixrQkFBYyx5QkFBUyxlQUFlLGNBQWM7QUFDcEQsd0JBQVEsSUFBSSxnQkFBZ0IsV0FBVztBQUFBLEVBQ3hDO0FBR0EsU0FBTyxJQUFJLElBQUksS0FBSyxZQUFZLGNBQWM7QUFDL0M7QUFBQztBQUVNLFNBQVMsSUFBSSxhQUFhLFlBQXFCLGdCQUF5QjtBQUM5RSxTQUFPLE9BQU8sYUFBYSxZQUFZLGNBQWM7QUFDdEQ7IiwKICAibmFtZXMiOiBbImdldE9STSIsICJjcmVhdGVPUk1TdGF0ZW1lbnRzIl0KfQo=
|