breeze-client 2.2.1-cjs → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapter-ajax-angularjs/{breeze-client-adapter-ajax-angularjs.d.ts → index.d.ts} +1 -0
- package/adapter-ajax-fetch/{breeze-client-adapter-ajax-fetch.d.ts → index.d.ts} +1 -0
- package/adapter-ajax-httpclient/{breeze-client-adapter-ajax-httpclient.d.ts → index.d.ts} +1 -0
- package/adapter-ajax-jquery/{breeze-client-adapter-ajax-jquery.d.ts → index.d.ts} +1 -0
- package/adapter-ajax-post/{breeze-client-adapter-ajax-post.d.ts → index.d.ts} +1 -0
- package/adapter-data-service-odata/{breeze-client-adapter-data-service-odata.d.ts → index.d.ts} +1 -0
- package/adapter-data-service-webapi/{breeze-client-adapter-data-service-webapi.d.ts → index.d.ts} +1 -0
- package/adapter-model-library-backing-store/{breeze-client-adapter-model-library-backing-store.d.ts → index.d.ts} +1 -0
- package/adapter-model-library-ko/{breeze-client-adapter-model-library-ko.d.ts → index.d.ts} +1 -0
- package/adapter-uri-builder-json/{breeze-client-adapter-uri-builder-json.d.ts → index.d.ts} +1 -0
- package/adapter-uri-builder-odata/{breeze-client-adapter-uri-builder-odata.d.ts → index.d.ts} +1 -0
- package/esm2022/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +135 -0
- package/esm2022/adapter-ajax-angularjs/adapter-core.mjs +49 -0
- package/esm2022/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +5 -0
- package/esm2022/adapter-ajax-fetch/adapter-ajax-fetch.mjs +135 -0
- package/esm2022/adapter-ajax-fetch/adapter-core.mjs +49 -0
- package/esm2022/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +5 -0
- package/esm2022/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +139 -0
- package/esm2022/adapter-ajax-httpclient/adapter-core.mjs +49 -0
- package/esm2022/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +5 -0
- package/esm2022/adapter-ajax-jquery/adapter-ajax-jquery.mjs +107 -0
- package/esm2022/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +5 -0
- package/esm2022/adapter-ajax-post/adapter-ajax-post.mjs +77 -0
- package/esm2022/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +5 -0
- package/esm2022/adapter-data-service-odata/adapter-core.mjs +49 -0
- package/{esm5/adapter-data-service-odata/adapter-data-service-odata.js → esm2022/adapter-data-service-odata/adapter-data-service-odata.mjs} +138 -147
- package/esm2022/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +5 -0
- package/esm2022/adapter-data-service-webapi/adapter-data-service-webapi.mjs +100 -0
- package/esm2022/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +5 -0
- package/esm2022/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +269 -0
- package/esm2022/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +5 -0
- package/esm2022/adapter-model-library-ko/adapter-model-library-ko.mjs +241 -0
- package/esm2022/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +5 -0
- package/esm2022/adapter-uri-builder-json/adapter-core.mjs +49 -0
- package/esm2022/adapter-uri-builder-json/adapter-uri-builder-json.mjs +37 -0
- package/esm2022/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +5 -0
- package/esm2022/adapter-uri-builder-odata/adapter-core.mjs +49 -0
- package/esm2022/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +191 -0
- package/esm2022/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +5 -0
- package/esm2022/breeze-client.mjs +5 -0
- package/esm2022/index.mjs +2 -0
- package/esm2022/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +5 -0
- package/esm2022/mixin-get-entity-graph/mixin-get-entity-graph.mjs +269 -0
- package/esm2022/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +5 -0
- package/esm2022/mixin-save-queuing/mixin-save-queuing.mjs +421 -0
- package/esm2022/src/abstract-data-service-adapter.mjs +325 -0
- package/esm2022/src/array.mjs +4 -0
- package/esm2022/src/assert-param.mjs +330 -0
- package/esm2022/src/breeze.mjs +85 -0
- package/esm2022/src/complex-array.mjs +117 -0
- package/esm2022/src/config.mjs +232 -0
- package/esm2022/src/core.mjs +712 -0
- package/esm2022/src/csdl-metadata-parser.mjs +385 -0
- package/esm2022/src/data-service.mjs +221 -0
- package/esm2022/src/data-type.mjs +510 -0
- package/esm2022/src/default-property-interceptor.mjs +460 -0
- package/{esm2015/src/entity-action.js → esm2022/src/entity-action.mjs} +25 -25
- package/esm2022/src/entity-aspect.mjs +897 -0
- package/esm2022/src/entity-group.mjs +192 -0
- package/esm2022/src/entity-key.mjs +125 -0
- package/esm2022/src/entity-manager.mjs +2163 -0
- package/esm2022/src/entity-metadata.mjs +2242 -0
- package/esm2022/src/entity-query.mjs +1024 -0
- package/esm2022/src/entity-state.mjs +107 -0
- package/esm2022/src/enum.mjs +143 -0
- package/esm2022/src/event.mjs +264 -0
- package/esm2022/src/interface-registry.mjs +39 -0
- package/esm2022/src/key-generator.mjs +110 -0
- package/esm2022/src/local-query-comparison-options.mjs +65 -0
- package/esm2022/src/mapping-context.mjs +411 -0
- package/esm2022/src/naming-convention.mjs +92 -0
- package/esm2022/src/observable-array.mjs +183 -0
- package/esm2022/src/predicate.mjs +1259 -0
- package/esm2022/src/primitive-array.mjs +85 -0
- package/esm2022/src/query-options.mjs +152 -0
- package/esm2022/src/relation-array.mjs +173 -0
- package/esm2022/src/save-options.mjs +41 -0
- package/esm2022/src/unattached-children-map.mjs +56 -0
- package/esm2022/src/validate.mjs +995 -0
- package/esm2022/src/validation-options.mjs +64 -0
- package/{fesm2015/breeze-client-adapter-ajax-angularjs.js → fesm2022/breeze-client-adapter-ajax-angularjs.mjs} +6 -1
- package/fesm2022/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-ajax-fetch.js → fesm2022/breeze-client-adapter-ajax-fetch.mjs} +9 -4
- package/fesm2022/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-ajax-httpclient.js → fesm2022/breeze-client-adapter-ajax-httpclient.mjs} +6 -4
- package/fesm2022/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-ajax-jquery.js → fesm2022/breeze-client-adapter-ajax-jquery.mjs} +6 -2
- package/fesm2022/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-ajax-post.js → fesm2022/breeze-client-adapter-ajax-post.mjs} +1 -1
- package/fesm2022/breeze-client-adapter-ajax-post.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-data-service-odata.js → fesm2022/breeze-client-adapter-data-service-odata.mjs} +68 -69
- package/fesm2022/breeze-client-adapter-data-service-odata.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-data-service-webapi.js → fesm2022/breeze-client-adapter-data-service-webapi.mjs} +30 -30
- package/fesm2022/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-model-library-backing-store.js → fesm2022/breeze-client-adapter-model-library-backing-store.mjs} +14 -13
- package/fesm2022/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-model-library-ko.js → fesm2022/breeze-client-adapter-model-library-ko.mjs} +14 -13
- package/fesm2022/breeze-client-adapter-model-library-ko.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-uri-builder-json.js → fesm2022/breeze-client-adapter-uri-builder-json.mjs} +9 -8
- package/fesm2022/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
- package/{fesm2015/breeze-client-adapter-uri-builder-odata.js → fesm2022/breeze-client-adapter-uri-builder-odata.mjs} +86 -86
- package/fesm2022/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
- package/{fesm2015/breeze-client-mixin-get-entity-graph.js → fesm2022/breeze-client-mixin-get-entity-graph.mjs} +1 -1
- package/fesm2022/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
- package/{fesm2015/breeze-client-mixin-save-queuing.js → fesm2022/breeze-client-mixin-save-queuing.mjs} +23 -2
- package/fesm2022/breeze-client-mixin-save-queuing.mjs.map +1 -0
- package/{fesm2015/breeze-client.js → fesm2022/breeze-client.mjs} +1933 -1538
- package/fesm2022/breeze-client.mjs.map +1 -0
- package/mixin-get-entity-graph/{breeze-client-mixin-get-entity-graph.d.ts → index.d.ts} +1 -0
- package/mixin-save-queuing/{breeze-client-mixin-save-queuing.d.ts → index.d.ts} +1 -0
- package/package.json +94 -12
- package/src/config.d.ts +1 -1
- package/src/core.d.ts +1 -1
- package/src/entity-aspect.d.ts +1 -1
- package/src/entity-metadata.d.ts +8 -6
- package/src/entity-query.d.ts +1 -1
- package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +0 -1
- package/adapter-ajax-angularjs/package.json +0 -13
- package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +0 -1
- package/adapter-ajax-fetch/package.json +0 -13
- package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +0 -1
- package/adapter-ajax-httpclient/package.json +0 -13
- package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +0 -1
- package/adapter-ajax-jquery/package.json +0 -13
- package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +0 -1
- package/adapter-ajax-post/package.json +0 -13
- package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +0 -1
- package/adapter-data-service-odata/package.json +0 -13
- package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +0 -1
- package/adapter-data-service-webapi/package.json +0 -13
- package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +0 -1
- package/adapter-model-library-backing-store/package.json +0 -13
- package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +0 -1
- package/adapter-model-library-ko/package.json +0 -13
- package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +0 -1
- package/adapter-uri-builder-json/package.json +0 -13
- package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +0 -1
- package/adapter-uri-builder-odata/package.json +0 -13
- package/breeze-client.d.ts +0 -8
- package/breeze-client.metadata.json +0 -1
- package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +0 -190
- package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-fetch.umd.js +0 -190
- package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +0 -195
- package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-jquery.umd.js +0 -115
- package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-post.umd.js +0 -92
- package/bundles/breeze-client-adapter-ajax-post.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-ajax-post.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-data-service-odata.umd.js +0 -747
- package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +0 -16
- package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-data-service-webapi.umd.js +0 -333
- package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +0 -16
- package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +0 -280
- package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-model-library-ko.umd.js +0 -252
- package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-uri-builder-json.umd.js +0 -96
- package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +0 -1
- package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +0 -262
- package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +0 -1
- package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +0 -2
- package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +0 -1
- package/bundles/breeze-client-mixin-get-entity-graph.umd.js +0 -258
- package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +0 -1
- package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +0 -2
- package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +0 -1
- package/bundles/breeze-client-mixin-save-queuing.umd.js +0 -579
- package/bundles/breeze-client-mixin-save-queuing.umd.js.map +0 -1
- package/bundles/breeze-client-mixin-save-queuing.umd.min.js +0 -16
- package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +0 -1
- package/bundles/breeze-client.umd.js +0 -14234
- package/bundles/breeze-client.umd.js.map +0 -1
- package/bundles/breeze-client.umd.min.js +0 -16
- package/bundles/breeze-client.umd.min.js.map +0 -1
- package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -130
- package/esm2015/adapter-ajax-angularjs/adapter-core.js +0 -49
- package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
- package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -130
- package/esm2015/adapter-ajax-fetch/adapter-core.js +0 -49
- package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
- package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -137
- package/esm2015/adapter-ajax-httpclient/adapter-core.js +0 -49
- package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
- package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -103
- package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
- package/esm2015/adapter-ajax-post/adapter-ajax-post.js +0 -77
- package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
- package/esm2015/adapter-data-service-odata/adapter-core.js +0 -49
- package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +0 -463
- package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
- package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -100
- package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
- package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -268
- package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
- package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +0 -240
- package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
- package/esm2015/adapter-uri-builder-json/adapter-core.js +0 -49
- package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -36
- package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
- package/esm2015/adapter-uri-builder-odata/adapter-core.js +0 -49
- package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -192
- package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
- package/esm2015/breeze-client.js +0 -9
- package/esm2015/index.js +0 -2
- package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
- package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
- package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
- package/esm2015/mixin-save-queuing/mixin-save-queuing.js +0 -400
- package/esm2015/src/abstract-data-service-adapter.js +0 -327
- package/esm2015/src/array.js +0 -4
- package/esm2015/src/assert-param.js +0 -312
- package/esm2015/src/breeze.js +0 -85
- package/esm2015/src/complex-array.js +0 -119
- package/esm2015/src/config.js +0 -223
- package/esm2015/src/core.js +0 -714
- package/esm2015/src/csdl-metadata-parser.js +0 -385
- package/esm2015/src/data-service.js +0 -203
- package/esm2015/src/data-type.js +0 -506
- package/esm2015/src/default-property-interceptor.js +0 -460
- package/esm2015/src/entity-aspect.js +0 -804
- package/esm2015/src/entity-group.js +0 -187
- package/esm2015/src/entity-key.js +0 -116
- package/esm2015/src/entity-manager.js +0 -2094
- package/esm2015/src/entity-metadata.js +0 -2109
- package/esm2015/src/entity-query.js +0 -1015
- package/esm2015/src/entity-state.js +0 -107
- package/esm2015/src/enum.js +0 -141
- package/esm2015/src/event.js +0 -256
- package/esm2015/src/interface-registry.js +0 -41
- package/esm2015/src/key-generator.js +0 -108
- package/esm2015/src/local-query-comparison-options.js +0 -65
- package/esm2015/src/mapping-context.js +0 -411
- package/esm2015/src/naming-convention.js +0 -88
- package/esm2015/src/observable-array.js +0 -185
- package/esm2015/src/predicate.js +0 -1242
- package/esm2015/src/primitive-array.js +0 -87
- package/esm2015/src/query-options.js +0 -152
- package/esm2015/src/relation-array.js +0 -175
- package/esm2015/src/save-options.js +0 -41
- package/esm2015/src/unattached-children-map.js +0 -58
- package/esm2015/src/validate.js +0 -991
- package/esm2015/src/validation-options.js +0 -64
- package/esm5/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -132
- package/esm5/adapter-ajax-angularjs/adapter-core.js +0 -49
- package/esm5/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
- package/esm5/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -132
- package/esm5/adapter-ajax-fetch/adapter-core.js +0 -49
- package/esm5/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
- package/esm5/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -139
- package/esm5/adapter-ajax-httpclient/adapter-core.js +0 -49
- package/esm5/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
- package/esm5/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -105
- package/esm5/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
- package/esm5/adapter-ajax-post/adapter-ajax-post.js +0 -81
- package/esm5/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
- package/esm5/adapter-data-service-odata/adapter-core.js +0 -49
- package/esm5/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
- package/esm5/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -105
- package/esm5/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
- package/esm5/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -270
- package/esm5/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
- package/esm5/adapter-model-library-ko/adapter-model-library-ko.js +0 -242
- package/esm5/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
- package/esm5/adapter-uri-builder-json/adapter-core.js +0 -49
- package/esm5/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -38
- package/esm5/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
- package/esm5/adapter-uri-builder-odata/adapter-core.js +0 -49
- package/esm5/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -197
- package/esm5/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
- package/esm5/breeze-client.js +0 -9
- package/esm5/index.js +0 -2
- package/esm5/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
- package/esm5/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
- package/esm5/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
- package/esm5/mixin-save-queuing/mixin-save-queuing.js +0 -412
- package/esm5/src/abstract-data-service-adapter.js +0 -333
- package/esm5/src/array.js +0 -4
- package/esm5/src/assert-param.js +0 -317
- package/esm5/src/breeze.js +0 -85
- package/esm5/src/complex-array.js +0 -119
- package/esm5/src/config.js +0 -228
- package/esm5/src/core.js +0 -722
- package/esm5/src/csdl-metadata-parser.js +0 -385
- package/esm5/src/data-service.js +0 -207
- package/esm5/src/data-type.js +0 -513
- package/esm5/src/default-property-interceptor.js +0 -460
- package/esm5/src/entity-action.js +0 -52
- package/esm5/src/entity-aspect.js +0 -810
- package/esm5/src/entity-group.js +0 -189
- package/esm5/src/entity-key.js +0 -118
- package/esm5/src/entity-manager.js +0 -2112
- package/esm5/src/entity-metadata.js +0 -2144
- package/esm5/src/entity-query.js +0 -1042
- package/esm5/src/entity-state.js +0 -114
- package/esm5/src/enum.js +0 -144
- package/esm5/src/event.js +0 -259
- package/esm5/src/interface-registry.js +0 -43
- package/esm5/src/key-generator.js +0 -111
- package/esm5/src/local-query-comparison-options.js +0 -67
- package/esm5/src/mapping-context.js +0 -413
- package/esm5/src/naming-convention.js +0 -90
- package/esm5/src/observable-array.js +0 -201
- package/esm5/src/predicate.js +0 -1307
- package/esm5/src/primitive-array.js +0 -87
- package/esm5/src/query-options.js +0 -167
- package/esm5/src/relation-array.js +0 -175
- package/esm5/src/save-options.js +0 -43
- package/esm5/src/unattached-children-map.js +0 -60
- package/esm5/src/validate.js +0 -996
- package/esm5/src/validation-options.js +0 -66
- package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +0 -1
- package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +0 -1
- package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +0 -1
- package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +0 -1
- package/fesm2015/breeze-client-adapter-ajax-post.js.map +0 -1
- package/fesm2015/breeze-client-adapter-data-service-odata.js.map +0 -1
- package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +0 -1
- package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +0 -1
- package/fesm2015/breeze-client-adapter-model-library-ko.js.map +0 -1
- package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +0 -1
- package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +0 -1
- package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +0 -1
- package/fesm2015/breeze-client-mixin-save-queuing.js.map +0 -1
- package/fesm2015/breeze-client.js.map +0 -1
- package/fesm5/breeze-client-adapter-ajax-angularjs.js +0 -186
- package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +0 -1
- package/fesm5/breeze-client-adapter-ajax-fetch.js +0 -186
- package/fesm5/breeze-client-adapter-ajax-fetch.js.map +0 -1
- package/fesm5/breeze-client-adapter-ajax-httpclient.js +0 -193
- package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +0 -1
- package/fesm5/breeze-client-adapter-ajax-jquery.js +0 -111
- package/fesm5/breeze-client-adapter-ajax-jquery.js.map +0 -1
- package/fesm5/breeze-client-adapter-ajax-post.js +0 -86
- package/fesm5/breeze-client-adapter-ajax-post.js.map +0 -1
- package/fesm5/breeze-client-adapter-data-service-odata.js +0 -523
- package/fesm5/breeze-client-adapter-data-service-odata.js.map +0 -1
- package/fesm5/breeze-client-adapter-data-service-webapi.js +0 -111
- package/fesm5/breeze-client-adapter-data-service-webapi.js.map +0 -1
- package/fesm5/breeze-client-adapter-model-library-backing-store.js +0 -276
- package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +0 -1
- package/fesm5/breeze-client-adapter-model-library-ko.js +0 -248
- package/fesm5/breeze-client-adapter-model-library-ko.js.map +0 -1
- package/fesm5/breeze-client-adapter-uri-builder-json.js +0 -92
- package/fesm5/breeze-client-adapter-uri-builder-json.js.map +0 -1
- package/fesm5/breeze-client-adapter-uri-builder-odata.js +0 -250
- package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +0 -1
- package/fesm5/breeze-client-mixin-get-entity-graph.js +0 -254
- package/fesm5/breeze-client-mixin-get-entity-graph.js.map +0 -1
- package/fesm5/breeze-client-mixin-save-queuing.js +0 -356
- package/fesm5/breeze-client-mixin-save-queuing.js.map +0 -1
- package/fesm5/breeze-client.js +0 -13956
- package/fesm5/breeze-client.js.map +0 -1
- package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +0 -1
- package/mixin-get-entity-graph/package.json +0 -13
- package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +0 -1
- package/mixin-save-queuing/package.json +0 -13
|
@@ -1,804 +0,0 @@
|
|
|
1
|
-
import { core } from './core';
|
|
2
|
-
import { config } from './config';
|
|
3
|
-
import { BreezeEvent } from './event';
|
|
4
|
-
import { assertParam } from './assert-param';
|
|
5
|
-
import { EntityState } from './entity-state';
|
|
6
|
-
import { EntityAction } from './entity-action';
|
|
7
|
-
import { EntityType } from './entity-metadata';
|
|
8
|
-
import { EntityKey } from './entity-key';
|
|
9
|
-
import { Validator, ValidationError } from './validate';
|
|
10
|
-
import { EntityQuery } from './entity-query';
|
|
11
|
-
/**
|
|
12
|
-
An EntityAspect instance is associated with every attached entity and is accessed via the entity's 'entityAspect' property.
|
|
13
|
-
|
|
14
|
-
The EntityAspect itself provides properties to determine and modify the EntityState of the entity and has methods
|
|
15
|
-
that provide a variety of services including validation and change tracking.
|
|
16
|
-
|
|
17
|
-
An EntityAspect will almost never need to be constructed directly. You will usually get an EntityAspect by accessing
|
|
18
|
-
an entities 'entityAspect' property. This property will be automatically attached when an entity is created via either
|
|
19
|
-
a query, import or [[EntityManager.createEntity]] call.
|
|
20
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
21
|
-
> var aspect = order.entityAspect;
|
|
22
|
-
> var currentState = aspect.entityState;
|
|
23
|
-
|
|
24
|
-
**/
|
|
25
|
-
export class EntityAspect {
|
|
26
|
-
/** @hidden @internal */
|
|
27
|
-
constructor(entity) {
|
|
28
|
-
// if called without new
|
|
29
|
-
// if (!(this instanceof EntityAspect)) {
|
|
30
|
-
// return new EntityAspect(entity);
|
|
31
|
-
// }
|
|
32
|
-
/**
|
|
33
|
-
Sets the entity to an EntityState of 'Unchanged'. This is also the equivalent of calling [[EntityAspect.acceptChanges]].
|
|
34
|
-
The same operation can be performed by calling [[EntityAspect.setEntityState]].
|
|
35
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
36
|
-
> order.entityAspect.setUnchanged();
|
|
37
|
-
> // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
|
|
38
|
-
**/
|
|
39
|
-
this.setUnchanged = function () {
|
|
40
|
-
return this.setEntityState(EntityState.Unchanged);
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
Sets the entity to an EntityState of 'Modified'. This can also be achieved by changing the value of any property on an 'Unchanged' entity.
|
|
44
|
-
The same operation can be performed by calling [[EntityAspect.setEntityState]].
|
|
45
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
46
|
-
> order.entityAspect.setModified();
|
|
47
|
-
> // The 'order' entity will now be in a 'Modified' state.
|
|
48
|
-
**/
|
|
49
|
-
this.setModified = function () {
|
|
50
|
-
return this.setEntityState(EntityState.Modified);
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
Sets the entity to an EntityState of 'Deleted'. This both marks the entity as being scheduled for deletion during the next 'Save' call
|
|
54
|
-
but also removes the entity from all of its related entities. If the current entityState is 'Added', then `setDeleted()` will mark it 'Detached'
|
|
55
|
-
The same operation can be performed by calling [[EntityAspect.setEntityState]].
|
|
56
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
57
|
-
> order.entityAspect.setDeleted();
|
|
58
|
-
> // The 'order' entity will now be in a 'Deleted' state and it will no longer have any 'related' entities.
|
|
59
|
-
**/
|
|
60
|
-
this.setDeleted = function () {
|
|
61
|
-
return this.setEntityState(EntityState.Deleted);
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
Sets the entity to an EntityState of 'Detached'. This removes the entity from all of its related entities, but does NOT change the EntityState of any existing entities.
|
|
65
|
-
The same operation can be performed by calling [[EntityAspect.setEntityState]].
|
|
66
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
67
|
-
> order.entityAspect.setDetached();
|
|
68
|
-
> // The 'order' entity will now be in a 'Detached' state and it will no longer have any 'related' entities.
|
|
69
|
-
**/
|
|
70
|
-
this.setDetached = function () {
|
|
71
|
-
return this.setEntityState(EntityState.Detached);
|
|
72
|
-
};
|
|
73
|
-
this.entity = entity;
|
|
74
|
-
// TODO: keep public or not?
|
|
75
|
-
this.entityGroup = undefined;
|
|
76
|
-
this.entityManager = undefined;
|
|
77
|
-
this.entityState = EntityState.Detached;
|
|
78
|
-
this.isBeingSaved = false;
|
|
79
|
-
this.originalValues = {};
|
|
80
|
-
this.hasValidationErrors = false;
|
|
81
|
-
this._validationErrors = {};
|
|
82
|
-
// Uncomment when we implement entityAspect.isNavigationPropertyLoaded method
|
|
83
|
-
// this._loadedNavPropMap = {};
|
|
84
|
-
this.validationErrorsChanged = new BreezeEvent("validationErrorsChanged", this);
|
|
85
|
-
this.propertyChanged = new BreezeEvent("propertyChanged", this);
|
|
86
|
-
// in case this is the NULL entityAspect. - used with ComplexAspects that have no parent.
|
|
87
|
-
if (entity != null) {
|
|
88
|
-
// remove properties that should be on prototype but placed on instance by Babel
|
|
89
|
-
if (entity.hasOwnProperty('entityType')) {
|
|
90
|
-
// throw new Error("Entity instance has entityType property; should only be on prototype");
|
|
91
|
-
delete (entity.entityType);
|
|
92
|
-
}
|
|
93
|
-
entity.entityAspect = this;
|
|
94
|
-
// entityType should already be on the entity from 'watch'
|
|
95
|
-
let entityType = entity.entityType || entity._$entityType;
|
|
96
|
-
if (!entityType) {
|
|
97
|
-
let typeName = entity.prototype._$typeName;
|
|
98
|
-
if (!typeName) {
|
|
99
|
-
throw new Error("This entity is not registered as a valid EntityType");
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
throw new Error("Metadata for this entityType has not yet been resolved: " + typeName);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
let entityCtor = entityType.getCtor();
|
|
106
|
-
config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(entity, entityCtor.prototype);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/** @hidden */
|
|
110
|
-
// type-guard
|
|
111
|
-
static isEntity(obj) {
|
|
112
|
-
return obj.entityAspect != null;
|
|
113
|
-
}
|
|
114
|
-
// No longer used
|
|
115
|
-
// static createFrom(entity: Entity): EntityAspect {
|
|
116
|
-
// if (entity == null) {
|
|
117
|
-
// return EntityAspect._nullInstance;
|
|
118
|
-
// } else if (entity.entityAspect) {
|
|
119
|
-
// return entity.entityAspect;
|
|
120
|
-
// }
|
|
121
|
-
// return new EntityAspect(entity);
|
|
122
|
-
// }
|
|
123
|
-
// TODO: refactor this and the instance getPropertyValue method.
|
|
124
|
-
/**
|
|
125
|
-
Returns the value of a specified 'property path' for a specified entity.
|
|
126
|
-
|
|
127
|
-
The propertyPath can be either a string delimited with '.' or a string array.
|
|
128
|
-
**/
|
|
129
|
-
// used by EntityQuery and Predicate
|
|
130
|
-
static getPropertyPathValue(obj, propertyPath) {
|
|
131
|
-
let properties = Array.isArray(propertyPath) ? propertyPath : propertyPath.split(".");
|
|
132
|
-
if (properties.length === 1) {
|
|
133
|
-
return obj.getProperty(propertyPath);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
let nextValue = obj;
|
|
137
|
-
// hack use of some to perform mapFirst operation.
|
|
138
|
-
properties.some((prop) => {
|
|
139
|
-
nextValue = nextValue.getProperty(prop);
|
|
140
|
-
return nextValue == null;
|
|
141
|
-
});
|
|
142
|
-
return nextValue;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
Returns the [[EntityKey]] for this Entity.
|
|
147
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
148
|
-
> var entityKey = order.entityAspect.getKey();
|
|
149
|
-
@param forceRefresh - (boolean=false) Forces the recalculation of the key. This should normally be unnecessary.
|
|
150
|
-
@return The [[EntityKey]] associated with this Entity.
|
|
151
|
-
**/
|
|
152
|
-
getKey(forceRefresh = false) {
|
|
153
|
-
forceRefresh = assertParam(forceRefresh, "forceRefresh").isBoolean().isOptional().check(false);
|
|
154
|
-
if (forceRefresh || !this._entityKey) {
|
|
155
|
-
let entityType = this.entity.entityType;
|
|
156
|
-
let keyProps = entityType.keyProperties;
|
|
157
|
-
let values = keyProps.map(function (p) {
|
|
158
|
-
return this.entity.getProperty(p.name);
|
|
159
|
-
}, this);
|
|
160
|
-
this._entityKey = new EntityKey(entityType, values);
|
|
161
|
-
}
|
|
162
|
-
return this._entityKey;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
Returns the entity to an [[EntityState]] of 'Unchanged' by committing all changes made since the entity was last queried
|
|
166
|
-
had 'acceptChanges' called on it.
|
|
167
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
168
|
-
> order.entityAspect.acceptChanges();
|
|
169
|
-
> // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
|
|
170
|
-
**/
|
|
171
|
-
acceptChanges() {
|
|
172
|
-
if (!this.entity)
|
|
173
|
-
return;
|
|
174
|
-
this._checkOperation("acceptChanges");
|
|
175
|
-
let em = this.entityManager;
|
|
176
|
-
if (this.entityState.isDeleted()) {
|
|
177
|
-
em.detachEntity(this.entity);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
this.setUnchanged();
|
|
181
|
-
}
|
|
182
|
-
em.entityChanged.publish({ entityAction: EntityAction.AcceptChanges, entity: this.entity });
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
Returns the entity to an [[EntityState]] of 'Unchanged' by rejecting all changes made to it since the entity was last queried
|
|
186
|
-
had 'rejectChanges' called on it.
|
|
187
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
188
|
-
> order.entityAspect.rejectChanges();
|
|
189
|
-
> // The 'order' entity will now be in an 'Unchanged' state with any changes rejected.
|
|
190
|
-
**/
|
|
191
|
-
rejectChanges() {
|
|
192
|
-
this._checkOperation("rejectChanges");
|
|
193
|
-
let entity = this.entity;
|
|
194
|
-
let entityManager = this.entityManager;
|
|
195
|
-
// we do not want PropertyChange or EntityChange events to occur here
|
|
196
|
-
core.using(entityManager, "isRejectingChanges", true, function () {
|
|
197
|
-
rejectChangesCore(entity);
|
|
198
|
-
});
|
|
199
|
-
if (this.entityState.isAdded()) {
|
|
200
|
-
// next line is needed because the following line will cause this.entityManager -> null;
|
|
201
|
-
entityManager.detachEntity(entity);
|
|
202
|
-
// need to tell em that an entity that needed to be saved no longer does.
|
|
203
|
-
entityManager._notifyStateChange(entity, false);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
if (this.entityState.isDeleted()) {
|
|
207
|
-
entityManager._linkRelatedEntities(entity);
|
|
208
|
-
}
|
|
209
|
-
this.setUnchanged();
|
|
210
|
-
// propertyChanged propertyName is not specified because more than one property may have changed.
|
|
211
|
-
this.propertyChanged.publish({ entity: entity, propertyName: null });
|
|
212
|
-
entityManager.entityChanged.publish({ entityAction: EntityAction.RejectChanges, entity: entity });
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/** @hidden @internal */
|
|
216
|
-
// TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
|
|
217
|
-
getPropertyPath(propName) {
|
|
218
|
-
return propName;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
Sets the entity to an EntityState of 'Added'. This is NOT the equivalent of calling [[EntityManager.addEntity]]
|
|
222
|
-
because no key generation will occur for autogenerated keys as a result of this operation. As a result this operation can be problematic
|
|
223
|
-
unless you are certain that the entity being marked 'Added' does not already exist in the database and does not have an autogenerated key.
|
|
224
|
-
The same operation can be performed by calling [[EntityAspect.setEntityState]].
|
|
225
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
226
|
-
> order.entityAspect.setAdded();
|
|
227
|
-
> // The 'order' entity will now be in an 'Added' state.
|
|
228
|
-
**/
|
|
229
|
-
setAdded() {
|
|
230
|
-
return this.setEntityState(EntityState.Added);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
Sets the entity to the specified EntityState. See also 'setUnchanged', 'setModified', 'setDetached', etc.
|
|
234
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
235
|
-
> order.entityAspect.setEntityState(EntityState.Unchanged);
|
|
236
|
-
> // The 'order' entity will now be in a 'Unchanged' state.
|
|
237
|
-
**/
|
|
238
|
-
setEntityState(entityState) {
|
|
239
|
-
if (this.entityState === entityState)
|
|
240
|
-
return false;
|
|
241
|
-
this._checkOperation("setEntityState");
|
|
242
|
-
if (this.entityState.isDetached()) {
|
|
243
|
-
throw new Error("You cannot set the 'entityState' of an entity when it is detached - except by first attaching it to an EntityManager");
|
|
244
|
-
}
|
|
245
|
-
let entity = this.entity;
|
|
246
|
-
let em = this.entityManager;
|
|
247
|
-
let needsSave = true;
|
|
248
|
-
if (entityState === EntityState.Unchanged) {
|
|
249
|
-
clearOriginalValues(entity);
|
|
250
|
-
delete this.hasTempKey;
|
|
251
|
-
needsSave = false;
|
|
252
|
-
}
|
|
253
|
-
else if (entityState === EntityState.Added) {
|
|
254
|
-
clearOriginalValues(entity);
|
|
255
|
-
// TODO: more to do here... like regenerating key ???
|
|
256
|
-
}
|
|
257
|
-
else if (entityState === EntityState.Deleted) {
|
|
258
|
-
if (this.entityState.isAdded()) {
|
|
259
|
-
// turn it into a detach and exit early
|
|
260
|
-
this.setEntityState(EntityState.Detached);
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
// TODO: think about cascade deletes
|
|
265
|
-
// entityState needs to be set it early in this one case to insure that fk's are not cleared.
|
|
266
|
-
this.entityState = EntityState.Deleted;
|
|
267
|
-
removeFromRelations(entity, EntityState.Deleted);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
else if (entityState === EntityState.Modified) {
|
|
271
|
-
// nothing extra needed
|
|
272
|
-
}
|
|
273
|
-
else if (entityState === EntityState.Detached) {
|
|
274
|
-
let group = this.entityGroup;
|
|
275
|
-
// no group === already detached.
|
|
276
|
-
if (!group)
|
|
277
|
-
return false;
|
|
278
|
-
group.detachEntity(entity);
|
|
279
|
-
// needs to occur early here - so this IS deliberately redundent with the same code later in this method.
|
|
280
|
-
this.entityState = entityState;
|
|
281
|
-
removeFromRelations(entity, EntityState.Detached);
|
|
282
|
-
this._detach();
|
|
283
|
-
em.entityChanged.publish({ entityAction: EntityAction.Detach, entity: entity });
|
|
284
|
-
needsSave = false;
|
|
285
|
-
}
|
|
286
|
-
this.entityState = entityState;
|
|
287
|
-
em._notifyStateChange(entity, needsSave);
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
Performs a query for the value of a specified [[NavigationProperty]]. __Async__
|
|
292
|
-
> emp.entityAspect.loadNavigationProperty("Orders").then(function (data) {
|
|
293
|
-
> var orders = data.results;
|
|
294
|
-
> }).catch(function (exception) {
|
|
295
|
-
> // handle exception here;
|
|
296
|
-
> });
|
|
297
|
-
@param navigationProperty - The NavigationProperty or the name of the NavigationProperty to 'load'.
|
|
298
|
-
@param callback - Function to call on success.
|
|
299
|
-
@param errorCallback - Function to call on failure.
|
|
300
|
-
@return Promise with shape
|
|
301
|
-
- results {Array of Entity}
|
|
302
|
-
- query {EntityQuery} The original query
|
|
303
|
-
- httpResponse {httpResponse} The HttpResponse returned from the server.
|
|
304
|
-
**/
|
|
305
|
-
loadNavigationProperty(navigationProperty, callback, errorCallback) {
|
|
306
|
-
let entity = this.entity;
|
|
307
|
-
let navProperty = entity.entityType._checkNavProperty(navigationProperty);
|
|
308
|
-
let query = EntityQuery.fromEntityNavigation(entity, navProperty);
|
|
309
|
-
// return entity.entityAspect.entityManager.executeQuery(query, callback, errorCallback);
|
|
310
|
-
let promise = entity.entityAspect.entityManager.executeQuery(query);
|
|
311
|
-
return promise.then((data) => {
|
|
312
|
-
this._markAsLoaded(navProperty.name);
|
|
313
|
-
if (callback)
|
|
314
|
-
callback(data);
|
|
315
|
-
return Promise.resolve(data);
|
|
316
|
-
}, (error) => {
|
|
317
|
-
if (errorCallback)
|
|
318
|
-
errorCallback(error);
|
|
319
|
-
return Promise.reject(error);
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
Marks this navigationProperty on this entity as already having been loaded.
|
|
324
|
-
> emp.entityAspect.markNavigationPropertyAsLoaded("Orders");
|
|
325
|
-
@param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
|
|
326
|
-
**/
|
|
327
|
-
markNavigationPropertyAsLoaded(navigationProperty) {
|
|
328
|
-
if (!this.entity)
|
|
329
|
-
return;
|
|
330
|
-
let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
|
|
331
|
-
this._markAsLoaded(navProperty.name);
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
Determines whether a navigationProperty on this entity has already been loaded.
|
|
335
|
-
|
|
336
|
-
A navigation property is considered loaded when any of the following three conditions applies:
|
|
337
|
-
|
|
338
|
-
1. It was fetched from the backend server.
|
|
339
|
-
<br/> This can be the result of an expand query or a call to the [[EntityAspect.loadNavigationProperty]] method.
|
|
340
|
-
<br/> Note that even if the fetch returns nothing the property is still marked as loaded in this case.
|
|
341
|
-
1. The property is scalar and has been set to a nonnull value.
|
|
342
|
-
1. The [[EntityAspect.markNavigationPropertyAsLoaded]] was called.
|
|
343
|
-
|
|
344
|
-
> var wasLoaded = emp.entityAspect.isNavigationPropertyLoaded("Orders");
|
|
345
|
-
@param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
|
|
346
|
-
**/
|
|
347
|
-
isNavigationPropertyLoaded(navigationProperty) {
|
|
348
|
-
if (!this.entity)
|
|
349
|
-
return;
|
|
350
|
-
let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
|
|
351
|
-
if (navProperty.isScalar && this.entity.getProperty(navProperty.name) != null) {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
return this._loadedNps && this._loadedNps.indexOf(navProperty.name) >= 0;
|
|
355
|
-
}
|
|
356
|
-
/** @hidden @internal */
|
|
357
|
-
_markAsLoaded(navPropName) {
|
|
358
|
-
this._loadedNps = this._loadedNps || [];
|
|
359
|
-
core.arrayAddItemUnique(this._loadedNps, navPropName);
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
Performs validation on the entity, any errors encountered during the validation are available via the
|
|
363
|
-
[[EntityAspect.getValidationErrors]] method. Validating an entity means executing
|
|
364
|
-
all of the validators on both the entity itself as well as those on each of its properties.
|
|
365
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
366
|
-
> var isOk = order.entityAspect.validateEntity();
|
|
367
|
-
> // isOk will be 'true' if there are no errors on the entity.
|
|
368
|
-
> if (!isOk) {
|
|
369
|
-
> var errors = order.entityAspect.getValidationErrors();
|
|
370
|
-
> }
|
|
371
|
-
@return Whether the entity passed validation.
|
|
372
|
-
**/
|
|
373
|
-
validateEntity() {
|
|
374
|
-
let ok = true;
|
|
375
|
-
this._processValidationOpAndPublish(function (that) {
|
|
376
|
-
ok = validateTarget(that.entity);
|
|
377
|
-
});
|
|
378
|
-
return ok;
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
Performs validation on a specific property of this entity, any errors encountered during the validation are available via the
|
|
382
|
-
[[EntityAspect.getValidationErrors]] method. Validating a property means executing
|
|
383
|
-
all of the validators on the specified property. This call is also made automatically anytime a property
|
|
384
|
-
of an entity is changed.
|
|
385
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
386
|
-
> var isOk = order.entityAspect.validateProperty("Order");
|
|
387
|
-
|
|
388
|
-
or
|
|
389
|
-
> var orderDateProperty = order.entityType.getProperty("OrderDate");
|
|
390
|
-
> var isOk = order.entityAspect.validateProperty(OrderDateProperty);
|
|
391
|
-
@param property - The [[DataProperty]] or [[NavigationProperty]] to validate or a string
|
|
392
|
-
with the name of the property or a property path with the path to a property of a complex object.
|
|
393
|
-
@param context - A context object used to pass additional information to each [[Validator]].
|
|
394
|
-
@return Whether the entity passed validation.
|
|
395
|
-
**/
|
|
396
|
-
validateProperty(property, context) {
|
|
397
|
-
let value = this.getPropertyValue(property); // performs validations
|
|
398
|
-
if (value && value.complexAspect) {
|
|
399
|
-
return validateTarget(value);
|
|
400
|
-
}
|
|
401
|
-
context = context || {};
|
|
402
|
-
context.entity = this.entity;
|
|
403
|
-
if (typeof property === "string") {
|
|
404
|
-
context.property = this.entity.entityType.getProperty(property, true);
|
|
405
|
-
context.propertyName = property;
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
context.property = property;
|
|
409
|
-
context.propertyName = property.name;
|
|
410
|
-
}
|
|
411
|
-
return this._validateProperty(value, context);
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
Returns the validation errors associated with either the entire entity or any specified property.
|
|
415
|
-
|
|
416
|
-
This method can return all of the errors for an Entity
|
|
417
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
418
|
-
> var valErrors = order.entityAspect.getValidationErrors();
|
|
419
|
-
|
|
420
|
-
as well as those for just a specific property.
|
|
421
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
422
|
-
> var orderDateErrors = order.entityAspect.getValidationErrors("OrderDate");
|
|
423
|
-
|
|
424
|
-
which can also be expressed as
|
|
425
|
-
> // assume order is an order entity attached to an EntityManager.
|
|
426
|
-
> var orderDateProperty = order.entityType.getProperty("OrderDate");
|
|
427
|
-
> var orderDateErrors = order.entityAspect.getValidationErrors(orderDateProperty);
|
|
428
|
-
@param property - The property for which validation errors should be retrieved.
|
|
429
|
-
If omitted, all of the validation errors for this entity will be returned.
|
|
430
|
-
@return A array of validation errors.
|
|
431
|
-
**/
|
|
432
|
-
getValidationErrors(property) {
|
|
433
|
-
assertParam(property, "property").isOptional().isEntityProperty().or().isString().check();
|
|
434
|
-
let result = core.getOwnPropertyValues(this._validationErrors);
|
|
435
|
-
if (property) {
|
|
436
|
-
let propertyName = typeof (property) === 'string' ? property : property.name;
|
|
437
|
-
result = result.filter(function (ve) {
|
|
438
|
-
return ve.property && (ve.property.name === propertyName || (propertyName.indexOf(".") !== -1 && ve.propertyName === propertyName));
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
return result;
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
Adds a validation error.
|
|
445
|
-
**/
|
|
446
|
-
addValidationError(validationError) {
|
|
447
|
-
assertParam(validationError, "validationError").isInstanceOf(ValidationError).check();
|
|
448
|
-
this._processValidationOpAndPublish(function (that) {
|
|
449
|
-
that._addValidationError(validationError);
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
Removes a validation error.
|
|
454
|
-
@param validationErrorOrKey - Either a ValidationError or a ValidationError 'key' value
|
|
455
|
-
**/
|
|
456
|
-
removeValidationError(validationErrorOrKey) {
|
|
457
|
-
assertParam(validationErrorOrKey, "validationErrorOrKey").isString().or().isInstanceOf(ValidationError).or().isInstanceOf(Validator).check();
|
|
458
|
-
let key = (typeof (validationErrorOrKey) === "string") ? validationErrorOrKey : validationErrorOrKey.key;
|
|
459
|
-
this._processValidationOpAndPublish(function (that) {
|
|
460
|
-
that._removeValidationError(key);
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
Removes all of the validation errors for a specified entity
|
|
465
|
-
**/
|
|
466
|
-
clearValidationErrors() {
|
|
467
|
-
this._processValidationOpAndPublish(function (that) {
|
|
468
|
-
core.objectForEach(that._validationErrors, function (key, valError) {
|
|
469
|
-
if (valError) {
|
|
470
|
-
delete that._validationErrors[key];
|
|
471
|
-
that._pendingValidationResult.removed.push(valError);
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
that.hasValidationErrors = !core.isEmpty(that._validationErrors);
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
Returns an [[EntityKey]] for the entity pointed to by the specified scalar NavigationProperty.
|
|
479
|
-
This only returns an EntityKey if the current entity is a 'child' entity along the specified NavigationProperty.
|
|
480
|
-
i.e. has a single parent.
|
|
481
|
-
|
|
482
|
-
@param navigationProperty - The [[NavigationProperty]] ( pointing to a parent).
|
|
483
|
-
@returns Either a parent EntityKey if this is a 'child' entity or null;
|
|
484
|
-
*/
|
|
485
|
-
getParentKey(navigationProperty) {
|
|
486
|
-
if (!this.entity)
|
|
487
|
-
return null;
|
|
488
|
-
// TODO: review this - not sure about the comment.
|
|
489
|
-
// NavigationProperty doesn't yet exist
|
|
490
|
-
// assertParam(navigationProperty, "navigationProperty").isInstanceOf(NavigationProperty).check();
|
|
491
|
-
let fkNames = navigationProperty.foreignKeyNames;
|
|
492
|
-
if (fkNames.length === 0)
|
|
493
|
-
return null;
|
|
494
|
-
let that = this;
|
|
495
|
-
let fkValues = fkNames.map(function (fkn) {
|
|
496
|
-
return that.entity.getProperty(fkn);
|
|
497
|
-
});
|
|
498
|
-
return new EntityKey(navigationProperty.entityType, fkValues);
|
|
499
|
-
}
|
|
500
|
-
// TODO: refactor this and the static getPropertyPathValue.
|
|
501
|
-
/**
|
|
502
|
-
Returns the value of a specified DataProperty or NavigationProperty or 'property path'.
|
|
503
|
-
**/
|
|
504
|
-
getPropertyValue(property) {
|
|
505
|
-
assertParam(property, "property").isString().or().isEntityProperty().check();
|
|
506
|
-
let value;
|
|
507
|
-
if (typeof (property) === 'string') {
|
|
508
|
-
let propNames = property.trim().split(".");
|
|
509
|
-
let propName = propNames.shift();
|
|
510
|
-
value = this.entity;
|
|
511
|
-
value = value.getProperty(propName);
|
|
512
|
-
while (propNames.length > 0) {
|
|
513
|
-
propName = propNames.shift();
|
|
514
|
-
value = value.getProperty(propName);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
if (!(property.parentType instanceof EntityType)) {
|
|
519
|
-
throw new Error("The validateProperty method does not accept a 'property' parameter whose parentType is a ComplexType; " +
|
|
520
|
-
"Pass a 'property path' string as the 'property' parameter instead ");
|
|
521
|
-
}
|
|
522
|
-
value = this.entity.getProperty(property.name);
|
|
523
|
-
}
|
|
524
|
-
return value;
|
|
525
|
-
}
|
|
526
|
-
// internal methods
|
|
527
|
-
/** @hidden @internal */
|
|
528
|
-
_checkOperation(operationName) {
|
|
529
|
-
if (this.isBeingSaved) {
|
|
530
|
-
throw new Error("Cannot perform a '" + operationName + "' on an entity that is in the process of being saved");
|
|
531
|
-
}
|
|
532
|
-
// allows chaining
|
|
533
|
-
return this;
|
|
534
|
-
}
|
|
535
|
-
/** @hidden @internal */
|
|
536
|
-
_detach() {
|
|
537
|
-
this.entityGroup = undefined;
|
|
538
|
-
this.entityManager = undefined;
|
|
539
|
-
this.entityState = EntityState.Detached;
|
|
540
|
-
this.originalValues = {};
|
|
541
|
-
this._validationErrors = {};
|
|
542
|
-
this.hasValidationErrors = false;
|
|
543
|
-
this.validationErrorsChanged.clear();
|
|
544
|
-
this.propertyChanged.clear();
|
|
545
|
-
}
|
|
546
|
-
// called from defaultInterceptor.
|
|
547
|
-
/** @hidden @internal */
|
|
548
|
-
_validateProperty(value, context) {
|
|
549
|
-
let ok = true;
|
|
550
|
-
this._processValidationOpAndPublish(function (that) {
|
|
551
|
-
context.property.getAllValidators().forEach(function (validator) {
|
|
552
|
-
ok = validate(that, validator, value, context) && ok;
|
|
553
|
-
});
|
|
554
|
-
});
|
|
555
|
-
return ok;
|
|
556
|
-
}
|
|
557
|
-
/** @hidden @internal */
|
|
558
|
-
_processValidationOpAndPublish(validationFn) {
|
|
559
|
-
if (this._pendingValidationResult) {
|
|
560
|
-
// only top level processValidations call publishes
|
|
561
|
-
validationFn(this);
|
|
562
|
-
}
|
|
563
|
-
else {
|
|
564
|
-
try {
|
|
565
|
-
this._pendingValidationResult = { entity: this.entity, added: [], removed: [] };
|
|
566
|
-
validationFn(this);
|
|
567
|
-
if (this._pendingValidationResult.added.length > 0 || this._pendingValidationResult.removed.length > 0) {
|
|
568
|
-
this.validationErrorsChanged.publish(this._pendingValidationResult);
|
|
569
|
-
// this might be a detached entity hence the guard below.
|
|
570
|
-
this.entityManager && this.entityManager.validationErrorsChanged.publish(this._pendingValidationResult);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
finally {
|
|
574
|
-
this._pendingValidationResult = undefined;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
/** @hidden @internal */
|
|
579
|
-
// TODO: add/use a ValidationError type
|
|
580
|
-
_addValidationError(validationError) {
|
|
581
|
-
this._validationErrors[validationError.key] = validationError;
|
|
582
|
-
this.hasValidationErrors = true;
|
|
583
|
-
this._pendingValidationResult.added.push(validationError);
|
|
584
|
-
}
|
|
585
|
-
/** @hidden @internal */
|
|
586
|
-
_removeValidationError(key) {
|
|
587
|
-
let valError = this._validationErrors[key];
|
|
588
|
-
if (valError) {
|
|
589
|
-
delete this._validationErrors[key];
|
|
590
|
-
this.hasValidationErrors = !core.isEmpty(this._validationErrors);
|
|
591
|
-
this._pendingValidationResult.removed.push(valError);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
/** @hidden @internal */
|
|
596
|
-
EntityAspect._nullInstance = new EntityAspect(); // TODO: determine if this works
|
|
597
|
-
BreezeEvent.bubbleEvent(EntityAspect.prototype, function () {
|
|
598
|
-
return this.entityManager;
|
|
599
|
-
});
|
|
600
|
-
function rejectChangesCore(target) {
|
|
601
|
-
let aspect = target.entityAspect || target.complexAspect;
|
|
602
|
-
let stype = target.entityType || target.complexType;
|
|
603
|
-
let originalValues = aspect.originalValues;
|
|
604
|
-
for (let propName in originalValues) {
|
|
605
|
-
target.setProperty(propName, originalValues[propName]);
|
|
606
|
-
}
|
|
607
|
-
stype.complexProperties.forEach(function (cp) {
|
|
608
|
-
let cos = target.getProperty(cp.name);
|
|
609
|
-
if (cp.isScalar) {
|
|
610
|
-
rejectChangesCore(cos);
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
cos._rejectChanges();
|
|
614
|
-
cos.forEach(rejectChangesCore);
|
|
615
|
-
}
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
function removeFromRelations(entity, entityState) {
|
|
619
|
-
// remove this entity from any collections.
|
|
620
|
-
// mark the entity deleted or detached
|
|
621
|
-
let isDeleted = entityState.isDeleted();
|
|
622
|
-
if (isDeleted) {
|
|
623
|
-
removeFromRelationsCore(entity);
|
|
624
|
-
}
|
|
625
|
-
else {
|
|
626
|
-
core.using(entity.entityAspect.entityManager, "isLoading", true, function () {
|
|
627
|
-
removeFromRelationsCore(entity);
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
function removeFromRelationsCore(entity) {
|
|
632
|
-
entity.entityType.navigationProperties.forEach(function (np) {
|
|
633
|
-
let inverseNp = np.inverse;
|
|
634
|
-
let npValue = entity.getProperty(np.name);
|
|
635
|
-
if (np.isScalar) {
|
|
636
|
-
if (npValue) {
|
|
637
|
-
if (inverseNp) {
|
|
638
|
-
if (inverseNp.isScalar) {
|
|
639
|
-
npValue.setProperty(inverseNp.name, null);
|
|
640
|
-
}
|
|
641
|
-
else {
|
|
642
|
-
let collection = npValue.getProperty(inverseNp.name);
|
|
643
|
-
if (collection.length) {
|
|
644
|
-
core.arrayRemoveItem(collection, entity);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
entity.setProperty(np.name, null);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
else {
|
|
652
|
-
if (inverseNp != null) {
|
|
653
|
-
// npValue is a live list so we need to copy it first.
|
|
654
|
-
npValue.slice(0).forEach((v) => {
|
|
655
|
-
if (inverseNp.isScalar) {
|
|
656
|
-
v.setProperty(inverseNp.name, null);
|
|
657
|
-
}
|
|
658
|
-
else {
|
|
659
|
-
// TODO: many to many - not yet handled.
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
// now clear it.
|
|
664
|
-
npValue.length = 0;
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
// note entityAspect only - ( no complex aspect allowed on the call).
|
|
669
|
-
function validate(entityAspect, validator, value, context) {
|
|
670
|
-
let ve = validator.validate(value, context);
|
|
671
|
-
if (ve) {
|
|
672
|
-
entityAspect._addValidationError(ve);
|
|
673
|
-
return false;
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
let key = ValidationError.getKey(validator, context ? context.propertyName : null);
|
|
677
|
-
entityAspect._removeValidationError(key);
|
|
678
|
-
return true;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
// coIndex is only used where target is a complex object that is part of an array of complex objects
|
|
682
|
-
// in which case ctIndex is the index of the target within the array.
|
|
683
|
-
function validateTarget(target, coIndex) {
|
|
684
|
-
let ok = true;
|
|
685
|
-
let stype = target.entityType || target.complexType;
|
|
686
|
-
let aspect = target.entityAspect || target.complexAspect;
|
|
687
|
-
let entityAspect = target.entityAspect || target.complexAspect.getEntityAspect();
|
|
688
|
-
let context = { entity: entityAspect.entity };
|
|
689
|
-
if (coIndex !== undefined) {
|
|
690
|
-
context.index = coIndex;
|
|
691
|
-
}
|
|
692
|
-
stype.getProperties().forEach(function (p) {
|
|
693
|
-
let value = target.getProperty(p.name);
|
|
694
|
-
let validators = p.getAllValidators();
|
|
695
|
-
if (validators.length > 0) {
|
|
696
|
-
context.property = p;
|
|
697
|
-
context.propertyName = aspect.getPropertyPath(p.name);
|
|
698
|
-
ok = entityAspect._validateProperty(value, context) && ok;
|
|
699
|
-
}
|
|
700
|
-
if (p.isComplexProperty) {
|
|
701
|
-
if (p.isScalar) {
|
|
702
|
-
ok = validateTarget(value) && ok;
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
ok = value.reduce(function (pv, cv, ix) {
|
|
706
|
-
return validateTarget(cv, ix) && pv;
|
|
707
|
-
}, ok);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
// then target level
|
|
712
|
-
stype.getAllValidators().forEach(function (validator) {
|
|
713
|
-
ok = validate(entityAspect, validator, target) && ok;
|
|
714
|
-
});
|
|
715
|
-
return ok;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
An ComplexAspect instance is associated with every complex object instance and is accessed via the complex object's 'complexAspect' property.
|
|
719
|
-
|
|
720
|
-
The ComplexAspect itself provides properties to determine the parent object, parent property and original values for the complex object.
|
|
721
|
-
|
|
722
|
-
A ComplexAspect will almost never need to be constructed directly. You will usually get an ComplexAspect by accessing
|
|
723
|
-
an entities 'complexAspect' property. This property will be automatically attached when an complex object is created as part of an
|
|
724
|
-
entity via either a query, import or EntityManager.createEntity call.
|
|
725
|
-
> // assume address is a complex property on the 'Customer' type
|
|
726
|
-
> var aspect = aCustomer.address.complexAspect;
|
|
727
|
-
> // aCustomer === aspect.parent;
|
|
728
|
-
**/
|
|
729
|
-
export class ComplexAspect {
|
|
730
|
-
/** You will rarely, if ever, create a ComplexAspect directly. */
|
|
731
|
-
constructor(complexObject, parent, parentProperty) {
|
|
732
|
-
if (!complexObject) {
|
|
733
|
-
throw new Error("The ComplexAspect ctor requires an entity as its only argument.");
|
|
734
|
-
}
|
|
735
|
-
if (complexObject.complexAspect) {
|
|
736
|
-
return complexObject.complexAspect;
|
|
737
|
-
}
|
|
738
|
-
// if called without new
|
|
739
|
-
if (!(this instanceof ComplexAspect)) {
|
|
740
|
-
return new ComplexAspect(complexObject, parent, parentProperty);
|
|
741
|
-
}
|
|
742
|
-
// entityType should already be on the entity from 'watch'
|
|
743
|
-
this.complexObject = complexObject;
|
|
744
|
-
complexObject.complexAspect = this;
|
|
745
|
-
// TODO: keep public or not?
|
|
746
|
-
this.originalValues = {};
|
|
747
|
-
// if a standalone complexObject
|
|
748
|
-
if (parent != null) {
|
|
749
|
-
this.parent = parent;
|
|
750
|
-
this.parentProperty = parentProperty;
|
|
751
|
-
}
|
|
752
|
-
let complexType = complexObject.complexType;
|
|
753
|
-
if (!complexType) {
|
|
754
|
-
let typeName = complexObject.prototype._$typeName;
|
|
755
|
-
if (!typeName) {
|
|
756
|
-
throw new Error("This entity is not registered as a valid ComplexType");
|
|
757
|
-
}
|
|
758
|
-
else {
|
|
759
|
-
throw new Error("Metadata for this complexType has not yet been resolved: " + typeName);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
let complexCtor = complexType.getCtor();
|
|
763
|
-
config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(complexObject, complexCtor.prototype);
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
Returns the EntityAspect for the top level entity that contains this complex object.
|
|
767
|
-
**/
|
|
768
|
-
getEntityAspect() {
|
|
769
|
-
let parent = this.parent;
|
|
770
|
-
if (!parent)
|
|
771
|
-
return new EntityAspect();
|
|
772
|
-
let entityAspect = parent.entityAspect;
|
|
773
|
-
while (parent && !entityAspect) {
|
|
774
|
-
parent = parent.complexAspect && parent.complexAspect.parent;
|
|
775
|
-
entityAspect = parent && parent.entityAspect;
|
|
776
|
-
}
|
|
777
|
-
return entityAspect || new EntityAspect();
|
|
778
|
-
}
|
|
779
|
-
/** @hidden @internal */
|
|
780
|
-
// TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
|
|
781
|
-
getPropertyPath(propName) {
|
|
782
|
-
let parent = this.parent;
|
|
783
|
-
if (!parent)
|
|
784
|
-
return null;
|
|
785
|
-
let aspect = parent.complexAspect || parent.entityAspect;
|
|
786
|
-
return aspect.getPropertyPath(this.parentProperty.name + "." + propName);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
function clearOriginalValues(target) {
|
|
790
|
-
let aspect = target.entityAspect || target.complexAspect;
|
|
791
|
-
aspect.originalValues = {};
|
|
792
|
-
let stype = target.entityType || target.complexType;
|
|
793
|
-
stype.complexProperties.forEach(function (cp) {
|
|
794
|
-
let cos = target.getProperty(cp.name);
|
|
795
|
-
if (cp.isScalar) {
|
|
796
|
-
clearOriginalValues(cos);
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
cos._acceptChanges();
|
|
800
|
-
cos.forEach(clearOriginalValues);
|
|
801
|
-
}
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWFzcGVjdC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2JyZWV6ZS1jbGllbnQvIiwic291cmNlcyI6WyJzcmMvZW50aXR5LWFzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDbEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFdBQVcsRUFBRyxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsVUFBVSxFQUFpRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDeEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBeUM3Qzs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFzRnZCLHdCQUF3QjtJQUN4QixZQUFZLE1BQWU7UUFFekIsd0JBQXdCO1FBQ3hCLHlDQUF5QztRQUN6QyxxQ0FBcUM7UUFDckMsSUFBSTtRQXlLTjs7Ozs7O1dBTUc7UUFDSCxpQkFBWSxHQUFHO1lBQ2IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUM7UUFHRjs7Ozs7O1dBTUc7UUFDSCxnQkFBVyxHQUFHO1lBQ1osT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUM7UUFFRjs7Ozs7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O0lBRUQseUJBQXlCO0lBQ3pCLG1HQUFtRztJQUNuRyxlQUFlLENBQUMsUUFBZ0I7UUFDOUIsSUFBSSxNQUFNLEdBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM5QixJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3pCLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxhQUFhLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQztRQUN6RCxPQUFPLE1BQU0sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGNBQWUsQ0FBQyxJQUFJLEdBQUcsR0FBRyxHQUFHLFFBQVEsQ0FBQyxDQUFDO0lBQzVFLENBQUM7Q0FFRjtBQUVELFNBQVMsbUJBQW1CLENBQUMsTUFBVztJQUN0QyxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsWUFBWSxJQUFJLE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDekQsTUFBTSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7SUFDM0IsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDO0lBQ3BELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFPO1FBQy9DLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtZQUNmLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQzFCO2FBQU07WUFDTCxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDckIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ2xDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29yZSB9IGZyb20gJy4vY29yZSc7XHJcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4vY29uZmlnJztcclxuaW1wb3J0IHsgQnJlZXplRXZlbnQgfSBmcm9tICcuL2V2ZW50JztcclxuaW1wb3J0IHsgYXNzZXJ0UGFyYW0gfSBmcm9tICcuL2Fzc2VydC1wYXJhbSc7XHJcbmltcG9ydCB7IEVudGl0eVN0YXRlICB9IGZyb20gJy4vZW50aXR5LXN0YXRlJztcclxuaW1wb3J0IHsgRW50aXR5QWN0aW9uIH0gZnJvbSAnLi9lbnRpdHktYWN0aW9uJztcclxuaW1wb3J0IHsgRW50aXR5VHlwZSwgQ29tcGxleFR5cGUsIERhdGFQcm9wZXJ0eSwgTmF2aWdhdGlvblByb3BlcnR5LCBFbnRpdHlQcm9wZXJ0eSB9IGZyb20gJy4vZW50aXR5LW1ldGFkYXRhJztcclxuaW1wb3J0IHsgRW50aXR5S2V5IH0gZnJvbSAnLi9lbnRpdHkta2V5JztcclxuaW1wb3J0IHsgRW50aXR5R3JvdXAgfSBmcm9tICcuL2VudGl0eS1ncm91cCc7XHJcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIsIFF1ZXJ5UmVzdWx0LCBRdWVyeUVycm9yQ2FsbGJhY2ssIFF1ZXJ5U3VjY2Vzc0NhbGxiYWNrIH0gZnJvbSAnLi9lbnRpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IFZhbGlkYXRvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi92YWxpZGF0ZSc7XHJcbmltcG9ydCB7IEVudGl0eVF1ZXJ5IH0gZnJvbSAnLi9lbnRpdHktcXVlcnknO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBFbnRpdHkge1xyXG4gIGVudGl0eUFzcGVjdDogRW50aXR5QXNwZWN0O1xyXG4gIGVudGl0eVR5cGU6IEVudGl0eVR5cGU7XHJcbiAgLyoqIEdldCB0aGUgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZSAqL1xyXG4gIGdldFByb3BlcnR5Pyhwcm9wOiBzdHJpbmcpOiBhbnk7XHJcbiAgLyoqIFNldCB0aGUgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZSAqL1xyXG4gIHNldFByb3BlcnR5Pyhwcm9wOiBhbnksIHZhbHVlOiBhbnkpOiB2b2lkO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RvdHlwZT86IHsgXyR0eXBlTmFtZTogc3RyaW5nIH07XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgXyRlbnRpdHlUeXBlPzogRW50aXR5VHlwZTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21wbGV4T2JqZWN0IHtcclxuICBjb21wbGV4QXNwZWN0OiBDb21wbGV4QXNwZWN0O1xyXG4gIGNvbXBsZXhUeXBlOiBDb21wbGV4VHlwZTtcclxuICBnZXRQcm9wZXJ0eT8ocHJvcDogc3RyaW5nKTogYW55O1xyXG4gIHNldFByb3BlcnR5Pyhwcm9wOiBhbnksIHZhbHVlOiBhbnkpOiB2b2lkO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RvdHlwZT86IHsgXyR0eXBlTmFtZTogc3RyaW5nIH07XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFN0cnVjdHVyYWxPYmplY3QgPSBFbnRpdHkgfCBDb21wbGV4T2JqZWN0O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQcm9wZXJ0eUNoYW5nZWRFdmVudEFyZ3Mge1xyXG4gIGVudGl0eTogRW50aXR5O1xyXG4gIHByb3BlcnR5TmFtZTogc3RyaW5nIHwgbnVsbDtcclxuICBwYXJlbnQ/OiBTdHJ1Y3R1cmFsT2JqZWN0O1xyXG4gIHByb3BlcnR5PzogRW50aXR5UHJvcGVydHk7XHJcbiAgb2xkVmFsdWU/OiBhbnk7XHJcbiAgbmV3VmFsdWU/OiBhbnk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvbkVycm9yc0NoYW5nZWRFdmVudEFyZ3Mge1xyXG4gIGVudGl0eTogRW50aXR5O1xyXG4gIGFkZGVkOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxuICByZW1vdmVkOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxufVxyXG5cclxuLyoqXHJcbkFuIEVudGl0eUFzcGVjdCBpbnN0YW5jZSBpcyBhc3NvY2lhdGVkIHdpdGggZXZlcnkgYXR0YWNoZWQgZW50aXR5IGFuZCBpcyBhY2Nlc3NlZCB2aWEgdGhlIGVudGl0eSdzICdlbnRpdHlBc3BlY3QnIHByb3BlcnR5LlxyXG5cclxuVGhlIEVudGl0eUFzcGVjdCBpdHNlbGYgcHJvdmlkZXMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgYW5kIG1vZGlmeSB0aGUgRW50aXR5U3RhdGUgb2YgdGhlIGVudGl0eSBhbmQgaGFzIG1ldGhvZHNcclxudGhhdCBwcm92aWRlIGEgdmFyaWV0eSBvZiBzZXJ2aWNlcyBpbmNsdWRpbmcgdmFsaWRhdGlvbiBhbmQgY2hhbmdlIHRyYWNraW5nLlxyXG5cclxuQW4gRW50aXR5QXNwZWN0IHdpbGwgYWxtb3N0IG5ldmVyIG5lZWQgdG8gYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuIFlvdSB3aWxsIHVzdWFsbHkgZ2V0IGFuIEVudGl0eUFzcGVjdCBieSBhY2Nlc3NpbmdcclxuYW4gZW50aXRpZXMgJ2VudGl0eUFzcGVjdCcgcHJvcGVydHkuICBUaGlzIHByb3BlcnR5IHdpbGwgYmUgYXV0b21hdGljYWxseSBhdHRhY2hlZCB3aGVuIGFuIGVudGl0eSBpcyBjcmVhdGVkIHZpYSBlaXRoZXJcclxuYSBxdWVyeSwgaW1wb3J0IG9yIFtbRW50aXR5TWFuYWdlci5jcmVhdGVFbnRpdHldXSBjYWxsLlxyXG4+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4+ICAgICAgdmFyIGFzcGVjdCA9IG9yZGVyLmVudGl0eUFzcGVjdDtcclxuPiAgICAgIHZhciBjdXJyZW50U3RhdGUgPSBhc3BlY3QuZW50aXR5U3RhdGU7XHJcblxyXG4qKi9cclxuZXhwb3J0IGNsYXNzIEVudGl0eUFzcGVjdCB7XHJcbiAgLyoqIFRoZSBFbnRpdHkgdGhhdCB0aGlzIGFzcGVjdCBpcyBhc3NvY2lhdGVkIHdpdGguIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGVudGl0eT86IEVudGl0eTtcclxuICAvKiogVGhlIFtbRW50aXR5TWFuYWdlcl1dIHRoYXQgY29udGFpbnMgdGhpcyBlbnRpdHkuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZW50aXR5TWFuYWdlcj86IEVudGl0eU1hbmFnZXI7XHJcbiAgLyoqICBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGVudGl0eUdyb3VwPzogRW50aXR5R3JvdXA7XHJcbiAgLyoqIFRoZSBbW0VudGl0eVN0YXRlXV0gb2YgdGhpcyBlbnRpdHkuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZW50aXR5U3RhdGU6IEVudGl0eVN0YXRlO1xyXG4gIC8qKiAgIFdoZXRoZXIgdGhpcyBlbnRpdHkgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgc2F2ZWQuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc0JlaW5nU2F2ZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSAnb3JpZ2luYWwgdmFsdWVzJyBvZiB0aGlzIGVudGl0eSB3aGVyZSB0aGV5IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGUgJ2N1cnJlbnQgdmFsdWVzJy5cclxuICBUaGlzIGlzIGEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCB0aGUgdmFsdWUgaXMgdGhlICdvcmlnaW5hbCB2YWx1ZScgb2YgdGhlIHByb3BlcnR5LiAqL1xyXG4gIG9yaWdpbmFsVmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG4gIC8qKiAgV2hldGhlciB0aGlzIGVudGl0eSBoYXMgYW55IHZhbGlkYXRpb24gZXJyb3JzLiBfX1JlYWQgT25seV9fICovXHJcbiAgaGFzVmFsaWRhdGlvbkVycm9yczogYm9vbGVhbjtcclxuICAvKiogV2hldGhlciB0aGlzIGVudGl0eSBoYXMgYSB0ZW1wb3JhcnkgW1tFbnRpdHlLZXldXS4gKi9cclxuICBoYXNUZW1wS2V5OiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIHRoaXMgZW50aXR5IHdhcyBjcmVhdGVkIGJ5IGJlaW5nIGxvYWRlZCBmcm9tIHRoZSBkYXRhYmFzZSAqL1xyXG4gIHdhc0xvYWRlZD86IGJvb2xlYW47XHJcbiAgLyoqIEV4dHJhIG1ldGFkYXRhIGFib3V0IHRoaXMgZW50aXR5IHN1Y2ggYXMgdGhlIGVudGl0eSdzIGV0YWcuXHJcbiAgWW91IG1heSBleHRlbmQgdGhpcyBvYmplY3Qgd2l0aCB5b3VyIG93biBtZXRhZGF0YSBpbmZvcm1hdGlvbi5cclxuICBCcmVlemUgKGRlKXNlcmlhbGl6ZXMgdGhpcyBvYmplY3Qgd2hlbiBpbXBvcnRpbmcvZXhwb3J0aW5nIHRoZSBlbnRpdHkuICoqL1xyXG4gIGV4dHJhTWV0YWRhdGE/OiBhbnk7XHJcbiAgLyoqXHJcbiAgQSBbW0JyZWV6ZUV2ZW50XV0gdGhhdCBmaXJlcyB3aGVuZXZlciBhbnkgb2YgdGhlIHZhbGlkYXRpb24gZXJyb3JzIG9uIHRoaXMgZW50aXR5IGNoYW5nZS5cclxuICBOb3RlIHRoYXQgdGhpcyBtaWdodCBiZSB0aGUgcmVtb3ZhbCBvZiBhbiBlcnJvciB3aGVuIHNvbWUgZGF0YSBvbiB0aGUgZW50aXR5IGlzIGZpeGVkLlxyXG4gIEBldmVudEFyZ3MgLSBcclxuICAgIC0gZW50aXR5IC0gVGhlIGVudGl0eSBvbiB3aGljaCB0aGUgdmFsaWRhdGlvbiBlcnJvcnMgYXJlIGJlaW5nIGFkZGVkIG9yIHJlbW92ZWQuXHJcbiAgICAtIGFkZGVkIC0gQW4gYXJyYXkgY29udGFpbmluZyBhbnkgbmV3bHkgYWRkZWQgW1tWYWxpZGF0aW9uRXJyb3JdXXNcclxuICAgIC0gcmVtb3ZlZCAtIEFuIGFycmF5IGNvbnRhaW5pbmcgYW55IG5ld2x5IHJlbW92ZWQgW1tWYWxpZGF0aW9uRXJyb3JdXXMuIFRoaXMgaXMgdGhvc2VcclxuICAgICAgZXJyb3JzIHRoYXQgaGF2ZSBiZWVuICdmaXhlZCcuXHJcblxyXG4+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkLnN1YnNjcmliZShcclxuPiAgICAgIGZ1bmN0aW9uICh2YWxpZGF0aW9uQ2hhbmdlQXJncykge1xyXG4+ICAgICAgICAgIC8vIHRoaXMgY29kZSB3aWxsIGJlIGV4ZWN1dGVkIGFueXRpbWUgYSBwcm9wZXJ0eSB2YWx1ZSBjaGFuZ2VzIG9uIHRoZSAnb3JkZXInIGVudGl0eS5cclxuPiAgICAgICAgICB2YXIgZW50aXR5ID09IHZhbGlkYXRpb25DaGFuZ2VBcmdzLmVudGl0eTsgLy8gTm90ZTogZW50aXR5ID09PSBvcmRlclxyXG4+ICAgICAgICAgIHZhciBlcnJvcnNBZGRlZCA9IHZhbGlkYXRpb25DaGFuZ2VBcmdzLmFkZGVkO1xyXG4+ICAgICAgICAgIHZhciBlcnJvcnNDbGVhcmVkID0gdmFsaWRhdGlvbkNoYW5nZUFyZ3MucmVtb3ZlZDtcclxuPiAgICAgIH0pO1xyXG4gIEBldmVudFxyXG4gICoqL1xyXG4gIHZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkOiBCcmVlemVFdmVudDxWYWxpZGF0aW9uRXJyb3JzQ2hhbmdlZEV2ZW50QXJncz47XHJcbiAgLyoqXHJcbiAgQSBbW0JyZWV6ZUV2ZW50XV0gdGhhdCBmaXJlcyB3aGVuZXZlciBhIHZhbHVlIG9mIG9uZSBvZiB0aGlzIGVudGl0eSdzIHByb3BlcnRpZXMgY2hhbmdlLlxyXG4gIEBldmVudEFyZ3MgLVxyXG4gICAgLSBlbnRpdHkgLSBUaGUgZW50aXR5IHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLlxyXG4gICAgLSBwcm9wZXJ0eSAtIFRoZSBbW0RhdGFQcm9wZXJ0eV1dIHRoYXQgY2hhbmdlZC5cclxuICAgIC0gcHJvcGVydHlOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRoYXQgY2hhbmdlZC4gVGhpcyB2YWx1ZSB3aWxsIGJlICdudWxsJyBmb3Igb3BlcmF0aW9ucyB0aGF0IHJlcGxhY2UgdGhlIGVudGlyZSBlbnRpdHkuICBUaGlzIGluY2x1ZGVzXHJcbiAgICAgIHF1ZXJpZXMsIGltcG9ydHMgYW5kIHNhdmVzIHRoYXQgcmVxdWlyZSBhIG1lcmdlLiBUaGUgcmVtYWluaW5nIHBhcmFtZXRlcnMgd2lsbCBub3QgZXhpc3QgaW4gdGhpcyBjYXNlIGVpdGhlci4gVGhpcyB3aWxsIGFjdHVhbGx5IGJlIGEgXCJwcm9wZXJ0eSBwYXRoXCJcclxuICAgICAgZm9yIGFueSBwcm9wZXJ0aWVzIG9mIGEgY29tcGxleCB0eXBlLlxyXG4gICAgLSBvbGRWYWx1ZSAtIFRoZSBvbGQgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSBiZWZvcmUgdGhlIGNoYW5nZS5cclxuICAgIC0gbmV3VmFsdWUgLSBUaGUgbmV3IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgYWZ0ZXIgdGhlIGNoYW5nZS5cclxuICAgIC0gcGFyZW50IC0gVGhlIGltbWVkaWF0ZSBwYXJlbnQgb2JqZWN0IGZvciB0aGUgY2hhbmdlZCBwcm9wZXJ0eS4gIFRoaXMgd2lsbCBiZSBhIENvbXBsZXhUeXBlIGluc3RhbmNlIGFzIG9wcG9zZWQgdG8gYW4gRW50aXR5IFxyXG4gICAgICBmb3IgYW55IGNvbXBsZXggdHlwZSBvciBuZXN0ZWQgY29tcGxleCB0eXBlIHByb3BlcnRpZXMuXHJcblxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5wcm9wZXJ0eUNoYW5nZWQuc3Vic2NyaWJlKFxyXG4gID4gICAgICBmdW5jdGlvbiAocHJvcGVydHlDaGFuZ2VkQXJncykge1xyXG4gID4gICAgICAgICAgLy8gdGhpcyBjb2RlIHdpbGwgYmUgZXhlY3V0ZWQgYW55dGltZSBhIHByb3BlcnR5IHZhbHVlIGNoYW5nZXMgb24gdGhlICdvcmRlcicgZW50aXR5LlxyXG4gID4gICAgICAgICAgdmFyIGVudGl0eSA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MuZW50aXR5OyAvLyBOb3RlOiBlbnRpdHkgPT09IG9yZGVyXHJcbiAgPiAgICAgICAgICB2YXIgcHJvcGVydHlOYW1lQ2hhbmdlZCA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MucHJvcGVydHlOYW1lO1xyXG4gID4gICAgICAgICAgdmFyIG9sZFZhbHVlID0gcHJvcGVydHlDaGFuZ2VkQXJncy5vbGRWYWx1ZTtcclxuICA+ICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MubmV3VmFsdWU7XHJcbiAgPiAgICAgIH0pO1xyXG4gIEBldmVudFxyXG4gICoqL1xyXG4gIHByb3BlcnR5Q2hhbmdlZDogQnJlZXplRXZlbnQ8UHJvcGVydHlDaGFuZ2VkRXZlbnRBcmdzPjtcclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3ZhbGlkYXRpb25FcnJvcnM6IHsgW2luZGV4OiBzdHJpbmddOiBWYWxpZGF0aW9uRXJyb3IgfTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQ6IGFueTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfZW50aXR5S2V5OiBFbnRpdHlLZXk7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2xvYWRlZE5wczogYW55W107XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2luaXRpYWxpemVkPzogYm9vbGVhbjtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfaW5Qcm9jZXNzOiBhbnlbXTsgLy8gdXNlZCBpbiBkZWZhdWx0UHJvcGVydHlJbnRlcmNlcHRvciBmb3IgdGVtcCBzdG9yYWdlLlxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pblByb2Nlc3NFbnRpdHk/OiBFbnRpdHk7IC8vIHVzZWQgaW4gRW50aXR5TWFuYWdlclxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHN0YXRpYyBfbnVsbEluc3RhbmNlID0gbmV3IEVudGl0eUFzcGVjdCgpOyAvLyBUT0RPOiBkZXRlcm1pbmUgaWYgdGhpcyB3b3Jrc1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGNvbnN0cnVjdG9yKGVudGl0eT86IEVudGl0eSkge1xyXG5cclxuICAgIC8vIGlmIGNhbGxlZCB3aXRob3V0IG5ld1xyXG4gICAgLy8gaWYgKCEodGhpcyBpbnN0YW5jZW9mIEVudGl0eUFzcGVjdCkpIHtcclxuICAgIC8vICAgcmV0dXJuIG5ldyBFbnRpdHlBc3BlY3QoZW50aXR5KTtcclxuICAgIC8vIH1cclxuXHJcbiAgICB0aGlzLmVudGl0eSA9IGVudGl0eTtcclxuICAgIC8vIFRPRE86IGtlZXAgcHVibGljIG9yIG5vdD9cclxuICAgIHRoaXMuZW50aXR5R3JvdXAgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eU1hbmFnZXIgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eVN0YXRlID0gRW50aXR5U3RhdGUuRGV0YWNoZWQ7XHJcbiAgICB0aGlzLmlzQmVpbmdTYXZlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG4gICAgdGhpcy5oYXNWYWxpZGF0aW9uRXJyb3JzID0gZmFsc2U7XHJcbiAgICB0aGlzLl92YWxpZGF0aW9uRXJyb3JzID0ge307XHJcblxyXG4gICAgLy8gVW5jb21tZW50IHdoZW4gd2UgaW1wbGVtZW50IGVudGl0eUFzcGVjdC5pc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZCBtZXRob2RcclxuICAgIC8vIHRoaXMuX2xvYWRlZE5hdlByb3BNYXAgPSB7fTtcclxuXHJcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkID0gbmV3IEJyZWV6ZUV2ZW50KFwidmFsaWRhdGlvbkVycm9yc0NoYW5nZWRcIiwgdGhpcyk7XHJcbiAgICB0aGlzLnByb3BlcnR5Q2hhbmdlZCA9IG5ldyBCcmVlemVFdmVudChcInByb3BlcnR5Q2hhbmdlZFwiLCB0aGlzKTtcclxuICAgIC8vIGluIGNhc2UgdGhpcyBpcyB0aGUgTlVMTCBlbnRpdHlBc3BlY3QuIC0gdXNlZCB3aXRoIENvbXBsZXhBc3BlY3RzIHRoYXQgaGF2ZSBubyBwYXJlbnQuXHJcblxyXG4gICAgaWYgKGVudGl0eSAhPSBudWxsKSB7XHJcbiAgICAgIC8vIHJlbW92ZSBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIG9uIHByb3RvdHlwZSBidXQgcGxhY2VkIG9uIGluc3RhbmNlIGJ5IEJhYmVsXHJcbiAgICAgIGlmIChlbnRpdHkuaGFzT3duUHJvcGVydHkoJ2VudGl0eVR5cGUnKSkge1xyXG4gICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihcIkVudGl0eSBpbnN0YW5jZSBoYXMgZW50aXR5VHlwZSBwcm9wZXJ0eTsgc2hvdWxkIG9ubHkgYmUgb24gcHJvdG90eXBlXCIpO1xyXG4gICAgICAgIGRlbGV0ZShlbnRpdHkuZW50aXR5VHlwZSk7XHJcbiAgICAgIH1cclxuICAgICAgZW50aXR5LmVudGl0eUFzcGVjdCA9IHRoaXM7XHJcblxyXG4gICAgICAvLyBlbnRpdHlUeXBlIHNob3VsZCBhbHJlYWR5IGJlIG9uIHRoZSBlbnRpdHkgZnJvbSAnd2F0Y2gnXHJcbiAgICAgIGxldCBlbnRpdHlUeXBlID0gZW50aXR5LmVudGl0eVR5cGUgfHwgZW50aXR5Ll8kZW50aXR5VHlwZTtcclxuICAgICAgaWYgKCFlbnRpdHlUeXBlKSB7XHJcbiAgICAgICAgbGV0IHR5cGVOYW1lID0gZW50aXR5LnByb3RvdHlwZS5fJHR5cGVOYW1lO1xyXG4gICAgICAgIGlmICghdHlwZU5hbWUpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgZW50aXR5IGlzIG5vdCByZWdpc3RlcmVkIGFzIGEgdmFsaWQgRW50aXR5VHlwZVwiKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWV0YWRhdGEgZm9yIHRoaXMgZW50aXR5VHlwZSBoYXMgbm90IHlldCBiZWVuIHJlc29sdmVkOiBcIiArIHR5cGVOYW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgbGV0IGVudGl0eUN0b3IgPSBlbnRpdHlUeXBlLmdldEN0b3IoKTtcclxuICAgICAgY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKS5zdGFydFRyYWNraW5nKGVudGl0eSwgZW50aXR5Q3Rvci5wcm90b3R5cGUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gKi9cclxuICAvLyB0eXBlLWd1YXJkXHJcbiAgc3RhdGljIGlzRW50aXR5KG9iajogU3RydWN0dXJhbE9iamVjdCk6IG9iaiBpcyBFbnRpdHkge1xyXG4gICAgcmV0dXJuIChvYmogYXMgYW55KS5lbnRpdHlBc3BlY3QgIT0gbnVsbDtcclxuICB9XHJcblxyXG4gIC8vIE5vIGxvbmdlciB1c2VkXHJcbiAgLy8gc3RhdGljIGNyZWF0ZUZyb20oZW50aXR5OiBFbnRpdHkpOiBFbnRpdHlBc3BlY3Qge1xyXG4gIC8vICAgaWYgKGVudGl0eSA9PSBudWxsKSB7XHJcbiAgLy8gICAgIHJldHVybiBFbnRpdHlBc3BlY3QuX251bGxJbnN0YW5jZTtcclxuICAvLyAgIH0gZWxzZSBpZiAoZW50aXR5LmVudGl0eUFzcGVjdCkge1xyXG4gIC8vICAgICByZXR1cm4gZW50aXR5LmVudGl0eUFzcGVjdDtcclxuICAvLyAgIH1cclxuICAvLyAgIHJldHVybiBuZXcgRW50aXR5QXNwZWN0KGVudGl0eSk7XHJcbiAgLy8gfVxyXG5cclxuICAvLyBUT0RPOiByZWZhY3RvciB0aGlzIGFuZCB0aGUgaW5zdGFuY2UgZ2V0UHJvcGVydHlWYWx1ZSBtZXRob2QuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgJ3Byb3BlcnR5IHBhdGgnIGZvciBhIHNwZWNpZmllZCBlbnRpdHkuXHJcblxyXG4gIFRoZSBwcm9wZXJ0eVBhdGggY2FuIGJlIGVpdGhlciBhIHN0cmluZyBkZWxpbWl0ZWQgd2l0aCAnLicgb3IgYSBzdHJpbmcgYXJyYXkuICBcclxuICAqKi9cclxuICAvLyB1c2VkIGJ5IEVudGl0eVF1ZXJ5IGFuZCBQcmVkaWNhdGVcclxuICBzdGF0aWMgZ2V0UHJvcGVydHlQYXRoVmFsdWUob2JqOiBFbnRpdHksIHByb3BlcnR5UGF0aDogc3RyaW5nIHwgc3RyaW5nW10pIHtcclxuICAgIGxldCBwcm9wZXJ0aWVzID0gQXJyYXkuaXNBcnJheShwcm9wZXJ0eVBhdGgpID8gcHJvcGVydHlQYXRoIDogcHJvcGVydHlQYXRoLnNwbGl0KFwiLlwiKTtcclxuICAgIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICByZXR1cm4gb2JqLmdldFByb3BlcnR5KHByb3BlcnR5UGF0aCBhcyBzdHJpbmcpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IG5leHRWYWx1ZSA9IG9iajtcclxuICAgICAgLy8gaGFjayB1c2Ugb2Ygc29tZSB0byBwZXJmb3JtIG1hcEZpcnN0IG9wZXJhdGlvbi5cclxuICAgICAgcHJvcGVydGllcy5zb21lKChwcm9wKSA9PiB7XHJcbiAgICAgICAgbmV4dFZhbHVlID0gbmV4dFZhbHVlLmdldFByb3BlcnR5KHByb3ApO1xyXG4gICAgICAgIHJldHVybiBuZXh0VmFsdWUgPT0gbnVsbDtcclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybiBuZXh0VmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBbW0VudGl0eUtleV1dIGZvciB0aGlzIEVudGl0eS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgZW50aXR5S2V5ID0gb3JkZXIuZW50aXR5QXNwZWN0LmdldEtleSgpO1xyXG4gIEBwYXJhbSBmb3JjZVJlZnJlc2ggLSAoYm9vbGVhbj1mYWxzZSkgRm9yY2VzIHRoZSByZWNhbGN1bGF0aW9uIG9mIHRoZSBrZXkuICBUaGlzIHNob3VsZCBub3JtYWxseSBiZSB1bm5lY2Vzc2FyeS5cclxuICBAcmV0dXJuIFRoZSBbW0VudGl0eUtleV1dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eS5cclxuICAqKi9cclxuICBnZXRLZXkoZm9yY2VSZWZyZXNoOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGZvcmNlUmVmcmVzaCA9IGFzc2VydFBhcmFtKGZvcmNlUmVmcmVzaCwgXCJmb3JjZVJlZnJlc2hcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLmNoZWNrKGZhbHNlKTtcclxuICAgIGlmIChmb3JjZVJlZnJlc2ggfHwgIXRoaXMuX2VudGl0eUtleSkge1xyXG4gICAgICBsZXQgZW50aXR5VHlwZSA9IHRoaXMuZW50aXR5IS5lbnRpdHlUeXBlO1xyXG4gICAgICBsZXQga2V5UHJvcHMgPSBlbnRpdHlUeXBlLmtleVByb3BlcnRpZXM7XHJcbiAgICAgIGxldCB2YWx1ZXMgPSBrZXlQcm9wcy5tYXAoZnVuY3Rpb24gKHApIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbnRpdHkuZ2V0UHJvcGVydHkocC5uYW1lKTtcclxuICAgICAgfSwgdGhpcyk7XHJcbiAgICAgIHRoaXMuX2VudGl0eUtleSA9IG5ldyBFbnRpdHlLZXkoZW50aXR5VHlwZSwgdmFsdWVzKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLl9lbnRpdHlLZXk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBlbnRpdHkgdG8gYW4gW1tFbnRpdHlTdGF0ZV1dIG9mICdVbmNoYW5nZWQnIGJ5IGNvbW1pdHRpbmcgYWxsIGNoYW5nZXMgbWFkZSBzaW5jZSB0aGUgZW50aXR5IHdhcyBsYXN0IHF1ZXJpZWRcclxuICBoYWQgJ2FjY2VwdENoYW5nZXMnIGNhbGxlZCBvbiBpdC5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3QuYWNjZXB0Q2hhbmdlcygpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYW4gJ1VuY2hhbmdlZCcgc3RhdGUgd2l0aCBhbnkgY2hhbmdlcyBjb21taXR0ZWQuXHJcbiAgKiovXHJcbiAgYWNjZXB0Q2hhbmdlcygpIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHkpIHJldHVybjtcclxuICAgIHRoaXMuX2NoZWNrT3BlcmF0aW9uKFwiYWNjZXB0Q2hhbmdlc1wiKTtcclxuICAgIGxldCBlbSA9IHRoaXMuZW50aXR5TWFuYWdlciE7XHJcbiAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZS5pc0RlbGV0ZWQoKSkge1xyXG4gICAgICBlbS5kZXRhY2hFbnRpdHkodGhpcy5lbnRpdHkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZXRVbmNoYW5nZWQoKTtcclxuICAgIH1cclxuICAgIGVtLmVudGl0eUNoYW5nZWQucHVibGlzaCh7IGVudGl0eUFjdGlvbjogRW50aXR5QWN0aW9uLkFjY2VwdENoYW5nZXMsIGVudGl0eTogdGhpcy5lbnRpdHkgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBlbnRpdHkgdG8gYW4gW1tFbnRpdHlTdGF0ZV1dIG9mICdVbmNoYW5nZWQnIGJ5IHJlamVjdGluZyBhbGwgY2hhbmdlcyBtYWRlIHRvIGl0IHNpbmNlIHRoZSBlbnRpdHkgd2FzIGxhc3QgcXVlcmllZFxyXG4gIGhhZCAncmVqZWN0Q2hhbmdlcycgY2FsbGVkIG9uIGl0LlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5yZWplY3RDaGFuZ2VzKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhbiAnVW5jaGFuZ2VkJyBzdGF0ZSB3aXRoIGFueSBjaGFuZ2VzIHJlamVjdGVkLlxyXG4gICoqL1xyXG4gIHJlamVjdENoYW5nZXMoKSB7XHJcbiAgICB0aGlzLl9jaGVja09wZXJhdGlvbihcInJlamVjdENoYW5nZXNcIik7XHJcbiAgICBsZXQgZW50aXR5ID0gdGhpcy5lbnRpdHkhO1xyXG4gICAgbGV0IGVudGl0eU1hbmFnZXIgPSB0aGlzLmVudGl0eU1hbmFnZXIhO1xyXG4gICAgLy8gd2UgZG8gbm90IHdhbnQgUHJvcGVydHlDaGFuZ2Ugb3IgRW50aXR5Q2hhbmdlIGV2ZW50cyB0byBvY2N1ciBoZXJlXHJcbiAgICBjb3JlLnVzaW5nKGVudGl0eU1hbmFnZXIsIFwiaXNSZWplY3RpbmdDaGFuZ2VzXCIsIHRydWUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmVqZWN0Q2hhbmdlc0NvcmUoZW50aXR5KTtcclxuICAgIH0pO1xyXG4gICAgaWYgKHRoaXMuZW50aXR5U3RhdGUuaXNBZGRlZCgpKSB7XHJcbiAgICAgIC8vIG5leHQgbGluZSBpcyBuZWVkZWQgYmVjYXVzZSB0aGUgZm9sbG93aW5nIGxpbmUgd2lsbCBjYXVzZSB0aGlzLmVudGl0eU1hbmFnZXIgLT4gbnVsbDtcclxuICAgICAgZW50aXR5TWFuYWdlci5kZXRhY2hFbnRpdHkoZW50aXR5KTtcclxuICAgICAgLy8gbmVlZCB0byB0ZWxsIGVtIHRoYXQgYW4gZW50aXR5IHRoYXQgbmVlZGVkIHRvIGJlIHNhdmVkIG5vIGxvbmdlciBkb2VzLlxyXG4gICAgICBlbnRpdHlNYW5hZ2VyLl9ub3RpZnlTdGF0ZUNoYW5nZShlbnRpdHksIGZhbHNlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICh0aGlzLmVudGl0eVN0YXRlLmlzRGVsZXRlZCgpKSB7XHJcbiAgICAgICAgZW50aXR5TWFuYWdlci5fbGlua1JlbGF0ZWRFbnRpdGllcyhlbnRpdHkpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuc2V0VW5jaGFuZ2VkKCk7XHJcbiAgICAgIC8vIHByb3BlcnR5Q2hhbmdlZCBwcm9wZXJ0eU5hbWUgaXMgbm90IHNwZWNpZmllZCBiZWNhdXNlIG1vcmUgdGhhbiBvbmUgcHJvcGVydHkgbWF5IGhhdmUgY2hhbmdlZC5cclxuICAgICAgdGhpcy5wcm9wZXJ0eUNoYW5nZWQucHVibGlzaCh7IGVudGl0eTogZW50aXR5LCBwcm9wZXJ0eU5hbWU6IG51bGwgfSk7XHJcbiAgICAgIGVudGl0eU1hbmFnZXIuZW50aXR5Q2hhbmdlZC5wdWJsaXNoKHsgZW50aXR5QWN0aW9uOiBFbnRpdHlBY3Rpb24uUmVqZWN0Q2hhbmdlcywgZW50aXR5OiBlbnRpdHkgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gVE9ETzogcmVuYW1lIC0gYW5kIHVzZSAnXyc7IHVzZWQgb24gYm90aCBFbnRpdHlBc3BlY3QgYW5kIENvbXBsZXhBc3BlY3QgZm9yIHBvbHltb3JwaGljIHJlYXNvbnMuXHJcbiAgZ2V0UHJvcGVydHlQYXRoKHByb3BOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiBwcm9wTmFtZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byBhbiBFbnRpdHlTdGF0ZSBvZiAnQWRkZWQnLiAgVGhpcyBpcyBOT1QgdGhlIGVxdWl2YWxlbnQgb2YgY2FsbGluZyBbW0VudGl0eU1hbmFnZXIuYWRkRW50aXR5XV1cclxuICBiZWNhdXNlIG5vIGtleSBnZW5lcmF0aW9uIHdpbGwgb2NjdXIgZm9yIGF1dG9nZW5lcmF0ZWQga2V5cyBhcyBhIHJlc3VsdCBvZiB0aGlzIG9wZXJhdGlvbi4gQXMgYSByZXN1bHQgdGhpcyBvcGVyYXRpb24gY2FuIGJlIHByb2JsZW1hdGljXHJcbiAgdW5sZXNzIHlvdSBhcmUgY2VydGFpbiB0aGF0IHRoZSBlbnRpdHkgYmVpbmcgbWFya2VkICdBZGRlZCcgZG9lcyBub3QgYWxyZWFkeSBleGlzdCBpbiB0aGUgZGF0YWJhc2UgYW5kIGRvZXMgbm90IGhhdmUgYW4gYXV0b2dlbmVyYXRlZCBrZXkuXHJcbiAgVGhlIHNhbWUgb3BlcmF0aW9uIGNhbiBiZSBwZXJmb3JtZWQgYnkgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZV1dLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXRBZGRlZCgpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYW4gJ0FkZGVkJyBzdGF0ZS5cclxuICAqKi9cclxuICBzZXRBZGRlZCgpIHtcclxuICAgIHJldHVybiB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLkFkZGVkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byBhbiBFbnRpdHlTdGF0ZSBvZiAnVW5jaGFuZ2VkJy4gIFRoaXMgaXMgYWxzbyB0aGUgZXF1aXZhbGVudCBvZiBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LmFjY2VwdENoYW5nZXNdXS5cclxuICBUaGUgc2FtZSBvcGVyYXRpb24gY2FuIGJlIHBlcmZvcm1lZCBieSBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlXV0uXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldFVuY2hhbmdlZCgpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYW4gJ1VuY2hhbmdlZCcgc3RhdGUgd2l0aCBhbnkgY2hhbmdlcyBjb21taXR0ZWQuXHJcbiAgKiovXHJcbiAgc2V0VW5jaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuVW5jaGFuZ2VkKTtcclxuICB9O1xyXG5cclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIGFuIEVudGl0eVN0YXRlIG9mICdNb2RpZmllZCcuICBUaGlzIGNhbiBhbHNvIGJlIGFjaGlldmVkIGJ5IGNoYW5naW5nIHRoZSB2YWx1ZSBvZiBhbnkgcHJvcGVydHkgb24gYW4gJ1VuY2hhbmdlZCcgZW50aXR5LlxyXG4gIFRoZSBzYW1lIG9wZXJhdGlvbiBjYW4gYmUgcGVyZm9ybWVkIGJ5IGNhbGxpbmcgW1tFbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGVdXS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0TW9kaWZpZWQoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGEgJ01vZGlmaWVkJyBzdGF0ZS5cclxuICAqKi9cclxuICBzZXRNb2RpZmllZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLk1vZGlmaWVkKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gYW4gRW50aXR5U3RhdGUgb2YgJ0RlbGV0ZWQnLiAgVGhpcyBib3RoIG1hcmtzIHRoZSBlbnRpdHkgYXMgYmVpbmcgc2NoZWR1bGVkIGZvciBkZWxldGlvbiBkdXJpbmcgdGhlIG5leHQgJ1NhdmUnIGNhbGxcclxuICBidXQgYWxzbyByZW1vdmVzIHRoZSBlbnRpdHkgZnJvbSBhbGwgb2YgaXRzIHJlbGF0ZWQgZW50aXRpZXMuICBJZiB0aGUgY3VycmVudCBlbnRpdHlTdGF0ZSBpcyAnQWRkZWQnLCB0aGVuIGBzZXREZWxldGVkKClgIHdpbGwgbWFyayBpdCAnRGV0YWNoZWQnXHJcbiAgVGhlIHNhbWUgb3BlcmF0aW9uIGNhbiBiZSBwZXJmb3JtZWQgYnkgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZV1dLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXREZWxldGVkKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhICdEZWxldGVkJyBzdGF0ZSBhbmQgaXQgd2lsbCBubyBsb25nZXIgaGF2ZSBhbnkgJ3JlbGF0ZWQnIGVudGl0aWVzLlxyXG4gICoqL1xyXG4gIHNldERlbGV0ZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5EZWxldGVkKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gYW4gRW50aXR5U3RhdGUgb2YgJ0RldGFjaGVkJy4gIFRoaXMgcmVtb3ZlcyB0aGUgZW50aXR5IGZyb20gYWxsIG9mIGl0cyByZWxhdGVkIGVudGl0aWVzLCBidXQgZG9lcyBOT1QgY2hhbmdlIHRoZSBFbnRpdHlTdGF0ZSBvZiBhbnkgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgVGhlIHNhbWUgb3BlcmF0aW9uIGNhbiBiZSBwZXJmb3JtZWQgYnkgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZV1dLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXREZXRhY2hlZCgpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYSAnRGV0YWNoZWQnIHN0YXRlIGFuZCBpdCB3aWxsIG5vIGxvbmdlciBoYXZlIGFueSAncmVsYXRlZCcgZW50aXRpZXMuXHJcbiAgKiovXHJcbiAgc2V0RGV0YWNoZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5EZXRhY2hlZCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIHRoZSBzcGVjaWZpZWQgRW50aXR5U3RhdGUuIFNlZSBhbHNvICdzZXRVbmNoYW5nZWQnLCAnc2V0TW9kaWZpZWQnLCAnc2V0RGV0YWNoZWQnLCBldGMuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLlVuY2hhbmdlZCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhICdVbmNoYW5nZWQnIHN0YXRlLlxyXG4gICoqL1xyXG4gIHNldEVudGl0eVN0YXRlKGVudGl0eVN0YXRlOiBFbnRpdHlTdGF0ZSkge1xyXG4gICAgaWYgKHRoaXMuZW50aXR5U3RhdGUgPT09IGVudGl0eVN0YXRlKSByZXR1cm4gZmFsc2U7XHJcbiAgICB0aGlzLl9jaGVja09wZXJhdGlvbihcInNldEVudGl0eVN0YXRlXCIpO1xyXG4gICAgaWYgKHRoaXMuZW50aXR5U3RhdGUuaXNEZXRhY2hlZCgpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIllvdSBjYW5ub3Qgc2V0IHRoZSAnZW50aXR5U3RhdGUnIG9mIGFuIGVudGl0eSB3aGVuIGl0IGlzIGRldGFjaGVkIC0gZXhjZXB0IGJ5IGZpcnN0IGF0dGFjaGluZyBpdCB0byBhbiBFbnRpdHlNYW5hZ2VyXCIpO1xyXG4gICAgfVxyXG4gICAgbGV0IGVudGl0eSA9IHRoaXMuZW50aXR5ITtcclxuICAgIGxldCBlbSA9IHRoaXMuZW50aXR5TWFuYWdlciE7XHJcbiAgICBsZXQgbmVlZHNTYXZlID0gdHJ1ZTtcclxuICAgIGlmIChlbnRpdHlTdGF0ZSA9PT0gRW50aXR5U3RhdGUuVW5jaGFuZ2VkKSB7XHJcbiAgICAgIGNsZWFyT3JpZ2luYWxWYWx1ZXMoZW50aXR5KTtcclxuICAgICAgZGVsZXRlIHRoaXMuaGFzVGVtcEtleTtcclxuICAgICAgbmVlZHNTYXZlID0gZmFsc2U7XHJcbiAgICB9IGVsc2UgaWYgKGVudGl0eVN0YXRlID09PSBFbnRpdHlTdGF0ZS5BZGRlZCkge1xyXG4gICAgICBjbGVhck9yaWdpbmFsVmFsdWVzKGVudGl0eSk7XHJcbiAgICAgIC8vIFRPRE86IG1vcmUgdG8gZG8gaGVyZS4uLiBsaWtlIHJlZ2VuZXJhdGluZyBrZXkgPz8/XHJcbiAgICB9IGVsc2UgaWYgKGVudGl0eVN0YXRlID09PSBFbnRpdHlTdGF0ZS5EZWxldGVkKSB7XHJcbiAgICAgIGlmICh0aGlzLmVudGl0eVN0YXRlLmlzQWRkZWQoKSkge1xyXG4gICAgICAgIC8vIHR1cm4gaXQgaW50byBhIGRldGFjaCBhbmQgZXhpdCBlYXJseVxyXG4gICAgICAgIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuRGV0YWNoZWQpO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIFRPRE86IHRoaW5rIGFib3V0IGNhc2NhZGUgZGVsZXRlc1xyXG4gICAgICAgIC8vIGVudGl0eVN0YXRlIG5lZWRzIHRvIGJlIHNldCBpdCBlYXJseSBpbiB0aGlzIG9uZSBjYXNlIHRvIGluc3VyZSB0aGF0IGZrJ3MgYXJlIG5vdCBjbGVhcmVkLlxyXG4gICAgICAgIHRoaXMuZW50aXR5U3RhdGUgPSBFbnRpdHlTdGF0ZS5EZWxldGVkO1xyXG4gICAgICAgIHJlbW92ZUZyb21SZWxhdGlvbnMoZW50aXR5LCBFbnRpdHlTdGF0ZS5EZWxldGVkKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChlbnRpdHlTdGF0ZSA9PT0gRW50aXR5U3RhdGUuTW9kaWZpZWQpIHtcclxuICAgICAgLy8gbm90aGluZyBleHRyYSBuZWVkZWRcclxuICAgIH0gZWxzZSBpZiAoZW50aXR5U3RhdGUgPT09IEVudGl0eVN0YXRlLkRldGFjaGVkKSB7XHJcbiAgICAgIGxldCBncm91cCA9IHRoaXMuZW50aXR5R3JvdXA7XHJcbiAgICAgIC8vIG5vIGdyb3VwID09PSBhbHJlYWR5IGRldGFjaGVkLlxyXG4gICAgICBpZiAoIWdyb3VwKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgIGdyb3VwLmRldGFjaEVudGl0eShlbnRpdHkpO1xyXG4gICAgICAvLyBuZWVkcyB0byBvY2N1ciBlYXJseSBoZXJlIC0gc28gdGhpcyBJUyBkZWxpYmVyYXRlbHkgcmVkdW5kZW50IHdpdGggdGhlIHNhbWUgY29kZSBsYXRlciBpbiB0aGlzIG1ldGhvZC5cclxuICAgICAgdGhpcy5lbnRpdHlTdGF0ZSA9IGVudGl0eVN0YXRlO1xyXG4gICAgICByZW1vdmVGcm9tUmVsYXRpb25zKGVudGl0eSwgRW50aXR5U3RhdGUuRGV0YWNoZWQpO1xyXG4gICAgICB0aGlzLl9kZXRhY2goKTtcclxuICAgICAgZW0uZW50aXR5Q2hhbmdlZC5wdWJsaXNoKHsgZW50aXR5QWN0aW9uOiBFbnRpdHlBY3Rpb24uRGV0YWNoLCBlbnRpdHk6IGVudGl0eSB9KTtcclxuICAgICAgbmVlZHNTYXZlID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgICB0aGlzLmVudGl0eVN0YXRlID0gZW50aXR5U3RhdGU7XHJcbiAgICBlbS5fbm90aWZ5U3RhdGVDaGFuZ2UoZW50aXR5LCBuZWVkc1NhdmUpO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBsb2FkTmF2aWdhdGlvblByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eTogc3RyaW5nLCBjYWxsYmFjaz86IFF1ZXJ5U3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrPzogUXVlcnlFcnJvckNhbGxiYWNrKTogUHJvbWlzZTxRdWVyeVJlc3VsdD47XHJcbiAgbG9hZE5hdmlnYXRpb25Qcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSwgY2FsbGJhY2s/OiBRdWVyeVN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaz86IFF1ZXJ5RXJyb3JDYWxsYmFjayk6IFByb21pc2U8UXVlcnlSZXN1bHQ+O1xyXG4gIC8qKlxyXG4gIFBlcmZvcm1zIGEgcXVlcnkgZm9yIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBbW05hdmlnYXRpb25Qcm9wZXJ0eV1dLiBfX0FzeW5jX19cclxuICA+ICAgICAgZW1wLmVudGl0eUFzcGVjdC5sb2FkTmF2aWdhdGlvblByb3BlcnR5KFwiT3JkZXJzXCIpLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcclxuICA+ICAgICAgICAgIHZhciBvcmRlcnMgPSBkYXRhLnJlc3VsdHM7XHJcbiAgPiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICA+ICAgICAgICAgIC8vIGhhbmRsZSBleGNlcHRpb24gaGVyZTtcclxuICA+ICAgICAgfSk7XHJcbiAgQHBhcmFtIG5hdmlnYXRpb25Qcm9wZXJ0eSAtIFRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgdGhlIG5hbWUgb2YgdGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSB0byAnbG9hZCcuXHJcbiAgQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCBvbiBzdWNjZXNzLlxyXG4gIEBwYXJhbSBlcnJvckNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCBvbiBmYWlsdXJlLlxyXG4gIEByZXR1cm4gUHJvbWlzZSB3aXRoIHNoYXBlXHJcbiAgICAtIHJlc3VsdHMge0FycmF5IG9mIEVudGl0eX1cclxuICAgIC0gcXVlcnkge0VudGl0eVF1ZXJ5fSBUaGUgb3JpZ2luYWwgcXVlcnlcclxuICAgIC0gaHR0cFJlc3BvbnNlIHtodHRwUmVzcG9uc2V9IFRoZSBIdHRwUmVzcG9uc2UgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyLlxyXG4gICoqL1xyXG4gIGxvYWROYXZpZ2F0aW9uUHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkgfCBzdHJpbmcsIGNhbGxiYWNrOiBRdWVyeVN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjazogUXVlcnlFcnJvckNhbGxiYWNrKSB7XHJcbiAgICBsZXQgZW50aXR5ID0gdGhpcy5lbnRpdHkhO1xyXG4gICAgbGV0IG5hdlByb3BlcnR5ID0gZW50aXR5LmVudGl0eVR5cGUuX2NoZWNrTmF2UHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5KTtcclxuICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdHlOYXZpZ2F0aW9uKGVudGl0eSwgbmF2UHJvcGVydHkpO1xyXG4gICAgLy8gcmV0dXJuIGVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlci5leGVjdXRlUXVlcnkocXVlcnksIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKTtcclxuICAgIGxldCBwcm9taXNlID0gZW50aXR5LmVudGl0eUFzcGVjdC5lbnRpdHlNYW5hZ2VyIS5leGVjdXRlUXVlcnkocXVlcnkpO1xyXG5cclxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgdGhpcy5fbWFya0FzTG9hZGVkKG5hdlByb3BlcnR5Lm5hbWUpO1xyXG4gICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKGRhdGEpO1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGRhdGEpO1xyXG4gICAgfSwgKGVycm9yKSA9PiB7XHJcbiAgICAgIGlmIChlcnJvckNhbGxiYWNrKSBlcnJvckNhbGxiYWNrKGVycm9yKTtcclxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIE1hcmtzIHRoaXMgbmF2aWdhdGlvblByb3BlcnR5IG9uIHRoaXMgZW50aXR5IGFzIGFscmVhZHkgaGF2aW5nIGJlZW4gbG9hZGVkLlxyXG4gID4gICAgICBlbXAuZW50aXR5QXNwZWN0Lm1hcmtOYXZpZ2F0aW9uUHJvcGVydHlBc0xvYWRlZChcIk9yZGVyc1wiKTtcclxuICBAcGFyYW0gbmF2aWdhdGlvblByb3BlcnR5IC0gVGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSBvciBuYW1lIG9mIE5hdmlnYXRpb25Qcm9wZXJ0eSB0byAnbG9hZCcuXHJcbiAgKiovXHJcbiAgbWFya05hdmlnYXRpb25Qcm9wZXJ0eUFzTG9hZGVkKG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5KSByZXR1cm47XHJcbiAgICBsZXQgbmF2UHJvcGVydHkgPSB0aGlzLmVudGl0eS5lbnRpdHlUeXBlLl9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICB0aGlzLl9tYXJrQXNMb2FkZWQobmF2UHJvcGVydHkubmFtZSk7XHJcbiAgfVxyXG5cclxuICBpc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZChuYXZpZ2F0aW9uUHJvcGVydHk6IHN0cmluZyk6IGJvb2xlYW47XHJcbiAgaXNOYXZpZ2F0aW9uUHJvcGVydHlMb2FkZWQobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkpOiBib29sZWFuO1xyXG4gIC8qKlxyXG4gIERldGVybWluZXMgd2hldGhlciBhIG5hdmlnYXRpb25Qcm9wZXJ0eSBvbiB0aGlzIGVudGl0eSBoYXMgYWxyZWFkeSBiZWVuIGxvYWRlZC5cclxuXHJcbiAgQSBuYXZpZ2F0aW9uIHByb3BlcnR5IGlzIGNvbnNpZGVyZWQgbG9hZGVkIHdoZW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgdGhyZWUgY29uZGl0aW9ucyBhcHBsaWVzOlxyXG5cclxuICAgIDEuIEl0IHdhcyBmZXRjaGVkIGZyb20gdGhlIGJhY2tlbmQgc2VydmVyLlxyXG4gICAgICAgIDxici8+ICAgVGhpcyBjYW4gYmUgdGhlIHJlc3VsdCBvZiBhbiBleHBhbmQgcXVlcnkgb3IgYSBjYWxsIHRvIHRoZSBbW0VudGl0eUFzcGVjdC5sb2FkTmF2aWdhdGlvblByb3BlcnR5XV0gbWV0aG9kLlxyXG4gICAgICAgIDxici8+ICAgTm90ZSB0aGF0IGV2ZW4gaWYgdGhlIGZldGNoIHJldHVybnMgbm90aGluZyB0aGUgcHJvcGVydHkgaXMgc3RpbGwgbWFya2VkIGFzIGxvYWRlZCBpbiB0aGlzIGNhc2UuXHJcbiAgICAxLiBUaGUgcHJvcGVydHkgaXMgc2NhbGFyIGFuZCBoYXMgYmVlbiBzZXQgdG8gYSBub25udWxsIHZhbHVlLlxyXG4gICAgMS4gVGhlIFtbRW50aXR5QXNwZWN0Lm1hcmtOYXZpZ2F0aW9uUHJvcGVydHlBc0xvYWRlZF1dIHdhcyBjYWxsZWQuXHJcbiAgXHJcbiAgPiAgICAgdmFyIHdhc0xvYWRlZCA9IGVtcC5lbnRpdHlBc3BlY3QuaXNOYXZpZ2F0aW9uUHJvcGVydHlMb2FkZWQoXCJPcmRlcnNcIik7XHJcbiAgQHBhcmFtIG5hdmlnYXRpb25Qcm9wZXJ0eSAtIFRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgbmFtZSBvZiBOYXZpZ2F0aW9uUHJvcGVydHkgdG8gJ2xvYWQnLlxyXG4gICoqL1xyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5TG9hZGVkKG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5KSByZXR1cm47XHJcbiAgICBsZXQgbmF2UHJvcGVydHkgPSB0aGlzLmVudGl0eS5lbnRpdHlUeXBlLl9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICBpZiAobmF2UHJvcGVydHkuaXNTY2FsYXIgJiYgdGhpcy5lbnRpdHkuZ2V0UHJvcGVydHkobmF2UHJvcGVydHkubmFtZSkgIT0gbnVsbCkge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLl9sb2FkZWROcHMgJiYgdGhpcy5fbG9hZGVkTnBzLmluZGV4T2YobmF2UHJvcGVydHkubmFtZSkgPj0gMDtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9tYXJrQXNMb2FkZWQobmF2UHJvcE5hbWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5fbG9hZGVkTnBzID0gdGhpcy5fbG9hZGVkTnBzIHx8IFtdO1xyXG4gICAgY29yZS5hcnJheUFkZEl0ZW1VbmlxdWUodGhpcy5fbG9hZGVkTnBzLCBuYXZQcm9wTmFtZSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgUGVyZm9ybXMgdmFsaWRhdGlvbiBvbiB0aGUgZW50aXR5LCBhbnkgZXJyb3JzIGVuY291bnRlcmVkIGR1cmluZyB0aGUgdmFsaWRhdGlvbiBhcmUgYXZhaWxhYmxlIHZpYSB0aGVcclxuICBbW0VudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzXV0gbWV0aG9kLiBWYWxpZGF0aW5nIGFuIGVudGl0eSBtZWFucyBleGVjdXRpbmdcclxuICBhbGwgb2YgdGhlIHZhbGlkYXRvcnMgb24gYm90aCB0aGUgZW50aXR5IGl0c2VsZiBhcyB3ZWxsIGFzIHRob3NlIG9uIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIGlzT2sgPSBvcmRlci5lbnRpdHlBc3BlY3QudmFsaWRhdGVFbnRpdHkoKTtcclxuICA+ICAgICAgLy8gaXNPayB3aWxsIGJlICd0cnVlJyBpZiB0aGVyZSBhcmUgbm8gZXJyb3JzIG9uIHRoZSBlbnRpdHkuXHJcbiAgPiAgICAgIGlmICghaXNPaykge1xyXG4gID4gICAgICAgICAgdmFyIGVycm9ycyA9IG9yZGVyLmVudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzKCk7XHJcbiAgPiAgICAgIH1cclxuICBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudGl0eSBwYXNzZWQgdmFsaWRhdGlvbi5cclxuICAqKi9cclxuICB2YWxpZGF0ZUVudGl0eSgpIHtcclxuICAgIGxldCBvayA9IHRydWU7XHJcbiAgICB0aGlzLl9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaChmdW5jdGlvbiAodGhhdDogYW55KSB7XHJcbiAgICAgIG9rID0gdmFsaWRhdGVUYXJnZXQodGhhdC5lbnRpdHkpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gb2s7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZVByb3BlcnR5KHByb3BlcnR5OiBzdHJpbmcsIGNvbnRleHQ/OiBhbnkpOiBib29sZWFuO1xyXG4gIHZhbGlkYXRlUHJvcGVydHkocHJvcGVydHk6IERhdGFQcm9wZXJ0eSwgY29udGV4dD86IGFueSk6IGJvb2xlYW47XHJcbiAgdmFsaWRhdGVQcm9wZXJ0eShwcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5LCBjb250ZXh0PzogYW55KTogYm9vbGVhbjtcclxuICAvKipcclxuICBQZXJmb3JtcyB2YWxpZGF0aW9uIG9uIGEgc3BlY2lmaWMgcHJvcGVydHkgb2YgdGhpcyBlbnRpdHksIGFueSBlcnJvcnMgZW5jb3VudGVyZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIGFyZSBhdmFpbGFibGUgdmlhIHRoZVxyXG4gIFtbRW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnNdXSBtZXRob2QuIFZhbGlkYXRpbmcgYSBwcm9wZXJ0eSBtZWFucyBleGVjdXRpbmdcclxuICBhbGwgb2YgdGhlIHZhbGlkYXRvcnMgb24gdGhlIHNwZWNpZmllZCBwcm9wZXJ0eS4gIFRoaXMgY2FsbCBpcyBhbHNvIG1hZGUgYXV0b21hdGljYWxseSBhbnl0aW1lIGEgcHJvcGVydHlcclxuICBvZiBhbiBlbnRpdHkgaXMgY2hhbmdlZC5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgaXNPayA9IG9yZGVyLmVudGl0eUFzcGVjdC52YWxpZGF0ZVByb3BlcnR5KFwiT3JkZXJcIik7XHJcblxyXG4gIG9yXHJcbiAgPiAgICAgIHZhciBvcmRlckRhdGVQcm9wZXJ0eSA9IG9yZGVyLmVudGl0eVR5cGUuZ2V0UHJvcGVydHkoXCJPcmRlckRhdGVcIik7XHJcbiAgPiAgICAgIHZhciBpc09rID0gb3JkZXIuZW50aXR5QXNwZWN0LnZhbGlkYXRlUHJvcGVydHkoT3JkZXJEYXRlUHJvcGVydHkpO1xyXG4gIEBwYXJhbSBwcm9wZXJ0eSAtIFRoZSBbW0RhdGFQcm9wZXJ0eV1dIG9yIFtbTmF2aWdhdGlvblByb3BlcnR5XV0gdG8gdmFsaWRhdGUgb3IgYSBzdHJpbmcgXHJcbiAgd2l0aCB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgb3IgYSBwcm9wZXJ0eSBwYXRoIHdpdGggdGhlIHBhdGggdG8gYSBwcm9wZXJ0eSBvZiBhIGNvbXBsZXggb2JqZWN0LlxyXG4gIEBwYXJhbSBjb250ZXh0IC0gIEEgY29udGV4dCBvYmplY3QgdXNlZCB0byBwYXNzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdG8gZWFjaCBbW1ZhbGlkYXRvcl1dLlxyXG4gIEByZXR1cm4gV2hldGhlciB0aGUgZW50aXR5IHBhc3NlZCB2YWxpZGF0aW9uLlxyXG4gICoqL1xyXG4gIHZhbGlkYXRlUHJvcGVydHkocHJvcGVydHk6IEVudGl0eVByb3BlcnR5IHwgc3RyaW5nLCBjb250ZXh0OiBhbnkpIHtcclxuICAgIGxldCB2YWx1ZSA9IHRoaXMuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSk7IC8vIHBlcmZvcm1zIHZhbGlkYXRpb25zXHJcbiAgICBpZiAodmFsdWUgJiYgdmFsdWUuY29tcGxleEFzcGVjdCkge1xyXG4gICAgICByZXR1cm4gdmFsaWRhdGVUYXJnZXQodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY29udGV4dCA9IGNvbnRleHQgfHwge307XHJcbiAgICBjb250ZXh0LmVudGl0eSA9IHRoaXMuZW50aXR5O1xyXG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5ID0gdGhpcy5lbnRpdHkhLmVudGl0eVR5cGUuZ2V0UHJvcGVydHkocHJvcGVydHksIHRydWUpO1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5TmFtZSA9IHByb3BlcnR5O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eSA9IHByb3BlcnR5O1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5TmFtZSA9IHByb3BlcnR5Lm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUHJvcGVydHkodmFsdWUsIGNvbnRleHQpO1xyXG4gIH1cclxuXHJcbiAgZ2V0VmFsaWRhdGlvbkVycm9ycygpOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxuICBnZXRWYWxpZGF0aW9uRXJyb3JzKHByb3BlcnR5OiBzdHJpbmcpOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxuICBnZXRWYWxpZGF0aW9uRXJyb3JzKHByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eSk6IFZhbGlkYXRpb25FcnJvcltdO1xyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIHZhbGlkYXRpb24gZXJyb3JzIGFzc29jaWF0ZWQgd2l0aCBlaXRoZXIgdGhlIGVudGlyZSBlbnRpdHkgb3IgYW55IHNwZWNpZmllZCBwcm9wZXJ0eS5cclxuICBcclxuICBUaGlzIG1ldGhvZCBjYW4gcmV0dXJuIGFsbCBvZiB0aGUgZXJyb3JzIGZvciBhbiBFbnRpdHlcclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgdmFsRXJyb3JzID0gb3JkZXIuZW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnMoKTtcclxuXHJcbiAgYXMgd2VsbCBhcyB0aG9zZSBmb3IganVzdCBhIHNwZWNpZmljIHByb3BlcnR5LlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciBvcmRlckRhdGVFcnJvcnMgPSBvcmRlci5lbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9ycyhcIk9yZGVyRGF0ZVwiKTtcclxuXHJcbiAgd2hpY2ggY2FuIGFsc28gYmUgZXhwcmVzc2VkIGFzXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIG9yZGVyRGF0ZVByb3BlcnR5ID0gb3JkZXIuZW50aXR5VHlwZS5nZXRQcm9wZXJ0eShcIk9yZGVyRGF0ZVwiKTtcclxuICA+ICAgICAgdmFyIG9yZGVyRGF0ZUVycm9ycyA9IG9yZGVyLmVudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzKG9yZGVyRGF0ZVByb3BlcnR5KTtcclxuICBAcGFyYW0gcHJvcGVydHkgLSBUaGUgcHJvcGVydHkgZm9yIHdoaWNoIHZhbGlkYXRpb24gZXJyb3JzIHNob3VsZCBiZSByZXRyaWV2ZWQuXHJcbiAgSWYgb21pdHRlZCwgYWxsIG9mIHRoZSB2YWxpZGF0aW9uIGVycm9ycyBmb3IgdGhpcyBlbnRpdHkgd2lsbCBiZSByZXR1cm5lZC5cclxuICBAcmV0dXJuIEEgYXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvcnMuXHJcbiAgKiovXHJcbiAgZ2V0VmFsaWRhdGlvbkVycm9ycyhwcm9wZXJ0eT86IERhdGFQcm9wZXJ0eSB8IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocHJvcGVydHksIFwicHJvcGVydHlcIikuaXNPcHRpb25hbCgpLmlzRW50aXR5UHJvcGVydHkoKS5vcigpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGxldCByZXN1bHQgPSBjb3JlLmdldE93blByb3BlcnR5VmFsdWVzKHRoaXMuX3ZhbGlkYXRpb25FcnJvcnMpO1xyXG4gICAgaWYgKHByb3BlcnR5KSB7XHJcbiAgICAgIGxldCBwcm9wZXJ0eU5hbWUgPSB0eXBlb2YgKHByb3BlcnR5KSA9PT0gJ3N0cmluZycgPyBwcm9wZXJ0eSA6IHByb3BlcnR5Lm5hbWU7XHJcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5maWx0ZXIoZnVuY3Rpb24gKHZlOiBWYWxpZGF0aW9uRXJyb3IpIHtcclxuICAgICAgICByZXR1cm4gdmUucHJvcGVydHkgJiYgKHZlLnByb3BlcnR5Lm5hbWUgPT09IHByb3BlcnR5TmFtZSB8fCAocHJvcGVydHlOYW1lLmluZGV4T2YoXCIuXCIpICE9PSAtMSAmJiB2ZS5wcm9wZXJ0eU5hbWUgPT09IHByb3BlcnR5TmFtZSkpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBBZGRzIGEgdmFsaWRhdGlvbiBlcnJvci5cclxuICAqKi9cclxuICBhZGRWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbkVycm9yOiBWYWxpZGF0aW9uRXJyb3IpIHtcclxuICAgIGFzc2VydFBhcmFtKHZhbGlkYXRpb25FcnJvciwgXCJ2YWxpZGF0aW9uRXJyb3JcIikuaXNJbnN0YW5jZU9mKFZhbGlkYXRpb25FcnJvcikuY2hlY2soKTtcclxuICAgIHRoaXMuX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKGZ1bmN0aW9uICh0aGF0OiBhbnkpIHtcclxuICAgICAgdGhhdC5fYWRkVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25FcnJvcik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJlbW92ZVZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uRXJyb3I6IFZhbGlkYXRpb25FcnJvcik6IHZvaWQ7XHJcbiAgcmVtb3ZlVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25LZXk6IHN0cmluZyk6IHZvaWQ7XHJcbiAgLyoqXHJcbiAgUmVtb3ZlcyBhIHZhbGlkYXRpb24gZXJyb3IuXHJcbiAgQHBhcmFtIHZhbGlkYXRpb25FcnJvck9yS2V5IC0gRWl0aGVyIGEgVmFsaWRhdGlvbkVycm9yIG9yIGEgVmFsaWRhdGlvbkVycm9yICdrZXknIHZhbHVlXHJcbiAgKiovXHJcbiAgcmVtb3ZlVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25FcnJvck9yS2V5OiBWYWxpZGF0aW9uRXJyb3IgfCBzdHJpbmcpIHtcclxuICAgIGFzc2VydFBhcmFtKHZhbGlkYXRpb25FcnJvck9yS2V5LCBcInZhbGlkYXRpb25FcnJvck9yS2V5XCIpLmlzU3RyaW5nKCkub3IoKS5pc0luc3RhbmNlT2YoVmFsaWRhdGlvbkVycm9yKS5vcigpLmlzSW5zdGFuY2VPZihWYWxpZGF0b3IpLmNoZWNrKCk7XHJcblxyXG4gICAgbGV0IGtleSA9ICh0eXBlb2YgKHZhbGlkYXRpb25FcnJvck9yS2V5KSA9PT0gXCJzdHJpbmdcIikgPyB2YWxpZGF0aW9uRXJyb3JPcktleSA6IHZhbGlkYXRpb25FcnJvck9yS2V5LmtleTtcclxuICAgIHRoaXMuX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKGZ1bmN0aW9uICh0aGF0OiBhbnkpIHtcclxuICAgICAgdGhhdC5fcmVtb3ZlVmFsaWRhdGlvbkVycm9yKGtleSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJlbW92ZXMgYWxsIG9mIHRoZSB2YWxpZGF0aW9uIGVycm9ycyBmb3IgYSBzcGVjaWZpZWQgZW50aXR5XHJcbiAgKiovXHJcbiAgY2xlYXJWYWxpZGF0aW9uRXJyb3JzKCkge1xyXG4gICAgdGhpcy5fcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2goZnVuY3Rpb24gKHRoYXQ6IGFueSkge1xyXG4gICAgICBjb3JlLm9iamVjdEZvckVhY2godGhhdC5fdmFsaWRhdGlvbkVycm9ycywgZnVuY3Rpb24gKGtleTogc3RyaW5nLCB2YWxFcnJvcjogVmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgaWYgKHZhbEVycm9yKSB7XHJcbiAgICAgICAgICBkZWxldGUgdGhhdC5fdmFsaWRhdGlvbkVycm9yc1trZXldO1xyXG4gICAgICAgICAgdGhhdC5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQucmVtb3ZlZC5wdXNoKHZhbEVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGF0Lmhhc1ZhbGlkYXRpb25FcnJvcnMgPSAhY29yZS5pc0VtcHR5KHRoYXQuX3ZhbGlkYXRpb25FcnJvcnMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFuIFtbRW50aXR5S2V5XV0gZm9yIHRoZSBlbnRpdHkgcG9pbnRlZCB0byBieSB0aGUgc3BlY2lmaWVkIHNjYWxhciBOYXZpZ2F0aW9uUHJvcGVydHkuXHJcbiAgVGhpcyBvbmx5IHJldHVybnMgYW4gRW50aXR5S2V5IGlmIHRoZSBjdXJyZW50IGVudGl0eSBpcyBhICdjaGlsZCcgZW50aXR5IGFsb25nIHRoZSBzcGVjaWZpZWQgTmF2aWdhdGlvblByb3BlcnR5LiBcclxuICBpLmUuIGhhcyBhIHNpbmdsZSBwYXJlbnQuXHJcblxyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgW1tOYXZpZ2F0aW9uUHJvcGVydHldXSAoIHBvaW50aW5nIHRvIGEgcGFyZW50KS4gXHJcbiAgQHJldHVybnMgRWl0aGVyIGEgcGFyZW50IEVudGl0eUtleSBpZiB0aGlzIGlzIGEgJ2NoaWxkJyBlbnRpdHkgb3IgbnVsbDsgIFxyXG4gICovXHJcbiAgZ2V0UGFyZW50S2V5KG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5KSByZXR1cm4gbnVsbDtcclxuICAgIC8vIFRPRE86IHJldmlldyB0aGlzIC0gbm90IHN1cmUgYWJvdXQgdGhlIGNvbW1lbnQuXHJcbiAgICAvLyBOYXZpZ2F0aW9uUHJvcGVydHkgZG9lc24ndCB5ZXQgZXhpc3RcclxuICAgIC8vIGFzc2VydFBhcmFtKG5hdmlnYXRpb25Qcm9wZXJ0eSwgXCJuYXZpZ2F0aW9uUHJvcGVydHlcIikuaXNJbnN0YW5jZU9mKE5hdmlnYXRpb25Qcm9wZXJ0eSkuY2hlY2soKTtcclxuICAgIGxldCBma05hbWVzID0gbmF2aWdhdGlvblByb3BlcnR5LmZvcmVpZ25LZXlOYW1lcztcclxuICAgIGlmIChma05hbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XHJcbiAgICBsZXQgdGhhdCA9IHRoaXM7XHJcbiAgICBsZXQgZmtWYWx1ZXMgPSBma05hbWVzLm1hcChmdW5jdGlvbiAoZmtuKSB7XHJcbiAgICAgIHJldHVybiB0aGF0LmVudGl0eSEuZ2V0UHJvcGVydHkoZmtuKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIG5ldyBFbnRpdHlLZXkobmF2aWdhdGlvblByb3BlcnR5LmVudGl0eVR5cGUsIGZrVmFsdWVzKTtcclxuICB9XHJcblxyXG4gIC8vIFRPRE86IHJlZmFjdG9yIHRoaXMgYW5kIHRoZSBzdGF0aWMgZ2V0UHJvcGVydHlQYXRoVmFsdWUuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgRGF0YVByb3BlcnR5IG9yIE5hdmlnYXRpb25Qcm9wZXJ0eSBvciAncHJvcGVydHkgcGF0aCcuICBcclxuICAqKi9cclxuICBnZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5OiBzdHJpbmcgfCBEYXRhUHJvcGVydHkgfCBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICAgIGFzc2VydFBhcmFtKHByb3BlcnR5LCBcInByb3BlcnR5XCIpLmlzU3RyaW5nKCkub3IoKS5pc0VudGl0eVByb3BlcnR5KCkuY2hlY2soKTtcclxuICAgIGxldCB2YWx1ZTogYW55O1xyXG4gICAgaWYgKHR5cGVvZiAocHJvcGVydHkpID09PSAnc3RyaW5nJykge1xyXG4gICAgICBsZXQgcHJvcE5hbWVzID0gcHJvcGVydHkudHJpbSgpLnNwbGl0KFwiLlwiKTtcclxuICAgICAgbGV0IHByb3BOYW1lID0gcHJvcE5hbWVzLnNoaWZ0KCk7XHJcbiAgICAgIHZhbHVlID0gdGhpcy5lbnRpdHk7XHJcbiAgICAgIHZhbHVlID0gdmFsdWUuZ2V0UHJvcGVydHkocHJvcE5hbWUpO1xyXG4gICAgICB3aGlsZSAocHJvcE5hbWVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBwcm9wTmFtZSA9IHByb3BOYW1lcy5zaGlmdCgpO1xyXG4gICAgICAgIHZhbHVlID0gdmFsdWUuZ2V0UHJvcGVydHkocHJvcE5hbWUpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoIShwcm9wZXJ0eS5wYXJlbnRUeXBlIGluc3RhbmNlb2YgRW50aXR5VHlwZSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgdmFsaWRhdGVQcm9wZXJ0eSBtZXRob2QgZG9lcyBub3QgYWNjZXB0IGEgJ3Byb3BlcnR5JyBwYXJhbWV0ZXIgd2hvc2UgcGFyZW50VHlwZSBpcyBhIENvbXBsZXhUeXBlOyBcIiArXHJcbiAgICAgICAgICBcIlBhc3MgYSAncHJvcGVydHkgcGF0aCcgc3RyaW5nIGFzIHRoZSAncHJvcGVydHknIHBhcmFtZXRlciBpbnN0ZWFkIFwiKTtcclxuICAgICAgfVxyXG4gICAgICB2YWx1ZSA9IHRoaXMuZW50aXR5IS5nZXRQcm9wZXJ0eShwcm9wZXJ0eS5uYW1lKTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxuICB9XHJcblxyXG4gIC8vIGludGVybmFsIG1ldGhvZHNcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY2hlY2tPcGVyYXRpb24ob3BlcmF0aW9uTmFtZTogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5pc0JlaW5nU2F2ZWQpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHBlcmZvcm0gYSAnXCIgKyBvcGVyYXRpb25OYW1lICsgXCInIG9uIGFuIGVudGl0eSB0aGF0IGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIHNhdmVkXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gYWxsb3dzIGNoYWluaW5nXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9kZXRhY2goKSB7XHJcbiAgICB0aGlzLmVudGl0eUdyb3VwID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5lbnRpdHlNYW5hZ2VyID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5lbnRpdHlTdGF0ZSA9IEVudGl0eVN0YXRlLkRldGFjaGVkO1xyXG4gICAgdGhpcy5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG4gICAgdGhpcy5fdmFsaWRhdGlvbkVycm9ycyA9IHt9O1xyXG4gICAgdGhpcy5oYXNWYWxpZGF0aW9uRXJyb3JzID0gZmFsc2U7XHJcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkLmNsZWFyKCk7XHJcbiAgICB0aGlzLnByb3BlcnR5Q2hhbmdlZC5jbGVhcigpO1xyXG5cclxuICB9XHJcblxyXG5cclxuICAvLyBjYWxsZWQgZnJvbSBkZWZhdWx0SW50ZXJjZXB0b3IuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3ZhbGlkYXRlUHJvcGVydHkodmFsdWU6IGFueSwgY29udGV4dDogYW55KSB7XHJcbiAgICBsZXQgb2sgPSB0cnVlO1xyXG4gICAgdGhpcy5fcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2goZnVuY3Rpb24gKHRoYXQ6IGFueSkge1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5LmdldEFsbFZhbGlkYXRvcnMoKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWxpZGF0b3I6IFZhbGlkYXRvcikge1xyXG4gICAgICAgIG9rID0gdmFsaWRhdGUodGhhdCwgdmFsaWRhdG9yLCB2YWx1ZSwgY29udGV4dCkgJiYgb2s7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gb2s7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2godmFsaWRhdGlvbkZuOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdCkge1xyXG4gICAgICAvLyBvbmx5IHRvcCBsZXZlbCBwcm9jZXNzVmFsaWRhdGlvbnMgY2FsbCBwdWJsaXNoZXNcclxuICAgICAgdmFsaWRhdGlvbkZuKHRoaXMpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICB0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdCA9IHsgZW50aXR5OiB0aGlzLmVudGl0eSwgYWRkZWQ6IFtdLCByZW1vdmVkOiBbXSB9O1xyXG4gICAgICAgIHZhbGlkYXRpb25Gbih0aGlzKTtcclxuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQuYWRkZWQubGVuZ3RoID4gMCB8fCB0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdC5yZW1vdmVkLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIHRoaXMudmFsaWRhdGlvbkVycm9yc0NoYW5nZWQucHVibGlzaCh0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdCk7XHJcbiAgICAgICAgICAvLyB0aGlzIG1pZ2h0IGJlIGEgZGV0YWNoZWQgZW50aXR5IGhlbmNlIHRoZSBndWFyZCBiZWxvdy5cclxuICAgICAgICAgIHRoaXMuZW50aXR5TWFuYWdlciAmJiB0aGlzLmVudGl0eU1hbmFnZXIudmFsaWRhdGlvbkVycm9yc0NoYW5nZWQucHVibGlzaCh0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdCk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICB0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gVE9ETzogYWRkL3VzZSBhIFZhbGlkYXRpb25FcnJvciB0eXBlXHJcbiAgX2FkZFZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uRXJyb3I6IGFueSkge1xyXG4gICAgdGhpcy5fdmFsaWRhdGlvbkVycm9yc1t2YWxpZGF0aW9uRXJyb3Iua2V5XSA9IHZhbGlkYXRpb25FcnJvcjtcclxuICAgIHRoaXMuaGFzVmFsaWRhdGlvbkVycm9ycyA9IHRydWU7XHJcbiAgICB0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdC5hZGRlZC5wdXNoKHZhbGlkYXRpb25FcnJvcik7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcmVtb3ZlVmFsaWRhdGlvbkVycm9yKGtleTogc3RyaW5nKSB7XHJcbiAgICBsZXQgdmFsRXJyb3IgPSB0aGlzLl92YWxpZGF0aW9uRXJyb3JzW2tleV07XHJcbiAgICBpZiAodmFsRXJyb3IpIHtcclxuICAgICAgZGVsZXRlIHRoaXMuX3ZhbGlkYXRpb25FcnJvcnNba2V5XTtcclxuICAgICAgdGhpcy5oYXNWYWxpZGF0aW9uRXJyb3JzID0gIWNvcmUuaXNFbXB0eSh0aGlzLl92YWxpZGF0aW9uRXJyb3JzKTtcclxuICAgICAgdGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQucmVtb3ZlZC5wdXNoKHZhbEVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG59XHJcblxyXG5CcmVlemVFdmVudC5idWJibGVFdmVudChFbnRpdHlBc3BlY3QucHJvdG90eXBlLCBmdW5jdGlvbiAoKSB7XHJcbiAgcmV0dXJuIHRoaXMuZW50aXR5TWFuYWdlcjtcclxufSk7XHJcblxyXG5mdW5jdGlvbiByZWplY3RDaGFuZ2VzQ29yZSh0YXJnZXQ6IGFueSkge1xyXG4gIGxldCBhc3BlY3QgPSB0YXJnZXQuZW50aXR5QXNwZWN0IHx8IHRhcmdldC5jb21wbGV4QXNwZWN0O1xyXG4gIGxldCBzdHlwZSA9IHRhcmdldC5lbnRpdHlUeXBlIHx8IHRhcmdldC5jb21wbGV4VHlwZTtcclxuICBsZXQgb3JpZ2luYWxWYWx1ZXMgPSBhc3BlY3Qub3JpZ2luYWxWYWx1ZXM7XHJcbiAgZm9yIChsZXQgcHJvcE5hbWUgaW4gb3JpZ2luYWxWYWx1ZXMpIHtcclxuICAgIHRhcmdldC5zZXRQcm9wZXJ0eShwcm9wTmFtZSwgb3JpZ2luYWxWYWx1ZXNbcHJvcE5hbWVdKTtcclxuICB9XHJcbiAgc3R5cGUuY29tcGxleFByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAoY3A6IGFueSkge1xyXG4gICAgbGV0IGNvcyA9IHRhcmdldC5nZXRQcm9wZXJ0eShjcC5uYW1lKTtcclxuICAgIGlmIChjcC5pc1NjYWxhcikge1xyXG4gICAgICByZWplY3RDaGFuZ2VzQ29yZShjb3MpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29zLl9yZWplY3RDaGFuZ2VzKCk7XHJcbiAgICAgIGNvcy5mb3JFYWNoKHJlamVjdENoYW5nZXNDb3JlKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRnJvbVJlbGF0aW9ucyhlbnRpdHk6IEVudGl0eSwgZW50aXR5U3RhdGU6IEVudGl0eVN0YXRlKSB7XHJcbiAgLy8gcmVtb3ZlIHRoaXMgZW50aXR5IGZyb20gYW55IGNvbGxlY3Rpb25zLlxyXG4gIC8vIG1hcmsgdGhlIGVudGl0eSBkZWxldGVkIG9yIGRldGFjaGVkXHJcblxyXG4gIGxldCBpc0RlbGV0ZWQgPSBlbnRpdHlTdGF0ZS5pc0RlbGV0ZWQoKTtcclxuICBpZiAoaXNEZWxldGVkKSB7XHJcbiAgICByZW1vdmVGcm9tUmVsYXRpb25zQ29yZShlbnRpdHkpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBjb3JlLnVzaW5nKGVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlciEsIFwiaXNMb2FkaW5nXCIsIHRydWUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmVtb3ZlRnJvbVJlbGF0aW9uc0NvcmUoZW50aXR5KTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRnJvbVJlbGF0aW9uc0NvcmUoZW50aXR5OiBFbnRpdHkpIHtcclxuICBlbnRpdHkuZW50aXR5VHlwZS5uYXZpZ2F0aW9uUHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChucCkge1xyXG4gICAgbGV0IGludmVyc2VOcCA9IG5wLmludmVyc2U7XHJcbiAgICBsZXQgbnBWYWx1ZSA9IGVudGl0eS5nZXRQcm9wZXJ0eShucC5uYW1lKTtcclxuICAgIGlmIChucC5pc1NjYWxhcikge1xyXG4gICAgICBpZiAobnBWYWx1ZSkge1xyXG4gICAgICAgIGlmIChpbnZlcnNlTnApIHtcclxuICAgICAgICAgIGlmIChpbnZlcnNlTnAuaXNTY2FsYXIpIHtcclxuICAgICAgICAgICAgbnBWYWx1ZS5zZXRQcm9wZXJ0eShpbnZlcnNlTnAubmFtZSwgbnVsbCk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgY29sbGVjdGlvbiA9IG5wVmFsdWUuZ2V0UHJvcGVydHkoaW52ZXJzZU5wLm5hbWUpO1xyXG4gICAgICAgICAgICBpZiAoY29sbGVjdGlvbi5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICBjb3JlLmFycmF5UmVtb3ZlSXRlbShjb2xsZWN0aW9uLCBlbnRpdHkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVudGl0eS5zZXRQcm9wZXJ0eShucC5uYW1lLCBudWxsKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKGludmVyc2VOcCAhPSBudWxsKSB7XHJcbiAgICAgICAgLy8gbnBWYWx1ZSBpcyBhIGxpdmUgbGlzdCBzbyB3ZSBuZWVkIHRvIGNvcHkgaXQgZmlyc3QuXHJcbiAgICAgICAgbnBWYWx1ZS5zbGljZSgwKS5mb3JFYWNoKCh2OiBhbnkpID0+IHtcclxuICAgICAgICAgIGlmIChpbnZlcnNlTnAhLmlzU2NhbGFyKSB7XHJcbiAgICAgICAgICAgIHYuc2V0UHJvcGVydHkoaW52ZXJzZU5wIS5uYW1lLCBudWxsKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRPRE86IG1hbnkgdG8gbWFueSAtIG5vdCB5ZXQgaGFuZGxlZC5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgICAvLyBub3cgY2xlYXIgaXQuXHJcbiAgICAgIG5wVmFsdWUubGVuZ3RoID0gMDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbn1cclxuXHJcbi8vIG5vdGUgZW50aXR5QXNwZWN0IG9ubHkgLSAoIG5vIGNvbXBsZXggYXNwZWN0IGFsbG93ZWQgb24gdGhlIGNhbGwpLlxyXG5mdW5jdGlvbiB2YWxpZGF0ZShlbnRpdHlBc3BlY3Q6IEVudGl0eUFzcGVjdCwgdmFsaWRhdG9yOiBWYWxpZGF0b3IsIHZhbHVlOiBhbnksIGNvbnRleHQ/OiBhbnkpIHtcclxuICBsZXQgdmUgPSB2YWxpZGF0b3IudmFsaWRhdGUodmFsdWUsIGNvbnRleHQpO1xyXG4gIGlmICh2ZSkge1xyXG4gICAgZW50aXR5QXNwZWN0Ll9hZGRWYWxpZGF0aW9uRXJyb3IodmUpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBsZXQga2V5ID0gVmFsaWRhdGlvbkVycm9yLmdldEtleSh2YWxpZGF0b3IsIGNvbnRleHQgPyBjb250ZXh0LnByb3BlcnR5TmFtZSA6IG51bGwpO1xyXG4gICAgZW50aXR5QXNwZWN0Ll9yZW1vdmVWYWxpZGF0aW9uRXJyb3Ioa2V5KTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxufVxyXG5cclxuLy8gY29JbmRleCBpcyBvbmx5IHVzZWQgd2hlcmUgdGFyZ2V0IGlzIGEgY29tcGxleCBvYmplY3QgdGhhdCBpcyBwYXJ0IG9mIGFuIGFycmF5IG9mIGNvbXBsZXggb2JqZWN0c1xyXG4vLyBpbiB3aGljaCBjYXNlIGN0SW5kZXggaXMgdGhlIGluZGV4IG9mIHRoZSB0YXJnZXQgd2l0aGluIHRoZSBhcnJheS5cclxuZnVuY3Rpb24gdmFsaWRhdGVUYXJnZXQodGFyZ2V0OiBhbnksIGNvSW5kZXg/OiBudW1iZXIpIHtcclxuICBsZXQgb2sgPSB0cnVlO1xyXG4gIGxldCBzdHlwZSA9IHRhcmdldC5lbnRpdHlUeXBlIHx8IHRhcmdldC5jb21wbGV4VHlwZTtcclxuICBsZXQgYXNwZWN0ID0gdGFyZ2V0LmVudGl0eUFzcGVjdCB8fCB0YXJnZXQuY29tcGxleEFzcGVjdDtcclxuICBsZXQgZW50aXR5QXNwZWN0ID0gdGFyZ2V0LmVudGl0eUFzcGVjdCB8fCB0YXJnZXQuY29tcGxleEFzcGVjdC5nZXRFbnRpdHlBc3BlY3QoKTtcclxuICBsZXQgY29udGV4dCA9IDxhbnk+eyBlbnRpdHk6IGVudGl0eUFzcGVjdC5lbnRpdHkgfTtcclxuICBpZiAoY29JbmRleCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICBjb250ZXh0LmluZGV4ID0gY29JbmRleDtcclxuICB9XHJcblxyXG4gIHN0eXBlLmdldFByb3BlcnRpZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChwOiBhbnkpIHtcclxuICAgIGxldCB2YWx1ZSA9IHRhcmdldC5nZXRQcm9wZXJ0eShwLm5hbWUpO1xyXG4gICAgbGV0IHZhbGlkYXRvcnMgPSBwLmdldEFsbFZhbGlkYXRvcnMoKTtcclxuICAgIGlmICh2YWxpZGF0b3JzLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eSA9IHA7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHlOYW1lID0gYXNwZWN0LmdldFByb3BlcnR5UGF0aChwLm5hbWUpO1xyXG4gICAgICBvayA9IGVudGl0eUFzcGVjdC5fdmFsaWRhdGVQcm9wZXJ0eSh2YWx1ZSwgY29udGV4dCkgJiYgb2s7XHJcbiAgICB9XHJcbiAgICBpZiAocC5pc0NvbXBsZXhQcm9wZXJ0eSkge1xyXG4gICAgICBpZiAocC5pc1NjYWxhcikge1xyXG4gICAgICAgIG9rID0gdmFsaWRhdGVUYXJnZXQodmFsdWUpICYmIG9rO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9rID0gdmFsdWUucmVkdWNlKGZ1bmN0aW9uIChwdjogYW55LCBjdjogYW55LCBpeDogbnVtYmVyKSB7XHJcbiAgICAgICAgICByZXR1cm4gdmFsaWRhdGVUYXJnZXQoY3YsIGl4KSAmJiBwdjtcclxuICAgICAgICB9LCBvayk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIC8vIHRoZW4gdGFyZ2V0IGxldmVsXHJcbiAgc3R5cGUuZ2V0QWxsVmFsaWRhdG9ycygpLmZvckVhY2goZnVuY3Rpb24gKHZhbGlkYXRvcjogVmFsaWRhdG9yKSB7XHJcbiAgICBvayA9IHZhbGlkYXRlKGVudGl0eUFzcGVjdCwgdmFsaWRhdG9yLCB0YXJnZXQpICYmIG9rO1xyXG4gIH0pO1xyXG4gIHJldHVybiBvaztcclxufVxyXG5cclxuLyoqXHJcbkFuIENvbXBsZXhBc3BlY3QgaW5zdGFuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIGV2ZXJ5IGNvbXBsZXggb2JqZWN0IGluc3RhbmNlIGFuZCBpcyBhY2Nlc3NlZCB2aWEgdGhlIGNvbXBsZXggb2JqZWN0J3MgJ2NvbXBsZXhBc3BlY3QnIHByb3BlcnR5LlxyXG5cclxuVGhlIENvbXBsZXhBc3BlY3QgaXRzZWxmIHByb3ZpZGVzIHByb3BlcnRpZXMgdG8gZGV0ZXJtaW5lIHRoZSBwYXJlbnQgb2JqZWN0LCBwYXJlbnQgcHJvcGVydHkgYW5kIG9yaWdpbmFsIHZhbHVlcyBmb3IgdGhlIGNvbXBsZXggb2JqZWN0LlxyXG5cclxuQSBDb21wbGV4QXNwZWN0IHdpbGwgYWxtb3N0IG5ldmVyIG5lZWQgdG8gYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuIFlvdSB3aWxsIHVzdWFsbHkgZ2V0IGFuIENvbXBsZXhBc3BlY3QgYnkgYWNjZXNzaW5nXHJcbmFuIGVudGl0aWVzICdjb21wbGV4QXNwZWN0JyBwcm9wZXJ0eS4gIFRoaXMgcHJvcGVydHkgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGF0dGFjaGVkIHdoZW4gYW4gY29tcGxleCBvYmplY3QgaXMgY3JlYXRlZCBhcyBwYXJ0IG9mIGFuXHJcbmVudGl0eSB2aWEgZWl0aGVyIGEgcXVlcnksIGltcG9ydCBvciBFbnRpdHlNYW5hZ2VyLmNyZWF0ZUVudGl0eSBjYWxsLlxyXG4+ICAgICAgLy8gYXNzdW1lIGFkZHJlc3MgaXMgYSBjb21wbGV4IHByb3BlcnR5IG9uIHRoZSAnQ3VzdG9tZXInIHR5cGVcclxuPiAgICAgIHZhciBhc3BlY3QgPSBhQ3VzdG9tZXIuYWRkcmVzcy5jb21wbGV4QXNwZWN0O1xyXG4+ICAgICAgLy8gYUN1c3RvbWVyID09PSBhc3BlY3QucGFyZW50O1xyXG4qKi9cclxuZXhwb3J0IGNsYXNzIENvbXBsZXhBc3BlY3Qge1xyXG5cclxuICAvKiogVGhlIGNvbXBsZXggb2JqZWN0IHRoYXQgdGhpcyBhc3BlY3QgaXMgYXNzb2NpYXRlZCB3aXRoLiBfX1JlYWQgT25seV9fICovXHJcbiAgY29tcGxleE9iamVjdDogQ29tcGxleE9iamVjdDtcclxuICAvKiogVGhlICdvcmlnaW5hbCB2YWx1ZXMnIG9mIHRoaXMgY29tcGxleCBvYmplY3Qgd2hlcmUgdGhleSBhcmUgZGlmZmVyZW50IGZyb20gdGhlICdjdXJyZW50IHZhbHVlcycuXHJcbiAgVGhpcyBpcyBhIG1hcCB3aGVyZSB0aGUga2V5IGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgdGhlIHZhbHVlIGlzIHRoZSAnb3JpZ2luYWwgdmFsdWUnIG9mIHRoZSBwcm9wZXJ0eS5cclxuICBfX1JlYWQgT25seV9fICovXHJcbiAgb3JpZ2luYWxWYWx1ZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLyoqIFRoZSBwYXJlbnQgb2JqZWN0IHRoYXQgdG8gd2hpY2ggdGhpcyBhc3BlY3QgYmVsb25nczsgdGhpcyB3aWxsIGVpdGhlciBiZSBhbiBlbnRpdHkgb3IgYW5vdGhlciBjb21wbGV4IG9iamVjdC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHBhcmVudD86IFN0cnVjdHVyYWxPYmplY3Q7XHJcbiAgLyoqIFRoZSBbW0RhdGFQcm9wZXJ0eV1dIG9uIHRoZSAncGFyZW50JyB0aGF0IGNvbnRhaW5zIHRoaXMgY29tcGxleCBvYmplY3QuIF9fUmVhZCBPbmx5X18gKi9cclxuICBwYXJlbnRQcm9wZXJ0eT86IERhdGFQcm9wZXJ0eTtcclxuICBleHRyYU1ldGFkYXRhPzogYW55O1xyXG5cclxuICAvKiogWW91IHdpbGwgcmFyZWx5LCBpZiBldmVyLCBjcmVhdGUgYSBDb21wbGV4QXNwZWN0IGRpcmVjdGx5LiAqL1xyXG4gIGNvbnN0cnVjdG9yKGNvbXBsZXhPYmplY3Q6IENvbXBsZXhPYmplY3QsIHBhcmVudDogU3RydWN0dXJhbE9iamVjdCwgcGFyZW50UHJvcGVydHk6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgaWYgKCFjb21wbGV4T2JqZWN0KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAgQ29tcGxleEFzcGVjdCBjdG9yIHJlcXVpcmVzIGFuIGVudGl0eSBhcyBpdHMgb25seSBhcmd1bWVudC5cIik7XHJcbiAgICB9XHJcbiAgICBpZiAoY29tcGxleE9iamVjdC5jb21wbGV4QXNwZWN0KSB7XHJcbiAgICAgIHJldHVybiBjb21wbGV4T2JqZWN0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgICB9XHJcbiAgICAvLyBpZiBjYWxsZWQgd2l0aG91dCBuZXdcclxuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wbGV4QXNwZWN0KSkge1xyXG4gICAgICByZXR1cm4gbmV3IENvbXBsZXhBc3BlY3QoY29tcGxleE9iamVjdCwgcGFyZW50LCBwYXJlbnRQcm9wZXJ0eSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZW50aXR5VHlwZSBzaG91bGQgYWxyZWFkeSBiZSBvbiB0aGUgZW50aXR5IGZyb20gJ3dhdGNoJ1xyXG4gICAgdGhpcy5jb21wbGV4T2JqZWN0ID0gY29tcGxleE9iamVjdDtcclxuICAgIGNvbXBsZXhPYmplY3QuY29tcGxleEFzcGVjdCA9IHRoaXM7XHJcblxyXG4gICAgLy8gVE9ETzoga2VlcCBwdWJsaWMgb3Igbm90P1xyXG4gICAgdGhpcy5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIC8vIGlmIGEgc3RhbmRhbG9uZSBjb21wbGV4T2JqZWN0XHJcbiAgICBpZiAocGFyZW50ICE9IG51bGwpIHtcclxuICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgICAgIHRoaXMucGFyZW50UHJvcGVydHkgPSBwYXJlbnRQcm9wZXJ0eTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgY29tcGxleFR5cGUgPSBjb21wbGV4T2JqZWN0LmNvbXBsZXhUeXBlO1xyXG4gICAgaWYgKCFjb21wbGV4VHlwZSkge1xyXG4gICAgICBsZXQgdHlwZU5hbWUgPSBjb21wbGV4T2JqZWN0LnByb3RvdHlwZS5fJHR5cGVOYW1lO1xyXG4gICAgICBpZiAoIXR5cGVOYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnRpdHkgaXMgbm90IHJlZ2lzdGVyZWQgYXMgYSB2YWxpZCBDb21wbGV4VHlwZVwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRhZGF0YSBmb3IgdGhpcyBjb21wbGV4VHlwZSBoYXMgbm90IHlldCBiZWVuIHJlc29sdmVkOiBcIiArIHR5cGVOYW1lKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgbGV0IGNvbXBsZXhDdG9yID0gY29tcGxleFR5cGUuZ2V0Q3RvcigpO1xyXG4gICAgY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKS5zdGFydFRyYWNraW5nKGNvbXBsZXhPYmplY3QsIGNvbXBsZXhDdG9yLnByb3RvdHlwZSk7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIEVudGl0eUFzcGVjdCBmb3IgdGhlIHRvcCBsZXZlbCBlbnRpdHkgdGhhdCBjb250YWlucyB0aGlzIGNvbXBsZXggb2JqZWN0LlxyXG4gICoqL1xyXG4gIGdldEVudGl0eUFzcGVjdCgpIHtcclxuICAgIGxldCBwYXJlbnQgPSA8YW55PnRoaXMucGFyZW50O1xyXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBuZXcgRW50aXR5QXNwZWN0KCk7XHJcbiAgICBsZXQgZW50aXR5QXNwZWN0ID0gcGFyZW50LmVudGl0eUFzcGVjdDtcclxuICAgIHdoaWxlIChwYXJlbnQgJiYgIWVudGl0eUFzcGVjdCkge1xyXG4gICAgICBwYXJlbnQgPSBwYXJlbnQuY29tcGxleEFzcGVjdCAmJiBwYXJlbnQuY29tcGxleEFzcGVjdC5wYXJlbnQ7XHJcbiAgICAgIGVudGl0eUFzcGVjdCA9IHBhcmVudCAmJiBwYXJlbnQuZW50aXR5QXNwZWN0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVudGl0eUFzcGVjdCB8fCBuZXcgRW50aXR5QXNwZWN0KCk7XHJcbiAgfVxyXG5cclxuICAvKiogIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gVE9ETzogcmVuYW1lIC0gYW5kIHVzZSAnXyc7IHVzZWQgb24gYm90aCBFbnRpdHlBc3BlY3QgYW5kIENvbXBsZXhBc3BlY3QgZm9yIHBvbHltb3JwaGljIHJlYXNvbnMuXHJcbiAgZ2V0UHJvcGVydHlQYXRoKHByb3BOYW1lOiBzdHJpbmcpIHtcclxuICAgIGxldCBwYXJlbnQgPSA8YW55PnRoaXMucGFyZW50O1xyXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBudWxsO1xyXG4gICAgbGV0IGFzcGVjdCA9IHBhcmVudC5jb21wbGV4QXNwZWN0IHx8IHBhcmVudC5lbnRpdHlBc3BlY3Q7XHJcbiAgICByZXR1cm4gYXNwZWN0LmdldFByb3BlcnR5UGF0aCh0aGlzLnBhcmVudFByb3BlcnR5IS5uYW1lICsgXCIuXCIgKyBwcm9wTmFtZSk7XHJcbiAgfVxyXG5cclxufVxyXG5cclxuZnVuY3Rpb24gY2xlYXJPcmlnaW5hbFZhbHVlcyh0YXJnZXQ6IGFueSkge1xyXG4gIGxldCBhc3BlY3QgPSB0YXJnZXQuZW50aXR5QXNwZWN0IHx8IHRhcmdldC5jb21wbGV4QXNwZWN0O1xyXG4gIGFzcGVjdC5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG4gIGxldCBzdHlwZSA9IHRhcmdldC5lbnRpdHlUeXBlIHx8IHRhcmdldC5jb21wbGV4VHlwZTtcclxuICBzdHlwZS5jb21wbGV4UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChjcDogYW55KSB7XHJcbiAgICBsZXQgY29zID0gdGFyZ2V0LmdldFByb3BlcnR5KGNwLm5hbWUpO1xyXG4gICAgaWYgKGNwLmlzU2NhbGFyKSB7XHJcbiAgICAgIGNsZWFyT3JpZ2luYWxWYWx1ZXMoY29zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvcy5fYWNjZXB0Q2hhbmdlcygpO1xyXG4gICAgICBjb3MuZm9yRWFjaChjbGVhck9yaWdpbmFsVmFsdWVzKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuXHJcbiJdfQ==
|