@angular/core 16.0.0-next.4 → 16.0.0-next.6
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/esm2022/rxjs-interop/index.mjs +9 -0
- package/esm2022/rxjs-interop/public_api.mjs +15 -0
- package/esm2022/rxjs-interop/rxjs-interop.mjs +5 -0
- package/esm2022/rxjs-interop/src/from_observable.mjs +46 -0
- package/esm2022/rxjs-interop/src/from_signal.mjs +36 -0
- package/esm2022/rxjs-interop/src/index.mjs +11 -0
- package/esm2022/rxjs-interop/src/take_until_destroyed.mjs +33 -0
- package/{esm2020 → esm2022}/src/application_init.mjs +3 -3
- package/{esm2020 → esm2022}/src/application_module.mjs +4 -4
- package/esm2022/src/application_ref.mjs +969 -0
- package/{esm2020 → esm2022}/src/change_detection/change_detector_ref.mjs +6 -6
- package/esm2022/src/change_detection/differs/iterable_differs.mjs +81 -0
- package/esm2022/src/change_detection/differs/keyvalue_differs.mjs +74 -0
- package/{esm2020 → esm2022}/src/console.mjs +3 -3
- package/esm2022/src/core.mjs +56 -0
- package/esm2022/src/core_private_export.mjs +39 -0
- package/esm2022/src/core_reactivity_export_internal.mjs +12 -0
- package/esm2022/src/di/contextual.mjs +54 -0
- package/esm2022/src/di/index.mjs +29 -0
- package/esm2022/src/di/injector.mjs +62 -0
- package/esm2022/src/di/injector_compatibility.mjs +239 -0
- package/esm2022/src/di/provider_collection.mjs +279 -0
- package/esm2022/src/di/reflective_injector.mjs +311 -0
- package/esm2022/src/errors.mjs +49 -0
- package/esm2022/src/hydration/annotate.mjs +426 -0
- package/esm2022/src/hydration/api.mjs +176 -0
- package/esm2022/src/hydration/cleanup.mjs +95 -0
- package/esm2022/src/hydration/node_lookup_utils.mjs +273 -0
- package/esm2022/src/hydration/utils.mjs +219 -0
- package/esm2022/src/initial_render_pending_tasks.mjs +75 -0
- package/{esm2020 → esm2022}/src/linker/compiler.mjs +5 -5
- package/{esm2020 → esm2022}/src/linker/component_factory.mjs +1 -1
- package/esm2022/src/linker/component_factory_resolver.mjs +42 -0
- package/{esm2020 → esm2022}/src/linker/destroy_ref.mjs +11 -11
- package/{esm2020 → esm2022}/src/linker/element_ref.mjs +6 -6
- package/esm2022/src/linker/query_list.mjs +169 -0
- package/esm2022/src/linker/template_ref.mjs +102 -0
- package/{esm2020 → esm2022}/src/linker/view_container_ref.mjs +7 -7
- package/{esm2020 → esm2022}/src/linker/view_ref.mjs +2 -2
- package/esm2022/src/metadata/di.mjs +69 -0
- package/{esm2020 → esm2022}/src/metadata/directives.mjs +1 -1
- package/{esm2020 → esm2022}/src/metadata/do_boostrap.mjs +1 -1
- package/{esm2020 → esm2022}/src/metadata/ng_module.mjs +2 -2
- package/esm2022/src/metadata.mjs +18 -0
- package/{esm2020 → esm2022}/src/render/api.mjs +6 -6
- package/esm2022/src/render3/component_ref.mjs +393 -0
- package/{esm2020 → esm2022}/src/render3/context_discovery.mjs +1 -1
- package/esm2022/src/render3/features/standalone_feature.mjs +70 -0
- package/{esm2020 → esm2022}/src/render3/instructions/element.mjs +3 -2
- package/{esm2020 → esm2022}/src/render3/instructions/element_container.mjs +1 -2
- package/esm2022/src/render3/instructions/listener.mjs +244 -0
- package/esm2022/src/render3/instructions/mark_view_dirty.mjs +35 -0
- package/{esm2020 → esm2022}/src/render3/instructions/shared.mjs +26 -38
- package/{esm2020 → esm2022}/src/render3/instructions/styling.mjs +5 -2
- package/esm2022/src/render3/interfaces/view.mjs +48 -0
- package/esm2022/src/render3/jit/module.mjs +531 -0
- package/esm2022/src/render3/ng_module_ref.mjs +134 -0
- package/esm2022/src/render3/node_manipulation.mjs +960 -0
- package/esm2022/src/render3/reactive_lview_consumer.mjs +81 -0
- package/esm2022/src/render3/reactivity/effect.mjs +77 -0
- package/{esm2020 → esm2022}/src/render3/util/change_detection_utils.mjs +2 -2
- package/esm2022/src/render3/view_ref.mjs +307 -0
- package/{esm2020 → esm2022}/src/sanitization/sanitization.mjs +3 -3
- package/{esm2020 → esm2022}/src/sanitization/sanitizer.mjs +7 -7
- package/esm2022/src/signals/index.mjs +16 -0
- package/esm2022/src/signals/src/api.mjs +46 -0
- package/esm2022/src/signals/src/computed.mjs +140 -0
- package/esm2022/src/signals/src/errors.mjs +18 -0
- package/esm2022/src/signals/src/graph.mjs +189 -0
- package/esm2022/src/signals/src/signal.mjs +86 -0
- package/esm2022/src/signals/src/watch.mjs +63 -0
- package/esm2022/src/signals/src/weak_ref.mjs +35 -0
- package/{esm2020 → esm2022}/src/testability/testability.mjs +5 -5
- package/esm2022/src/transfer_state.mjs +153 -0
- package/esm2022/src/util/ng_dev_mode.mjs +80 -0
- package/{esm2020 → esm2022}/src/version.mjs +1 -1
- package/{esm2020 → esm2022}/testing/src/logger.mjs +4 -4
- package/{esm2020 → esm2022}/testing/src/ng_zone_mock.mjs +4 -4
- package/{esm2020 → esm2022}/testing/src/test_bed.mjs +2 -2
- package/esm2022/testing/src/test_bed_compiler.mjs +845 -0
- package/{fesm2020 → fesm2022}/core.mjs +15745 -15364
- package/fesm2022/core.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +104 -0
- package/fesm2022/rxjs-interop.mjs.map +1 -0
- package/{fesm2020 → fesm2022}/testing.mjs +913 -176
- package/fesm2022/testing.mjs.map +1 -0
- package/index.d.ts +459 -211
- package/package.json +14 -16
- package/rxjs-interop/index.d.ts +95 -0
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +694 -0
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js.map +7 -0
- package/schematics/migrations/{router-link-with-href → remove-module-id}/bundle.js +153 -155
- package/schematics/migrations/remove-module-id/bundle.js.map +7 -0
- package/schematics/migrations.json +8 -8
- package/schematics/ng-generate/standalone-migration/bundle.js +928 -562
- package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
- package/testing/index.d.ts +1 -1
- package/esm2020/src/application_ref.mjs +0 -907
- package/esm2020/src/change_detection/differs/iterable_differs.mjs +0 -81
- package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +0 -74
- package/esm2020/src/core.mjs +0 -55
- package/esm2020/src/core_private_export.mjs +0 -38
- package/esm2020/src/core_reactivity_export_internal.mjs +0 -9
- package/esm2020/src/di/contextual.mjs +0 -37
- package/esm2020/src/di/index.mjs +0 -29
- package/esm2020/src/di/injector.mjs +0 -62
- package/esm2020/src/di/injector_compatibility.mjs +0 -236
- package/esm2020/src/di/provider_collection.mjs +0 -279
- package/esm2020/src/di/reflective_injector.mjs +0 -311
- package/esm2020/src/errors.mjs +0 -48
- package/esm2020/src/hydration/annotate.mjs +0 -384
- package/esm2020/src/hydration/api.mjs +0 -141
- package/esm2020/src/hydration/cleanup.mjs +0 -101
- package/esm2020/src/hydration/node_lookup_utils.mjs +0 -275
- package/esm2020/src/hydration/utils.mjs +0 -219
- package/esm2020/src/linker/component_factory_resolver.mjs +0 -42
- package/esm2020/src/linker/query_list.mjs +0 -169
- package/esm2020/src/linker/template_ref.mjs +0 -102
- package/esm2020/src/metadata/di.mjs +0 -108
- package/esm2020/src/metadata.mjs +0 -18
- package/esm2020/src/render3/component_ref.mjs +0 -377
- package/esm2020/src/render3/features/standalone_feature.mjs +0 -70
- package/esm2020/src/render3/instructions/listener.mjs +0 -243
- package/esm2020/src/render3/interfaces/view.mjs +0 -47
- package/esm2020/src/render3/jit/module.mjs +0 -544
- package/esm2020/src/render3/ng_module_ref.mjs +0 -132
- package/esm2020/src/render3/node_manipulation.mjs +0 -961
- package/esm2020/src/render3/view_ref.mjs +0 -306
- package/esm2020/src/signals/index.mjs +0 -16
- package/esm2020/src/signals/src/api.mjs +0 -46
- package/esm2020/src/signals/src/computed.mjs +0 -142
- package/esm2020/src/signals/src/effect.mjs +0 -67
- package/esm2020/src/signals/src/graph.mjs +0 -114
- package/esm2020/src/signals/src/signal.mjs +0 -78
- package/esm2020/src/signals/src/watch.mjs +0 -54
- package/esm2020/src/signals/src/weak_ref.mjs +0 -27
- package/esm2020/src/transfer_state.mjs +0 -153
- package/esm2020/src/util/ng_dev_mode.mjs +0 -79
- package/esm2020/testing/src/test_bed_compiler.mjs +0 -846
- package/fesm2015/core.mjs +0 -30473
- package/fesm2015/core.mjs.map +0 -1
- package/fesm2015/testing.mjs +0 -26417
- package/fesm2015/testing.mjs.map +0 -1
- package/fesm2020/core.mjs.map +0 -1
- package/fesm2020/testing.mjs.map +0 -1
- package/schematics/migrations/relative-link-resolution/bundle.js +0 -283
- package/schematics/migrations/relative-link-resolution/bundle.js.map +0 -7
- package/schematics/migrations/router-link-with-href/bundle.js.map +0 -7
- /package/{esm2020 → esm2022}/core.mjs +0 -0
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/application_config.mjs +0 -0
- /package/{esm2020 → esm2022}/src/application_tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/constants.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/differs/default_iterable_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/differs/default_keyvalue_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/pipe_transform.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/compiler/compiler_facade.mjs +0 -0
- /package/{esm2020 → esm2022}/src/compiler/compiler_facade_interface.mjs +0 -0
- /package/{esm2020 → esm2022}/src/core_reactivity_export.mjs +0 -0
- /package/{esm2020 → esm2022}/src/core_render3_private_export.mjs +0 -0
- /package/{esm2020 → esm2022}/src/debug/debug_node.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/create_injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/forward_ref.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/initializer_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/inject_switch.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injectable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injection_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injector_marker.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injector_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/defs.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/provider.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/internal_tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/injectable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/metadata.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/metadata_attr.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/null_injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/provider_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/r3_injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_key.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_provider.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/scope.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/error_details_base_url.mjs +0 -0
- /package/{esm2020 → esm2022}/src/error_handler.mjs +0 -0
- /package/{esm2020 → esm2022}/src/event_emitter.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/compression.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/error_handling.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/interfaces.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/skip_hydration.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/views.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/locale_data_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/locale_en.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/localization.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/lifecycle_hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/simple_change.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/type.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader_impl.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_registration.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/ng_module_def.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/resource_loading.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/schema.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/view.mjs +0 -0
- /package/{esm2020 → esm2022}/src/platform_core_providers.mjs +0 -0
- /package/{esm2020 → esm2022}/src/r3_symbols.mjs +0 -0
- /package/{esm2020 → esm2022}/src/reflection/platform_reflection_capabilities.mjs +0 -0
- /package/{esm2020 → esm2022}/src/reflection/reflection_capabilities.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render/api_flags.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/bindings.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/collect_native_nodes.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/component.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/definition.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/definition_factory.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/di_setup.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/errors_di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/copy_definition_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/host_directives_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/inherit_definition_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/ng_onchanges_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/providers_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/fields.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/global_utils_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_apply.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_debug.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_insert_before_index.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_locale_id.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_parse.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_postprocess.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_tree_shaking.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/index.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/advance.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/all.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/attribute.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/attribute_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/class_map_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/di_attr.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/element_validation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/get_current_view.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/host_property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/i18n_icu_container_visitor.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/namespace.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/next_context.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/projection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/property_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/storage.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/style_map_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/style_prop_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/template.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/text.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/text_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/container.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/context.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/definition.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/document.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/lview_tracking.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/node.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/projection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/public_definitions.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/query.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/renderer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/renderer_dom.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/sanitization.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/styling.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/type_checks.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/directive.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/jit_options.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/module_patch.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/partial.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/pipe.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/metadata.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/namespaces.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/node_assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/node_manipulation_i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/node_selector_matcher.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/pipe.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/profiler.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/pure_function.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/query.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/state.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/class_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/static_styling.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/style_binding_list.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/styling_parser.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/attrs_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/discovery_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/global_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/injector_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/misc_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/stringify_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/view_traversal_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/view_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/view_engine_compatibility_prebound.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/bypass.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/html_sanitizer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/iframe_attrs_validation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/inert_body.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/security.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/url_sanitizer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/signals/src/untracked.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/array_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/char_code.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/closure.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/coercion.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/comparison.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/decorators.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/dom.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/empty.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/global.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/is_dev_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/iterable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/lang.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/microtask.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_i18n_closure_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_jit_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_reflect.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/noop.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/raf.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_type_defs.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_types.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_types_bypass.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/stringify.mjs +0 -0
- /package/{esm2020 → esm2022}/src/view/provider_flags.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone/async-stack-tagging.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone/ng_zone.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/async.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/component_fixture.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/fake_async.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/metadata_override.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/metadata_overrider.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/resolvers.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/styling.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/test_bed_common.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/test_hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/testing.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/testing_internal.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/testing.mjs +0 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { ResourceLoader } from '@angular/compiler';
|
|
9
|
+
import { ApplicationInitStatus, Compiler, COMPILER_OPTIONS, LOCALE_ID, ModuleWithComponentFactories, provideZoneChangeDetection, resolveForwardRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID, ɵgetInjectableDef as getInjectableDef, ɵisEnvironmentProviders as isEnvironmentProviders, ɵNG_COMP_DEF as NG_COMP_DEF, ɵNG_DIR_DEF as NG_DIR_DEF, ɵNG_INJ_DEF as NG_INJ_DEF, ɵNG_MOD_DEF as NG_MOD_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵNgModuleFactory as R3NgModuleFactory, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵsetLocaleId as setLocaleId, ɵtransitiveScopesFor as transitiveScopesFor } from '@angular/core';
|
|
10
|
+
import { clearResolutionOfComponentResourcesQueue, isComponentDefPendingResolution, resolveComponentResources, restoreComponentResolutionQueue } from '../../src/metadata/resource_loading';
|
|
11
|
+
import { generateStandaloneInDeclarationsError } from '../../src/render3/jit/module';
|
|
12
|
+
import { ComponentResolver, DirectiveResolver, NgModuleResolver, PipeResolver } from './resolvers';
|
|
13
|
+
var TestingModuleOverride;
|
|
14
|
+
(function (TestingModuleOverride) {
|
|
15
|
+
TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
|
|
16
|
+
TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
|
|
17
|
+
})(TestingModuleOverride || (TestingModuleOverride = {}));
|
|
18
|
+
function isTestingModuleOverride(value) {
|
|
19
|
+
return value === TestingModuleOverride.DECLARATION ||
|
|
20
|
+
value === TestingModuleOverride.OVERRIDE_TEMPLATE;
|
|
21
|
+
}
|
|
22
|
+
function assertNoStandaloneComponents(types, resolver, location) {
|
|
23
|
+
types.forEach(type => {
|
|
24
|
+
const component = resolver.resolve(type);
|
|
25
|
+
if (component && component.standalone) {
|
|
26
|
+
throw new Error(generateStandaloneInDeclarationsError(type, location));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export class TestBedCompiler {
|
|
31
|
+
constructor(platform, additionalModuleTypes) {
|
|
32
|
+
this.platform = platform;
|
|
33
|
+
this.additionalModuleTypes = additionalModuleTypes;
|
|
34
|
+
this.originalComponentResolutionQueue = null;
|
|
35
|
+
// Testing module configuration
|
|
36
|
+
this.declarations = [];
|
|
37
|
+
this.imports = [];
|
|
38
|
+
this.providers = [];
|
|
39
|
+
this.schemas = [];
|
|
40
|
+
// Queues of components/directives/pipes that should be recompiled.
|
|
41
|
+
this.pendingComponents = new Set();
|
|
42
|
+
this.pendingDirectives = new Set();
|
|
43
|
+
this.pendingPipes = new Set();
|
|
44
|
+
// Keep track of all components and directives, so we can patch Providers onto defs later.
|
|
45
|
+
this.seenComponents = new Set();
|
|
46
|
+
this.seenDirectives = new Set();
|
|
47
|
+
// Keep track of overridden modules, so that we can collect all affected ones in the module tree.
|
|
48
|
+
this.overriddenModules = new Set();
|
|
49
|
+
// Store resolved styles for Components that have template overrides present and `styleUrls`
|
|
50
|
+
// defined at the same time.
|
|
51
|
+
this.existingComponentStyles = new Map();
|
|
52
|
+
this.resolvers = initResolvers();
|
|
53
|
+
this.componentToModuleScope = new Map();
|
|
54
|
+
// Map that keeps initial version of component/directive/pipe defs in case
|
|
55
|
+
// we compile a Type again, thus overriding respective static fields. This is
|
|
56
|
+
// required to make sure we restore defs to their initial states between test runs.
|
|
57
|
+
// Note: one class may have multiple defs (for example: ɵmod and ɵinj in case of an
|
|
58
|
+
// NgModule), store all of them in a map.
|
|
59
|
+
this.initialNgDefs = new Map();
|
|
60
|
+
// Array that keeps cleanup operations for initial versions of component/directive/pipe/module
|
|
61
|
+
// defs in case TestBed makes changes to the originals.
|
|
62
|
+
this.defCleanupOps = [];
|
|
63
|
+
this._injector = null;
|
|
64
|
+
this.compilerProviders = null;
|
|
65
|
+
this.providerOverrides = [];
|
|
66
|
+
this.rootProviderOverrides = [];
|
|
67
|
+
// Overrides for injectables with `{providedIn: SomeModule}` need to be tracked and added to that
|
|
68
|
+
// module's provider list.
|
|
69
|
+
this.providerOverridesByModule = new Map();
|
|
70
|
+
this.providerOverridesByToken = new Map();
|
|
71
|
+
this.scopesWithOverriddenProviders = new Set();
|
|
72
|
+
this.testModuleRef = null;
|
|
73
|
+
class DynamicTestModule {
|
|
74
|
+
}
|
|
75
|
+
this.testModuleType = DynamicTestModule;
|
|
76
|
+
}
|
|
77
|
+
setCompilerProviders(providers) {
|
|
78
|
+
this.compilerProviders = providers;
|
|
79
|
+
this._injector = null;
|
|
80
|
+
}
|
|
81
|
+
configureTestingModule(moduleDef) {
|
|
82
|
+
// Enqueue any compilation tasks for the directly declared component.
|
|
83
|
+
if (moduleDef.declarations !== undefined) {
|
|
84
|
+
// Verify that there are no standalone components
|
|
85
|
+
assertNoStandaloneComponents(moduleDef.declarations, this.resolvers.component, '"TestBed.configureTestingModule" call');
|
|
86
|
+
this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
|
|
87
|
+
this.declarations.push(...moduleDef.declarations);
|
|
88
|
+
}
|
|
89
|
+
// Enqueue any compilation tasks for imported modules.
|
|
90
|
+
if (moduleDef.imports !== undefined) {
|
|
91
|
+
this.queueTypesFromModulesArray(moduleDef.imports);
|
|
92
|
+
this.imports.push(...moduleDef.imports);
|
|
93
|
+
}
|
|
94
|
+
if (moduleDef.providers !== undefined) {
|
|
95
|
+
this.providers.push(...moduleDef.providers);
|
|
96
|
+
}
|
|
97
|
+
if (moduleDef.schemas !== undefined) {
|
|
98
|
+
this.schemas.push(...moduleDef.schemas);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
overrideModule(ngModule, override) {
|
|
102
|
+
this.overriddenModules.add(ngModule);
|
|
103
|
+
// Compile the module right away.
|
|
104
|
+
this.resolvers.module.addOverride(ngModule, override);
|
|
105
|
+
const metadata = this.resolvers.module.resolve(ngModule);
|
|
106
|
+
if (metadata === null) {
|
|
107
|
+
throw invalidTypeError(ngModule.name, 'NgModule');
|
|
108
|
+
}
|
|
109
|
+
this.recompileNgModule(ngModule, metadata);
|
|
110
|
+
// At this point, the module has a valid module def (ɵmod), but the override may have introduced
|
|
111
|
+
// new declarations or imported modules. Ingest any possible new types and add them to the
|
|
112
|
+
// current queue.
|
|
113
|
+
this.queueTypesFromModulesArray([ngModule]);
|
|
114
|
+
}
|
|
115
|
+
overrideComponent(component, override) {
|
|
116
|
+
this.verifyNoStandaloneFlagOverrides(component, override);
|
|
117
|
+
this.resolvers.component.addOverride(component, override);
|
|
118
|
+
this.pendingComponents.add(component);
|
|
119
|
+
}
|
|
120
|
+
overrideDirective(directive, override) {
|
|
121
|
+
this.verifyNoStandaloneFlagOverrides(directive, override);
|
|
122
|
+
this.resolvers.directive.addOverride(directive, override);
|
|
123
|
+
this.pendingDirectives.add(directive);
|
|
124
|
+
}
|
|
125
|
+
overridePipe(pipe, override) {
|
|
126
|
+
this.verifyNoStandaloneFlagOverrides(pipe, override);
|
|
127
|
+
this.resolvers.pipe.addOverride(pipe, override);
|
|
128
|
+
this.pendingPipes.add(pipe);
|
|
129
|
+
}
|
|
130
|
+
verifyNoStandaloneFlagOverrides(type, override) {
|
|
131
|
+
if (override.add?.hasOwnProperty('standalone') || override.set?.hasOwnProperty('standalone') ||
|
|
132
|
+
override.remove?.hasOwnProperty('standalone')) {
|
|
133
|
+
throw new Error(`An override for the ${type.name} class has the \`standalone\` flag. ` +
|
|
134
|
+
`Changing the \`standalone\` flag via TestBed overrides is not supported.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
overrideProvider(token, provider) {
|
|
138
|
+
let providerDef;
|
|
139
|
+
if (provider.useFactory !== undefined) {
|
|
140
|
+
providerDef = {
|
|
141
|
+
provide: token,
|
|
142
|
+
useFactory: provider.useFactory,
|
|
143
|
+
deps: provider.deps || [],
|
|
144
|
+
multi: provider.multi
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else if (provider.useValue !== undefined) {
|
|
148
|
+
providerDef = { provide: token, useValue: provider.useValue, multi: provider.multi };
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
providerDef = { provide: token };
|
|
152
|
+
}
|
|
153
|
+
const injectableDef = typeof token !== 'string' ? getInjectableDef(token) : null;
|
|
154
|
+
const providedIn = injectableDef === null ? null : resolveForwardRef(injectableDef.providedIn);
|
|
155
|
+
const overridesBucket = providedIn === 'root' ? this.rootProviderOverrides : this.providerOverrides;
|
|
156
|
+
overridesBucket.push(providerDef);
|
|
157
|
+
// Keep overrides grouped by token as well for fast lookups using token
|
|
158
|
+
this.providerOverridesByToken.set(token, providerDef);
|
|
159
|
+
if (injectableDef !== null && providedIn !== null && typeof providedIn !== 'string') {
|
|
160
|
+
const existingOverrides = this.providerOverridesByModule.get(providedIn);
|
|
161
|
+
if (existingOverrides !== undefined) {
|
|
162
|
+
existingOverrides.push(providerDef);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.providerOverridesByModule.set(providedIn, [providerDef]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
overrideTemplateUsingTestingModule(type, template) {
|
|
170
|
+
const def = type[NG_COMP_DEF];
|
|
171
|
+
const hasStyleUrls = () => {
|
|
172
|
+
const metadata = this.resolvers.component.resolve(type);
|
|
173
|
+
return !!metadata.styleUrls && metadata.styleUrls.length > 0;
|
|
174
|
+
};
|
|
175
|
+
const overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
|
|
176
|
+
// In Ivy, compiling a component does not require knowing the module providing the
|
|
177
|
+
// component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
|
|
178
|
+
// overrideComponent. Important: overriding template requires full Component re-compilation,
|
|
179
|
+
// which may fail in case styleUrls are also present (thus Component is considered as required
|
|
180
|
+
// resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
|
|
181
|
+
// preserve current styles available on Component def and restore styles back once compilation
|
|
182
|
+
// is complete.
|
|
183
|
+
const override = overrideStyleUrls ? { template, styles: [], styleUrls: [] } : { template };
|
|
184
|
+
this.overrideComponent(type, { set: override });
|
|
185
|
+
if (overrideStyleUrls && def.styles && def.styles.length > 0) {
|
|
186
|
+
this.existingComponentStyles.set(type, def.styles);
|
|
187
|
+
}
|
|
188
|
+
// Set the component's scope to be the testing module.
|
|
189
|
+
this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
|
|
190
|
+
}
|
|
191
|
+
async compileComponents() {
|
|
192
|
+
this.clearComponentResolutionQueue();
|
|
193
|
+
// Run compilers for all queued types.
|
|
194
|
+
let needsAsyncResources = this.compileTypesSync();
|
|
195
|
+
// compileComponents() should not be async unless it needs to be.
|
|
196
|
+
if (needsAsyncResources) {
|
|
197
|
+
let resourceLoader;
|
|
198
|
+
let resolver = (url) => {
|
|
199
|
+
if (!resourceLoader) {
|
|
200
|
+
resourceLoader = this.injector.get(ResourceLoader);
|
|
201
|
+
}
|
|
202
|
+
return Promise.resolve(resourceLoader.get(url));
|
|
203
|
+
};
|
|
204
|
+
await resolveComponentResources(resolver);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
finalize() {
|
|
208
|
+
// One last compile
|
|
209
|
+
this.compileTypesSync();
|
|
210
|
+
// Create the testing module itself.
|
|
211
|
+
this.compileTestModule();
|
|
212
|
+
this.applyTransitiveScopes();
|
|
213
|
+
this.applyProviderOverrides();
|
|
214
|
+
// Patch previously stored `styles` Component values (taken from ɵcmp), in case these
|
|
215
|
+
// Components have `styleUrls` fields defined and template override was requested.
|
|
216
|
+
this.patchComponentsWithExistingStyles();
|
|
217
|
+
// Clear the componentToModuleScope map, so that future compilations don't reset the scope of
|
|
218
|
+
// every component.
|
|
219
|
+
this.componentToModuleScope.clear();
|
|
220
|
+
const parentInjector = this.platform.injector;
|
|
221
|
+
this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector, []);
|
|
222
|
+
// ApplicationInitStatus.runInitializers() is marked @internal to core.
|
|
223
|
+
// Cast it to any before accessing it.
|
|
224
|
+
this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
|
|
225
|
+
// Set locale ID after running app initializers, since locale information might be updated while
|
|
226
|
+
// running initializers. This is also consistent with the execution order while bootstrapping an
|
|
227
|
+
// app (see `packages/core/src/application_ref.ts` file).
|
|
228
|
+
const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
|
|
229
|
+
setLocaleId(localeId);
|
|
230
|
+
return this.testModuleRef;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
_compileNgModuleSync(moduleType) {
|
|
236
|
+
this.queueTypesFromModulesArray([moduleType]);
|
|
237
|
+
this.compileTypesSync();
|
|
238
|
+
this.applyProviderOverrides();
|
|
239
|
+
this.applyProviderOverridesInScope(moduleType);
|
|
240
|
+
this.applyTransitiveScopes();
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* @internal
|
|
244
|
+
*/
|
|
245
|
+
async _compileNgModuleAsync(moduleType) {
|
|
246
|
+
this.queueTypesFromModulesArray([moduleType]);
|
|
247
|
+
await this.compileComponents();
|
|
248
|
+
this.applyProviderOverrides();
|
|
249
|
+
this.applyProviderOverridesInScope(moduleType);
|
|
250
|
+
this.applyTransitiveScopes();
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
_getModuleResolver() {
|
|
256
|
+
return this.resolvers.module;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* @internal
|
|
260
|
+
*/
|
|
261
|
+
_getComponentFactories(moduleType) {
|
|
262
|
+
return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce((factories, declaration) => {
|
|
263
|
+
const componentDef = declaration.ɵcmp;
|
|
264
|
+
componentDef && factories.push(new ComponentFactory(componentDef, this.testModuleRef));
|
|
265
|
+
return factories;
|
|
266
|
+
}, []);
|
|
267
|
+
}
|
|
268
|
+
compileTypesSync() {
|
|
269
|
+
// Compile all queued components, directives, pipes.
|
|
270
|
+
let needsAsyncResources = false;
|
|
271
|
+
this.pendingComponents.forEach(declaration => {
|
|
272
|
+
needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
|
|
273
|
+
const metadata = this.resolvers.component.resolve(declaration);
|
|
274
|
+
if (metadata === null) {
|
|
275
|
+
throw invalidTypeError(declaration.name, 'Component');
|
|
276
|
+
}
|
|
277
|
+
this.maybeStoreNgDef(NG_COMP_DEF, declaration);
|
|
278
|
+
compileComponent(declaration, metadata);
|
|
279
|
+
});
|
|
280
|
+
this.pendingComponents.clear();
|
|
281
|
+
this.pendingDirectives.forEach(declaration => {
|
|
282
|
+
const metadata = this.resolvers.directive.resolve(declaration);
|
|
283
|
+
if (metadata === null) {
|
|
284
|
+
throw invalidTypeError(declaration.name, 'Directive');
|
|
285
|
+
}
|
|
286
|
+
this.maybeStoreNgDef(NG_DIR_DEF, declaration);
|
|
287
|
+
compileDirective(declaration, metadata);
|
|
288
|
+
});
|
|
289
|
+
this.pendingDirectives.clear();
|
|
290
|
+
this.pendingPipes.forEach(declaration => {
|
|
291
|
+
const metadata = this.resolvers.pipe.resolve(declaration);
|
|
292
|
+
if (metadata === null) {
|
|
293
|
+
throw invalidTypeError(declaration.name, 'Pipe');
|
|
294
|
+
}
|
|
295
|
+
this.maybeStoreNgDef(NG_PIPE_DEF, declaration);
|
|
296
|
+
compilePipe(declaration, metadata);
|
|
297
|
+
});
|
|
298
|
+
this.pendingPipes.clear();
|
|
299
|
+
return needsAsyncResources;
|
|
300
|
+
}
|
|
301
|
+
applyTransitiveScopes() {
|
|
302
|
+
if (this.overriddenModules.size > 0) {
|
|
303
|
+
// Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
|
|
304
|
+
// calculated and stored in `transitiveCompileScopes`. If module overrides are present,
|
|
305
|
+
// collect all affected modules and reset scopes to force their re-calculation.
|
|
306
|
+
const testingModuleDef = this.testModuleType[NG_MOD_DEF];
|
|
307
|
+
const affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
|
|
308
|
+
if (affectedModules.size > 0) {
|
|
309
|
+
affectedModules.forEach(moduleType => {
|
|
310
|
+
this.storeFieldOfDefOnType(moduleType, NG_MOD_DEF, 'transitiveCompileScopes');
|
|
311
|
+
moduleType[NG_MOD_DEF].transitiveCompileScopes = null;
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const moduleToScope = new Map();
|
|
316
|
+
const getScopeOfModule = (moduleType) => {
|
|
317
|
+
if (!moduleToScope.has(moduleType)) {
|
|
318
|
+
const isTestingModule = isTestingModuleOverride(moduleType);
|
|
319
|
+
const realType = isTestingModule ? this.testModuleType : moduleType;
|
|
320
|
+
moduleToScope.set(moduleType, transitiveScopesFor(realType));
|
|
321
|
+
}
|
|
322
|
+
return moduleToScope.get(moduleType);
|
|
323
|
+
};
|
|
324
|
+
this.componentToModuleScope.forEach((moduleType, componentType) => {
|
|
325
|
+
const moduleScope = getScopeOfModule(moduleType);
|
|
326
|
+
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'directiveDefs');
|
|
327
|
+
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'pipeDefs');
|
|
328
|
+
// `tView` that is stored on component def contains information about directives and pipes
|
|
329
|
+
// that are in the scope of this component. Patching component scope will cause `tView` to be
|
|
330
|
+
// changed. Store original `tView` before patching scope, so the `tView` (including scope
|
|
331
|
+
// information) is restored back to its previous/original state before running next test.
|
|
332
|
+
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'tView');
|
|
333
|
+
patchComponentDefWithScope(componentType.ɵcmp, moduleScope);
|
|
334
|
+
});
|
|
335
|
+
this.componentToModuleScope.clear();
|
|
336
|
+
}
|
|
337
|
+
applyProviderOverrides() {
|
|
338
|
+
const maybeApplyOverrides = (field) => (type) => {
|
|
339
|
+
const resolver = field === NG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
|
|
340
|
+
const metadata = resolver.resolve(type);
|
|
341
|
+
if (this.hasProviderOverrides(metadata.providers)) {
|
|
342
|
+
this.patchDefWithProviderOverrides(type, field);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
this.seenComponents.forEach(maybeApplyOverrides(NG_COMP_DEF));
|
|
346
|
+
this.seenDirectives.forEach(maybeApplyOverrides(NG_DIR_DEF));
|
|
347
|
+
this.seenComponents.clear();
|
|
348
|
+
this.seenDirectives.clear();
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Applies provider overrides to a given type (either an NgModule or a standalone component)
|
|
352
|
+
* and all imported NgModules and standalone components recursively.
|
|
353
|
+
*/
|
|
354
|
+
applyProviderOverridesInScope(type) {
|
|
355
|
+
const hasScope = isStandaloneComponent(type) || isNgModule(type);
|
|
356
|
+
// The function can be re-entered recursively while inspecting dependencies
|
|
357
|
+
// of an NgModule or a standalone component. Exit early if we come across a
|
|
358
|
+
// type that can not have a scope (directive or pipe) or the type is already
|
|
359
|
+
// processed earlier.
|
|
360
|
+
if (!hasScope || this.scopesWithOverriddenProviders.has(type)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
this.scopesWithOverriddenProviders.add(type);
|
|
364
|
+
// NOTE: the line below triggers JIT compilation of the module injector,
|
|
365
|
+
// which also invokes verification of the NgModule semantics, which produces
|
|
366
|
+
// detailed error messages. The fact that the code relies on this line being
|
|
367
|
+
// present here is suspicious and should be refactored in a way that the line
|
|
368
|
+
// below can be moved (for ex. after an early exit check below).
|
|
369
|
+
const injectorDef = type[NG_INJ_DEF];
|
|
370
|
+
// No provider overrides, exit early.
|
|
371
|
+
if (this.providerOverridesByToken.size === 0)
|
|
372
|
+
return;
|
|
373
|
+
if (isStandaloneComponent(type)) {
|
|
374
|
+
// Visit all component dependencies and override providers there.
|
|
375
|
+
const def = getComponentDef(type);
|
|
376
|
+
const dependencies = maybeUnwrapFn(def.dependencies ?? []);
|
|
377
|
+
for (const dependency of dependencies) {
|
|
378
|
+
this.applyProviderOverridesInScope(dependency);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
const providers = [
|
|
383
|
+
...injectorDef.providers,
|
|
384
|
+
...(this.providerOverridesByModule.get(type) || [])
|
|
385
|
+
];
|
|
386
|
+
if (this.hasProviderOverrides(providers)) {
|
|
387
|
+
this.maybeStoreNgDef(NG_INJ_DEF, type);
|
|
388
|
+
this.storeFieldOfDefOnType(type, NG_INJ_DEF, 'providers');
|
|
389
|
+
injectorDef.providers = this.getOverriddenProviders(providers);
|
|
390
|
+
}
|
|
391
|
+
// Apply provider overrides to imported modules recursively
|
|
392
|
+
const moduleDef = type[NG_MOD_DEF];
|
|
393
|
+
const imports = maybeUnwrapFn(moduleDef.imports);
|
|
394
|
+
for (const importedModule of imports) {
|
|
395
|
+
this.applyProviderOverridesInScope(importedModule);
|
|
396
|
+
}
|
|
397
|
+
// Also override the providers on any ModuleWithProviders imports since those don't appear in
|
|
398
|
+
// the moduleDef.
|
|
399
|
+
for (const importedModule of flatten(injectorDef.imports)) {
|
|
400
|
+
if (isModuleWithProviders(importedModule)) {
|
|
401
|
+
this.defCleanupOps.push({
|
|
402
|
+
object: importedModule,
|
|
403
|
+
fieldName: 'providers',
|
|
404
|
+
originalValue: importedModule.providers
|
|
405
|
+
});
|
|
406
|
+
importedModule.providers = this.getOverriddenProviders(importedModule.providers);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
patchComponentsWithExistingStyles() {
|
|
412
|
+
this.existingComponentStyles.forEach((styles, type) => type[NG_COMP_DEF].styles = styles);
|
|
413
|
+
this.existingComponentStyles.clear();
|
|
414
|
+
}
|
|
415
|
+
queueTypeArray(arr, moduleType) {
|
|
416
|
+
for (const value of arr) {
|
|
417
|
+
if (Array.isArray(value)) {
|
|
418
|
+
this.queueTypeArray(value, moduleType);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
this.queueType(value, moduleType);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
recompileNgModule(ngModule, metadata) {
|
|
426
|
+
// Cache the initial ngModuleDef as it will be overwritten.
|
|
427
|
+
this.maybeStoreNgDef(NG_MOD_DEF, ngModule);
|
|
428
|
+
this.maybeStoreNgDef(NG_INJ_DEF, ngModule);
|
|
429
|
+
compileNgModuleDefs(ngModule, metadata);
|
|
430
|
+
}
|
|
431
|
+
queueType(type, moduleType) {
|
|
432
|
+
const component = this.resolvers.component.resolve(type);
|
|
433
|
+
if (component) {
|
|
434
|
+
// Check whether a give Type has respective NG def (ɵcmp) and compile if def is
|
|
435
|
+
// missing. That might happen in case a class without any Angular decorators extends another
|
|
436
|
+
// class where Component/Directive/Pipe decorator is defined.
|
|
437
|
+
if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(NG_COMP_DEF)) {
|
|
438
|
+
this.pendingComponents.add(type);
|
|
439
|
+
}
|
|
440
|
+
this.seenComponents.add(type);
|
|
441
|
+
// Keep track of the module which declares this component, so later the component's scope
|
|
442
|
+
// can be set correctly. If the component has already been recorded here, then one of several
|
|
443
|
+
// cases is true:
|
|
444
|
+
// * the module containing the component was imported multiple times (common).
|
|
445
|
+
// * the component is declared in multiple modules (which is an error).
|
|
446
|
+
// * the component was in 'declarations' of the testing module, and also in an imported module
|
|
447
|
+
// in which case the module scope will be TestingModuleOverride.DECLARATION.
|
|
448
|
+
// * overrideTemplateUsingTestingModule was called for the component in which case the module
|
|
449
|
+
// scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
|
|
450
|
+
//
|
|
451
|
+
// If the component was previously in the testing module's 'declarations' (meaning the
|
|
452
|
+
// current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
|
|
453
|
+
// real module, which was imported. This pattern is understood to mean that the component
|
|
454
|
+
// should use its original scope, but that the testing module should also contain the
|
|
455
|
+
// component in its scope.
|
|
456
|
+
//
|
|
457
|
+
// Note: standalone components have no associated NgModule, so the `moduleType` can be `null`.
|
|
458
|
+
if (moduleType !== null &&
|
|
459
|
+
(!this.componentToModuleScope.has(type) ||
|
|
460
|
+
this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION)) {
|
|
461
|
+
this.componentToModuleScope.set(type, moduleType);
|
|
462
|
+
}
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
const directive = this.resolvers.directive.resolve(type);
|
|
466
|
+
if (directive) {
|
|
467
|
+
if (!type.hasOwnProperty(NG_DIR_DEF)) {
|
|
468
|
+
this.pendingDirectives.add(type);
|
|
469
|
+
}
|
|
470
|
+
this.seenDirectives.add(type);
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
const pipe = this.resolvers.pipe.resolve(type);
|
|
474
|
+
if (pipe && !type.hasOwnProperty(NG_PIPE_DEF)) {
|
|
475
|
+
this.pendingPipes.add(type);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
queueTypesFromModulesArray(arr) {
|
|
480
|
+
// Because we may encounter the same NgModule or a standalone Component while processing
|
|
481
|
+
// the dependencies of an NgModule or a standalone Component, we cache them in this set so we
|
|
482
|
+
// can skip ones that have already been seen encountered. In some test setups, this caching
|
|
483
|
+
// resulted in 10X runtime improvement.
|
|
484
|
+
const processedDefs = new Set();
|
|
485
|
+
const queueTypesFromModulesArrayRecur = (arr) => {
|
|
486
|
+
for (const value of arr) {
|
|
487
|
+
if (Array.isArray(value)) {
|
|
488
|
+
queueTypesFromModulesArrayRecur(value);
|
|
489
|
+
}
|
|
490
|
+
else if (hasNgModuleDef(value)) {
|
|
491
|
+
const def = value.ɵmod;
|
|
492
|
+
if (processedDefs.has(def)) {
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
processedDefs.add(def);
|
|
496
|
+
// Look through declarations, imports, and exports, and queue
|
|
497
|
+
// everything found there.
|
|
498
|
+
this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
|
|
499
|
+
queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports));
|
|
500
|
+
queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports));
|
|
501
|
+
}
|
|
502
|
+
else if (isModuleWithProviders(value)) {
|
|
503
|
+
queueTypesFromModulesArrayRecur([value.ngModule]);
|
|
504
|
+
}
|
|
505
|
+
else if (isStandaloneComponent(value)) {
|
|
506
|
+
this.queueType(value, null);
|
|
507
|
+
const def = getComponentDef(value);
|
|
508
|
+
if (processedDefs.has(def)) {
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
processedDefs.add(def);
|
|
512
|
+
const dependencies = maybeUnwrapFn(def.dependencies ?? []);
|
|
513
|
+
dependencies.forEach((dependency) => {
|
|
514
|
+
// Note: in AOT, the `dependencies` might also contain regular
|
|
515
|
+
// (NgModule-based) Component, Directive and Pipes, so we handle
|
|
516
|
+
// them separately and proceed with recursive process for standalone
|
|
517
|
+
// Components and NgModules only.
|
|
518
|
+
if (isStandaloneComponent(dependency) || hasNgModuleDef(dependency)) {
|
|
519
|
+
queueTypesFromModulesArrayRecur([dependency]);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
this.queueType(dependency, null);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
queueTypesFromModulesArrayRecur(arr);
|
|
529
|
+
}
|
|
530
|
+
// When module overrides (via `TestBed.overrideModule`) are present, it might affect all modules
|
|
531
|
+
// that import (even transitively) an overridden one. For all affected modules we need to
|
|
532
|
+
// recalculate their scopes for a given test run and restore original scopes at the end. The goal
|
|
533
|
+
// of this function is to collect all affected modules in a set for further processing. Example:
|
|
534
|
+
// if we have the following module hierarchy: A -> B -> C (where `->` means `imports`) and module
|
|
535
|
+
// `C` is overridden, we consider `A` and `B` as affected, since their scopes might become
|
|
536
|
+
// invalidated with the override.
|
|
537
|
+
collectModulesAffectedByOverrides(arr) {
|
|
538
|
+
const seenModules = new Set();
|
|
539
|
+
const affectedModules = new Set();
|
|
540
|
+
const calcAffectedModulesRecur = (arr, path) => {
|
|
541
|
+
for (const value of arr) {
|
|
542
|
+
if (Array.isArray(value)) {
|
|
543
|
+
// If the value is an array, just flatten it (by invoking this function recursively),
|
|
544
|
+
// keeping "path" the same.
|
|
545
|
+
calcAffectedModulesRecur(value, path);
|
|
546
|
+
}
|
|
547
|
+
else if (hasNgModuleDef(value)) {
|
|
548
|
+
if (seenModules.has(value)) {
|
|
549
|
+
// If we've seen this module before and it's included into "affected modules" list, mark
|
|
550
|
+
// the whole path that leads to that module as affected, but do not descend into its
|
|
551
|
+
// imports, since we already examined them before.
|
|
552
|
+
if (affectedModules.has(value)) {
|
|
553
|
+
path.forEach(item => affectedModules.add(item));
|
|
554
|
+
}
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
seenModules.add(value);
|
|
558
|
+
if (this.overriddenModules.has(value)) {
|
|
559
|
+
path.forEach(item => affectedModules.add(item));
|
|
560
|
+
}
|
|
561
|
+
// Examine module imports recursively to look for overridden modules.
|
|
562
|
+
const moduleDef = value[NG_MOD_DEF];
|
|
563
|
+
calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
calcAffectedModulesRecur(arr, []);
|
|
568
|
+
return affectedModules;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Preserve an original def (such as ɵmod, ɵinj, etc) before applying an override.
|
|
572
|
+
* Note: one class may have multiple defs (for example: ɵmod and ɵinj in case of
|
|
573
|
+
* an NgModule). If there is a def in a set already, don't override it, since
|
|
574
|
+
* an original one should be restored at the end of a test.
|
|
575
|
+
*/
|
|
576
|
+
maybeStoreNgDef(prop, type) {
|
|
577
|
+
if (!this.initialNgDefs.has(type)) {
|
|
578
|
+
this.initialNgDefs.set(type, new Map());
|
|
579
|
+
}
|
|
580
|
+
const currentDefs = this.initialNgDefs.get(type);
|
|
581
|
+
if (!currentDefs.has(prop)) {
|
|
582
|
+
const currentDef = Object.getOwnPropertyDescriptor(type, prop);
|
|
583
|
+
currentDefs.set(prop, currentDef);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
storeFieldOfDefOnType(type, defField, fieldName) {
|
|
587
|
+
const def = type[defField];
|
|
588
|
+
const originalValue = def[fieldName];
|
|
589
|
+
this.defCleanupOps.push({ object: def, fieldName, originalValue });
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Clears current components resolution queue, but stores the state of the queue, so we can
|
|
593
|
+
* restore it later. Clearing the queue is required before we try to compile components (via
|
|
594
|
+
* `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
|
|
595
|
+
*/
|
|
596
|
+
clearComponentResolutionQueue() {
|
|
597
|
+
if (this.originalComponentResolutionQueue === null) {
|
|
598
|
+
this.originalComponentResolutionQueue = new Map();
|
|
599
|
+
}
|
|
600
|
+
clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
|
|
601
|
+
}
|
|
602
|
+
/*
|
|
603
|
+
* Restores component resolution queue to the previously saved state. This operation is performed
|
|
604
|
+
* as a part of restoring the state after completion of the current set of tests (that might
|
|
605
|
+
* potentially mutate the state).
|
|
606
|
+
*/
|
|
607
|
+
restoreComponentResolutionQueue() {
|
|
608
|
+
if (this.originalComponentResolutionQueue !== null) {
|
|
609
|
+
restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
|
|
610
|
+
this.originalComponentResolutionQueue = null;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
restoreOriginalState() {
|
|
614
|
+
// Process cleanup ops in reverse order so the field's original value is restored correctly (in
|
|
615
|
+
// case there were multiple overrides for the same field).
|
|
616
|
+
forEachRight(this.defCleanupOps, (op) => {
|
|
617
|
+
op.object[op.fieldName] = op.originalValue;
|
|
618
|
+
});
|
|
619
|
+
// Restore initial component/directive/pipe defs
|
|
620
|
+
this.initialNgDefs.forEach((defs, type) => {
|
|
621
|
+
defs.forEach((descriptor, prop) => {
|
|
622
|
+
if (!descriptor) {
|
|
623
|
+
// Delete operations are generally undesirable since they have performance
|
|
624
|
+
// implications on objects they were applied to. In this particular case, situations
|
|
625
|
+
// where this code is invoked should be quite rare to cause any noticeable impact,
|
|
626
|
+
// since it's applied only to some test cases (for example when class with no
|
|
627
|
+
// annotations extends some @Component) when we need to clear 'ɵcmp' field on a given
|
|
628
|
+
// class to restore its original state (before applying overrides and running tests).
|
|
629
|
+
delete type[prop];
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
Object.defineProperty(type, prop, descriptor);
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
this.initialNgDefs.clear();
|
|
637
|
+
this.scopesWithOverriddenProviders.clear();
|
|
638
|
+
this.restoreComponentResolutionQueue();
|
|
639
|
+
// Restore the locale ID to the default value, this shouldn't be necessary but we never know
|
|
640
|
+
setLocaleId(DEFAULT_LOCALE_ID);
|
|
641
|
+
}
|
|
642
|
+
compileTestModule() {
|
|
643
|
+
class RootScopeModule {
|
|
644
|
+
}
|
|
645
|
+
compileNgModuleDefs(RootScopeModule, {
|
|
646
|
+
providers: [...this.rootProviderOverrides],
|
|
647
|
+
});
|
|
648
|
+
const providers = [
|
|
649
|
+
provideZoneChangeDetection(),
|
|
650
|
+
{ provide: Compiler, useFactory: () => new R3TestCompiler(this) },
|
|
651
|
+
...this.providers,
|
|
652
|
+
...this.providerOverrides,
|
|
653
|
+
];
|
|
654
|
+
const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
|
|
655
|
+
// clang-format off
|
|
656
|
+
compileNgModuleDefs(this.testModuleType, {
|
|
657
|
+
declarations: this.declarations,
|
|
658
|
+
imports,
|
|
659
|
+
schemas: this.schemas,
|
|
660
|
+
providers,
|
|
661
|
+
}, /* allowDuplicateDeclarationsInRoot */ true);
|
|
662
|
+
// clang-format on
|
|
663
|
+
this.applyProviderOverridesInScope(this.testModuleType);
|
|
664
|
+
}
|
|
665
|
+
get injector() {
|
|
666
|
+
if (this._injector !== null) {
|
|
667
|
+
return this._injector;
|
|
668
|
+
}
|
|
669
|
+
const providers = [];
|
|
670
|
+
const compilerOptions = this.platform.injector.get(COMPILER_OPTIONS);
|
|
671
|
+
compilerOptions.forEach(opts => {
|
|
672
|
+
if (opts.providers) {
|
|
673
|
+
providers.push(opts.providers);
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
if (this.compilerProviders !== null) {
|
|
677
|
+
providers.push(...this.compilerProviders);
|
|
678
|
+
}
|
|
679
|
+
// TODO(ocombe): make this work with an Injector directly instead of creating a module for it
|
|
680
|
+
class CompilerModule {
|
|
681
|
+
}
|
|
682
|
+
compileNgModuleDefs(CompilerModule, { providers });
|
|
683
|
+
const CompilerModuleFactory = new R3NgModuleFactory(CompilerModule);
|
|
684
|
+
this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
|
|
685
|
+
return this._injector;
|
|
686
|
+
}
|
|
687
|
+
// get overrides for a specific provider (if any)
|
|
688
|
+
getSingleProviderOverrides(provider) {
|
|
689
|
+
const token = getProviderToken(provider);
|
|
690
|
+
return this.providerOverridesByToken.get(token) || null;
|
|
691
|
+
}
|
|
692
|
+
getProviderOverrides(providers) {
|
|
693
|
+
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
694
|
+
return [];
|
|
695
|
+
// There are two flattening operations here. The inner flattenProviders() operates on the
|
|
696
|
+
// metadata's providers and applies a mapping function which retrieves overrides for each
|
|
697
|
+
// incoming provider. The outer flatten() then flattens the produced overrides array. If this is
|
|
698
|
+
// not done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
|
|
699
|
+
// providers array and contaminate any error messages that might be generated.
|
|
700
|
+
return flatten(flattenProviders(providers, (provider) => this.getSingleProviderOverrides(provider) || []));
|
|
701
|
+
}
|
|
702
|
+
getOverriddenProviders(providers) {
|
|
703
|
+
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
704
|
+
return [];
|
|
705
|
+
const flattenedProviders = flattenProviders(providers);
|
|
706
|
+
const overrides = this.getProviderOverrides(flattenedProviders);
|
|
707
|
+
const overriddenProviders = [...flattenedProviders, ...overrides];
|
|
708
|
+
const final = [];
|
|
709
|
+
const seenOverriddenProviders = new Set();
|
|
710
|
+
// We iterate through the list of providers in reverse order to make sure provider overrides
|
|
711
|
+
// take precedence over the values defined in provider list. We also filter out all providers
|
|
712
|
+
// that have overrides, keeping overridden values only. This is needed, since presence of a
|
|
713
|
+
// provider with `ngOnDestroy` hook will cause this hook to be registered and invoked later.
|
|
714
|
+
forEachRight(overriddenProviders, (provider) => {
|
|
715
|
+
const token = getProviderToken(provider);
|
|
716
|
+
if (this.providerOverridesByToken.has(token)) {
|
|
717
|
+
if (!seenOverriddenProviders.has(token)) {
|
|
718
|
+
seenOverriddenProviders.add(token);
|
|
719
|
+
// Treat all overridden providers as `{multi: false}` (even if it's a multi-provider) to
|
|
720
|
+
// make sure that provided override takes highest precedence and is not combined with
|
|
721
|
+
// other instances of the same multi provider.
|
|
722
|
+
final.unshift({ ...provider, multi: false });
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
final.unshift(provider);
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
return final;
|
|
730
|
+
}
|
|
731
|
+
hasProviderOverrides(providers) {
|
|
732
|
+
return this.getProviderOverrides(providers).length > 0;
|
|
733
|
+
}
|
|
734
|
+
patchDefWithProviderOverrides(declaration, field) {
|
|
735
|
+
const def = declaration[field];
|
|
736
|
+
if (def && def.providersResolver) {
|
|
737
|
+
this.maybeStoreNgDef(field, declaration);
|
|
738
|
+
const resolver = def.providersResolver;
|
|
739
|
+
const processProvidersFn = (providers) => this.getOverriddenProviders(providers);
|
|
740
|
+
this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
|
|
741
|
+
def.providersResolver = (ngDef) => resolver(ngDef, processProvidersFn);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function initResolvers() {
|
|
746
|
+
return {
|
|
747
|
+
module: new NgModuleResolver(),
|
|
748
|
+
component: new ComponentResolver(),
|
|
749
|
+
directive: new DirectiveResolver(),
|
|
750
|
+
pipe: new PipeResolver()
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
function isStandaloneComponent(value) {
|
|
754
|
+
const def = getComponentDef(value);
|
|
755
|
+
return !!def?.standalone;
|
|
756
|
+
}
|
|
757
|
+
function getComponentDef(value) {
|
|
758
|
+
return value.ɵcmp ?? null;
|
|
759
|
+
}
|
|
760
|
+
function hasNgModuleDef(value) {
|
|
761
|
+
return value.hasOwnProperty('ɵmod');
|
|
762
|
+
}
|
|
763
|
+
function isNgModule(value) {
|
|
764
|
+
return hasNgModuleDef(value);
|
|
765
|
+
}
|
|
766
|
+
function maybeUnwrapFn(maybeFn) {
|
|
767
|
+
return maybeFn instanceof Function ? maybeFn() : maybeFn;
|
|
768
|
+
}
|
|
769
|
+
function flatten(values) {
|
|
770
|
+
const out = [];
|
|
771
|
+
values.forEach(value => {
|
|
772
|
+
if (Array.isArray(value)) {
|
|
773
|
+
out.push(...flatten(value));
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
out.push(value);
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
return out;
|
|
780
|
+
}
|
|
781
|
+
function identityFn(value) {
|
|
782
|
+
return value;
|
|
783
|
+
}
|
|
784
|
+
function flattenProviders(providers, mapFn = identityFn) {
|
|
785
|
+
const out = [];
|
|
786
|
+
for (let provider of providers) {
|
|
787
|
+
if (isEnvironmentProviders(provider)) {
|
|
788
|
+
provider = provider.ɵproviders;
|
|
789
|
+
}
|
|
790
|
+
if (Array.isArray(provider)) {
|
|
791
|
+
out.push(...flattenProviders(provider, mapFn));
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
out.push(mapFn(provider));
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return out;
|
|
798
|
+
}
|
|
799
|
+
function getProviderField(provider, field) {
|
|
800
|
+
return provider && typeof provider === 'object' && provider[field];
|
|
801
|
+
}
|
|
802
|
+
function getProviderToken(provider) {
|
|
803
|
+
return getProviderField(provider, 'provide') || provider;
|
|
804
|
+
}
|
|
805
|
+
function isModuleWithProviders(value) {
|
|
806
|
+
return value.hasOwnProperty('ngModule');
|
|
807
|
+
}
|
|
808
|
+
function forEachRight(values, fn) {
|
|
809
|
+
for (let idx = values.length - 1; idx >= 0; idx--) {
|
|
810
|
+
fn(values[idx], idx);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
function invalidTypeError(name, expectedType) {
|
|
814
|
+
return new Error(`${name} class doesn't have @${expectedType} decorator or is missing metadata.`);
|
|
815
|
+
}
|
|
816
|
+
class R3TestCompiler {
|
|
817
|
+
constructor(testBed) {
|
|
818
|
+
this.testBed = testBed;
|
|
819
|
+
}
|
|
820
|
+
compileModuleSync(moduleType) {
|
|
821
|
+
this.testBed._compileNgModuleSync(moduleType);
|
|
822
|
+
return new R3NgModuleFactory(moduleType);
|
|
823
|
+
}
|
|
824
|
+
async compileModuleAsync(moduleType) {
|
|
825
|
+
await this.testBed._compileNgModuleAsync(moduleType);
|
|
826
|
+
return new R3NgModuleFactory(moduleType);
|
|
827
|
+
}
|
|
828
|
+
compileModuleAndAllComponentsSync(moduleType) {
|
|
829
|
+
const ngModuleFactory = this.compileModuleSync(moduleType);
|
|
830
|
+
const componentFactories = this.testBed._getComponentFactories(moduleType);
|
|
831
|
+
return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
|
|
832
|
+
}
|
|
833
|
+
async compileModuleAndAllComponentsAsync(moduleType) {
|
|
834
|
+
const ngModuleFactory = await this.compileModuleAsync(moduleType);
|
|
835
|
+
const componentFactories = this.testBed._getComponentFactories(moduleType);
|
|
836
|
+
return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
|
|
837
|
+
}
|
|
838
|
+
clearCache() { }
|
|
839
|
+
clearCacheFor(type) { }
|
|
840
|
+
getModuleId(moduleType) {
|
|
841
|
+
const meta = this.testBed._getModuleResolver().resolve(moduleType);
|
|
842
|
+
return meta && meta.id || undefined;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9iZWRfY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3Rlc3Rpbmcvc3JjL3Rlc3RfYmVkX2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFnRCxTQUFTLEVBQUUsNEJBQTRCLEVBQXVGLDBCQUEwQixFQUFFLGlCQUFpQixFQUFRLGlCQUFpQixJQUFJLGdCQUFnQixFQUFFLGlCQUFpQixJQUFJLGdCQUFnQixFQUFFLG9CQUFvQixJQUFJLG1CQUFtQixFQUFFLFlBQVksSUFBSSxXQUFXLEVBQUUsa0JBQWtCLElBQUksaUJBQWlCLEVBQWlDLGlCQUFpQixJQUFJLGdCQUFnQixFQUFpRSx1QkFBdUIsSUFBSSxzQkFBc0IsRUFBRSxZQUFZLElBQUksV0FBVyxFQUFFLFdBQVcsSUFBSSxVQUFVLEVBQUUsV0FBVyxJQUFJLFVBQVUsRUFBRSxXQUFXLElBQUksVUFBVSxFQUFFLFlBQVksSUFBSSxXQUFXLEVBQUUsZ0JBQWdCLElBQUksaUJBQWlCLEVBQXdGLDJCQUEyQixJQUFJLDBCQUEwQixFQUFFLHdCQUF3QixJQUFJLGdCQUFnQixFQUFFLG1CQUFtQixJQUFJLFdBQVcsRUFBRSxZQUFZLElBQUksV0FBVyxFQUFFLG9CQUFvQixJQUFJLG1CQUFtQixFQUFtRCxNQUFNLGVBQWUsQ0FBQztBQUUzckMsT0FBTyxFQUFDLHdDQUF3QyxFQUFFLCtCQUErQixFQUFFLHlCQUF5QixFQUFFLCtCQUErQixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFFMUwsT0FBTyxFQUFDLHFDQUFxQyxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFHbkYsT0FBTyxFQUFDLGlCQUFpQixFQUFFLGlCQUFp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XG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtSZXNvdXJjZUxvYWRlcn0gZnJvbSAnQGFuZ3VsYXIvY29tcGlsZXInO1xuaW1wb3J0IHtBcHBsaWNhdGlvbkluaXRTdGF0dXMsIENvbXBpbGVyLCBDT01QSUxFUl9PUFRJT05TLCBDb21wb25lbnQsIERpcmVjdGl2ZSwgSW5qZWN0b3IsIEluamVjdG9yVHlwZSwgTE9DQUxFX0lELCBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzLCBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSwgTmdNb2R1bGVGYWN0b3J5LCBOZ1pvbmUsIFBpcGUsIFBsYXRmb3JtUmVmLCBQcm92aWRlciwgcHJvdmlkZVpvbmVDaGFuZ2VEZXRlY3Rpb24sIHJlc29sdmVGb3J3YXJkUmVmLCBUeXBlLCDJtWNvbXBpbGVDb21wb25lbnQgYXMgY29tcGlsZUNvbXBvbmVudCwgybVjb21waWxlRGlyZWN0aXZlIGFzIGNvbXBpbGVEaXJlY3RpdmUsIMm1Y29tcGlsZU5nTW9kdWxlRGVmcyBhcyBjb21waWxlTmdNb2R1bGVEZWZzLCDJtWNvbXBpbGVQaXBlIGFzIGNvbXBpbGVQaXBlLCDJtURFRkFVTFRfTE9DQUxFX0lEIGFzIERFRkFVTFRfTE9DQUxFX0lELCDJtURpcmVjdGl2ZURlZiBhcyBEaXJlY3RpdmVEZWYsIMm1Z2V0SW5qZWN0YWJsZURlZiBhcyBnZXRJbmplY3RhYmxlRGVmLCDJtUludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnMgYXMgSW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycywgybVpc0Vudmlyb25tZW50UHJvdmlkZXJzIGFzIGlzRW52aXJvbm1lbnRQcm92aWRlcnMsIMm1TkdfQ09NUF9ERUYgYXMgTkdfQ09NUF9ERUYsIMm1TkdfRElSX0RFRiBhcyBOR19ESVJfREVGLCDJtU5HX0lOSl9ERUYgYXMgTkdfSU5KX0RFRiwgybVOR19NT0RfREVGIGFzIE5HX01PRF9ERUYsIMm1TkdfUElQRV9ERUYgYXMgTkdfUElQRV9ERUYsIMm1TmdNb2R1bGVGYWN0b3J5IGFzIFIzTmdNb2R1bGVGYWN0b3J5LCDJtU5nTW9kdWxlVHJhbnNpdGl2ZVNjb3BlcyBhcyBOZ01vZHVsZVRyYW5zaXRpdmVTY29wZXMsIMm1TmdNb2R1bGVUeXBlIGFzIE5nTW9kdWxlVHlwZSwgybVwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSBhcyBwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSwgybVSZW5kZXIzQ29tcG9uZW50RmFjdG9yeSBhcyBDb21wb25lbnRGYWN0b3J5LCDJtVJlbmRlcjNOZ01vZHVsZVJlZiBhcyBOZ01vZHVsZVJlZiwgybVzZXRMb2NhbGVJZCBhcyBzZXRMb2NhbGVJZCwgybV0cmFuc2l0aXZlU2NvcGVzRm9yIGFzIHRyYW5zaXRpdmVTY29wZXNGb3IsIMm1ybVJbmplY3RhYmxlRGVjbGFyYXRpb24gYXMgSW5qZWN0YWJsZURlY2xhcmF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlLCBpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uLCByZXNvbHZlQ29tcG9uZW50UmVzb3VyY2VzLCByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlfSBmcm9tICcuLi8uLi9zcmMvbWV0YWRhdGEvcmVzb3VyY2VfbG9hZGluZyc7XG5pbXBvcnQge0NvbXBvbmVudERlZiwgQ29tcG9uZW50VHlwZX0gZnJvbSAnLi4vLi4vc3JjL3JlbmRlcjMnO1xuaW1wb3J0IHtnZW5lcmF0ZVN0YW5kYWxvbmVJbkRlY2xhcmF0aW9uc0Vycm9yfSBmcm9tICcuLi8uLi9zcmMvcmVuZGVyMy9qaXQvbW9kdWxlJztcblxuaW1wb3J0IHtNZXRhZGF0YU92ZXJyaWRlfSBmcm9tICcuL21ldGFkYXRhX292ZXJyaWRlJztcbmltcG9ydCB7Q29tcG9uZW50UmVzb2x2ZXIsIERpcmVjdGl2ZVJlc29sdmVyLCBOZ01vZHVsZVJlc29sdmVyLCBQaXBlUmVzb2x2ZXIsIFJlc29sdmVyfSBmcm9tICcuL3Jlc29sdmVycyc7XG5pbXBvcnQge1Rlc3RNb2R1bGVNZXRhZGF0YX0gZnJvbSAnLi90ZXN0X2JlZF9jb21tb24nO1xuXG5lbnVtIFRlc3RpbmdNb2R1bGVPdmVycmlkZSB7XG4gIERFQ0xBUkFUSU9OLFxuICBPVkVSUklERV9URU1QTEFURSxcbn1cblxuZnVuY3Rpb24gaXNUZXN0aW5nTW9kdWxlT3ZlcnJpZGUodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUge1xuICByZXR1cm4gdmFsdWUgPT09IFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTiB8fFxuICAgICAgdmFsdWUgPT09IFRlc3RpbmdNb2R1bGVPdmVycmlkZS5PVkVSUklERV9URU1QTEFURTtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0Tm9TdGFuZGFsb25lQ29tcG9uZW50cyhcbiAgICB0eXBlczogVHlwZTxhbnk+W10sIHJlc29sdmVyOiBSZXNvbHZlcjxhbnk+LCBsb2NhdGlvbjogc3RyaW5nKSB7XG4gIHR5cGVzLmZvckVhY2godHlwZSA9PiB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gcmVzb2x2ZXIucmVzb2x2ZSh0eXBlKTtcbiAgICBpZiAoY29tcG9uZW50ICYmIGNvbXBvbmVudC5zdGFuZGFsb25lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZ2VuZXJhdGVTdGFuZGFsb25lSW5EZWNsYXJhdGlvbnNFcnJvcih0eXBlLCBsb2NhdGlvbikpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIFJlc29sdmVycyBmb3IgQW5ndWxhciBkZWNvcmF0b3JzXG50eXBlIFJlc29sdmVycyA9IHtcbiAgbW9kdWxlOiBSZXNvbHZlcjxOZ01vZHVsZT4sXG4gIGNvbXBvbmVudDogUmVzb2x2ZXI8RGlyZWN0aXZlPixcbiAgZGlyZWN0aXZlOiBSZXNvbHZlcjxDb21wb25lbnQ+LFxuICBwaXBlOiBSZXNvbHZlcjxQaXBlPixcbn07XG5cbmludGVyZmFjZSBDbGVhbnVwT3BlcmF0aW9uIHtcbiAgZmllbGROYW1lOiBzdHJpbmc7XG4gIG9iamVjdDogYW55O1xuICBvcmlnaW5hbFZhbHVlOiB1bmtub3duO1xufVxuXG5leHBvcnQgY2xhc3MgVGVzdEJlZENvbXBpbGVyIHtcbiAgcHJpdmF0ZSBvcmlnaW5hbENvbXBvbmVudFJlc29sdXRpb25RdWV1ZTogTWFwPFR5cGU8YW55PiwgQ29tcG9uZW50PnxudWxsID0gbnVsbDtcblxuICAvLyBUZXN0aW5nIG1vZHVsZSBjb25maWd1cmF0aW9uXG4gIHByaXZhdGUgZGVjbGFyYXRpb25zOiBUeXBlPGFueT5bXSA9IFtdO1xuICBwcml2YXRlIGltcG9ydHM6IFR5cGU8YW55PltdID0gW107XG4gIHByaXZhdGUgcHJvdmlkZXJzOiBQcm92aWRlcltdID0gW107XG4gIHByaXZhdGUgc2NoZW1hczogYW55W10gPSBbXTtcblxuICAvLyBRdWV1ZXMgb2YgY29tcG9uZW50cy9kaXJlY3RpdmVzL3BpcGVzIHRoYXQgc2hvdWxkIGJlIHJlY29tcGlsZWQuXG4gIHByaXZhdGUgcGVuZGluZ0NvbXBvbmVudHMgPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcbiAgcHJpdmF0ZSBwZW5kaW5nRGlyZWN0aXZlcyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuICBwcml2YXRlIHBlbmRpbmdQaXBlcyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuXG4gIC8vIEtlZXAgdHJhY2sgb2YgYWxsIGNvbXBvbmVudHMgYW5kIGRpcmVjdGl2ZXMsIHNvIHdlIGNhbiBwYXRjaCBQcm92aWRlcnMgb250byBkZWZzIGxhdGVyLlxuICBwcml2YXRlIHNlZW5Db21wb25lbnRzID0gbmV3IFNldDxUeXBlPGFueT4+KCk7XG4gIHByaXZhdGUgc2VlbkRpcmVjdGl2ZXMgPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcblxuICAvLyBLZWVwIHRyYWNrIG9mIG92ZXJyaWRkZW4gbW9kdWxlcywgc28gdGhhdCB3ZSBjYW4gY29sbGVjdCBhbGwgYWZmZWN0ZWQgb25lcyBpbiB0aGUgbW9kdWxlIHRyZWUuXG4gIHByaXZhdGUgb3ZlcnJpZGRlbk1vZHVsZXMgPSBuZXcgU2V0PE5nTW9kdWxlVHlwZTxhbnk+PigpO1xuXG4gIC8vIFN0b3JlIHJlc29sdmVkIHN0eWxlcyBmb3IgQ29tcG9uZW50cyB0aGF0IGhhdmUgdGVtcGxhdGUgb3ZlcnJpZGVzIHByZXNlbnQgYW5kIGBzdHlsZVVybHNgXG4gIC8vIGRlZmluZWQgYXQgdGhlIHNhbWUgdGltZS5cbiAgcHJpdmF0ZSBleGlzdGluZ0NvbXBvbmVudFN0eWxlcyA9IG5ldyBNYXA8VHlwZTxhbnk+LCBzdHJpbmdbXT4oKTtcblxuICBwcml2YXRlIHJlc29sdmVyczogUmVzb2x2ZXJzID0gaW5pdFJlc29sdmVycygpO1xuXG4gIHByaXZhdGUgY29tcG9uZW50VG9Nb2R1bGVTY29wZSA9IG5ldyBNYXA8VHlwZTxhbnk+LCBUeXBlPGFueT58VGVzdGluZ01vZHVsZU92ZXJyaWRlPigpO1xuXG4gIC8vIE1hcCB0aGF0IGtlZXBzIGluaXRpYWwgdmVyc2lvbiBvZiBjb21wb25lbnQvZGlyZWN0aXZlL3BpcGUgZGVmcyBpbiBjYXNlXG4gIC8vIHdlIGNvbXBpbGUgYSBUeXBlIGFnYWluLCB0aHVzIG92ZXJyaWRpbmcgcmVzcGVjdGl2ZSBzdGF0aWMgZmllbGRzLiBUaGlzIGlzXG4gIC8vIHJlcXVpcmVkIHRvIG1ha2Ugc3VyZSB3ZSByZXN0b3JlIGRlZnMgdG8gdGhlaXIgaW5pdGlhbCBzdGF0ZXMgYmV0d2VlbiB0ZXN0IHJ1bnMuXG4gIC8vIE5vdGU6IG9uZSBjbGFzcyBtYXkgaGF2ZSBtdWx0aXBsZSBkZWZzIChmb3IgZXhhbXBsZTogybVtb2QgYW5kIMm1aW5qIGluIGNhc2Ugb2YgYW5cbiAgLy8gTmdNb2R1bGUpLCBzdG9yZSBhbGwgb2YgdGhlbSBpbiBhIG1hcC5cbiAgcHJpdmF0ZSBpbml0aWFsTmdEZWZzID0gbmV3IE1hcDxUeXBlPGFueT4sIE1hcDxzdHJpbmcsIFByb3BlcnR5RGVzY3JpcHRvcnx1bmRlZmluZWQ+PigpO1xuXG4gIC8vIEFycmF5IHRoYXQga2VlcHMgY2xlYW51cCBvcGVyYXRpb25zIGZvciBpbml0aWFsIHZlcnNpb25zIG9mIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZS9tb2R1bGVcbiAgLy8gZGVmcyBpbiBjYXNlIFRlc3RCZWQgbWFrZXMgY2hhbmdlcyB0byB0aGUgb3JpZ2luYWxzLlxuICBwcml2YXRlIGRlZkNsZWFudXBPcHM6IENsZWFudXBPcGVyYXRpb25bXSA9IFtdO1xuXG4gIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3RvcnxudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb21waWxlclByb3ZpZGVyczogUHJvdmlkZXJbXXxudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHByb3ZpZGVyT3ZlcnJpZGVzOiBQcm92aWRlcltdID0gW107XG4gIHByaXZhdGUgcm9vdFByb3ZpZGVyT3ZlcnJpZGVzOiBQcm92aWRlcltdID0gW107XG4gIC8vIE92ZXJyaWRlcyBmb3IgaW5qZWN0YWJsZXMgd2l0aCBge3Byb3ZpZGVkSW46IFNvbWVNb2R1bGV9YCBuZWVkIHRvIGJlIHRyYWNrZWQgYW5kIGFkZGVkIHRvIHRoYXRcbiAgLy8gbW9kdWxlJ3MgcHJvdmlkZXIgbGlzdC5cbiAgcHJpdmF0ZSBwcm92aWRlck92ZXJyaWRlc0J5TW9kdWxlID0gbmV3IE1hcDxJbmplY3RvclR5cGU8YW55PiwgUHJvdmlkZXJbXT4oKTtcbiAgcHJpdmF0ZSBwcm92aWRlck92ZXJyaWRlc0J5VG9rZW4gPSBuZXcgTWFwPGFueSwgUHJvdmlkZXI+KCk7XG4gIHByaXZhdGUgc2NvcGVzV2l0aE92ZXJyaWRkZW5Qcm92aWRlcnMgPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcblxuICBwcml2YXRlIHRlc3RNb2R1bGVUeXBlOiBOZ01vZHVsZVR5cGU8YW55PjtcbiAgcHJpdmF0ZSB0ZXN0TW9kdWxlUmVmOiBOZ01vZHVsZVJlZjxhbnk+fG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtUmVmLCBwcml2YXRlIGFkZGl0aW9uYWxNb2R1bGVUeXBlczogVHlwZTxhbnk+fFR5cGU8YW55PltdKSB7XG4gICAgY2xhc3MgRHluYW1pY1Rlc3RNb2R1bGUge31cbiAgICB0aGlzLnRlc3RNb2R1bGVUeXBlID0gRHluYW1pY1Rlc3RNb2R1bGUgYXMgYW55O1xuICB9XG5cbiAgc2V0Q29tcGlsZXJQcm92aWRlcnMocHJvdmlkZXJzOiBQcm92aWRlcltdfG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBpbGVyUHJvdmlkZXJzID0gcHJvdmlkZXJzO1xuICAgIHRoaXMuX2luamVjdG9yID0gbnVsbDtcbiAgfVxuXG4gIGNvbmZpZ3VyZVRlc3RpbmdNb2R1bGUobW9kdWxlRGVmOiBUZXN0TW9kdWxlTWV0YWRhdGEpOiB2b2lkIHtcbiAgICAvLyBFbnF1ZXVlIGFueSBjb21waWxhdGlvbiB0YXNrcyBmb3IgdGhlIGRpcmVjdGx5IGRlY2xhcmVkIGNvbXBvbmVudC5cbiAgICBpZiAobW9kdWxlRGVmLmRlY2xhcmF0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBWZXJpZnkgdGhhdCB0aGVyZSBhcmUgbm8gc3RhbmRhbG9uZSBjb21wb25lbnRzXG4gICAgICBhc3NlcnROb1N0YW5kYWxvbmVDb21wb25lbnRzKFxuICAgICAgICAgIG1vZHVsZURlZi5kZWNsYXJhdGlvbnMsIHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudCxcbiAgICAgICAgICAnXCJUZXN0QmVkLmNvbmZpZ3VyZVRlc3RpbmdNb2R1bGVcIiBjYWxsJyk7XG4gICAgICB0aGlzLnF1ZXVlVHlwZUFycmF5KG1vZHVsZURlZi5kZWNsYXJhdGlvbnMsIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTik7XG4gICAgICB0aGlzLmRlY2xhcmF0aW9ucy5wdXNoKC4uLm1vZHVsZURlZi5kZWNsYXJhdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIEVucXVldWUgYW55IGNvbXBpbGF0aW9uIHRhc2tzIGZvciBpbXBvcnRlZCBtb2R1bGVzLlxuICAgIGlmIChtb2R1bGVEZWYuaW1wb3J0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5KG1vZHVsZURlZi5pbXBvcnRzKTtcbiAgICAgIHRoaXMuaW1wb3J0cy5wdXNoKC4uLm1vZHVsZURlZi5pbXBvcnRzKTtcbiAgICB9XG5cbiAgICBpZiAobW9kdWxlRGVmLnByb3ZpZGVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnByb3ZpZGVycy5wdXNoKC4uLm1vZHVsZURlZi5wcm92aWRlcnMpO1xuICAgIH1cblxuICAgIGlmIChtb2R1bGVEZWYuc2NoZW1hcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNjaGVtYXMucHVzaCguLi5tb2R1bGVEZWYuc2NoZW1hcyk7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGVNb2R1bGUobmdNb2R1bGU6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8TmdNb2R1bGU+KTogdm9pZCB7XG4gICAgdGhpcy5vdmVycmlkZGVuTW9kdWxlcy5hZGQobmdNb2R1bGUgYXMgTmdNb2R1bGVUeXBlPGFueT4pO1xuXG4gICAgLy8gQ29tcGlsZSB0aGUgbW9kdWxlIHJpZ2h0IGF3YXkuXG4gICAgdGhpcy5yZXNvbHZlcnMubW9kdWxlLmFkZE92ZXJyaWRlKG5nTW9kdWxlLCBvdmVycmlkZSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5tb2R1bGUucmVzb2x2ZShuZ01vZHVsZSk7XG4gICAgaWYgKG1ldGFkYXRhID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkVHlwZUVycm9yKG5nTW9kdWxlLm5hbWUsICdOZ01vZHVsZScpO1xuICAgIH1cblxuICAgIHRoaXMucmVjb21waWxlTmdNb2R1bGUobmdNb2R1bGUsIG1ldGFkYXRhKTtcblxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSBtb2R1bGUgaGFzIGEgdmFsaWQgbW9kdWxlIGRlZiAoybVtb2QpLCBidXQgdGhlIG92ZXJyaWRlIG1heSBoYXZlIGludHJvZHVjZWRcbiAgICAvLyBuZXcgZGVjbGFyYXRpb25zIG9yIGltcG9ydGVkIG1vZHVsZXMuIEluZ2VzdCBhbnkgcG9zc2libGUgbmV3IHR5cGVzIGFuZCBhZGQgdGhlbSB0byB0aGVcbiAgICAvLyBjdXJyZW50IHF1ZXVlLlxuICAgIHRoaXMucXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXkoW25nTW9kdWxlXSk7XG4gIH1cblxuICBvdmVycmlkZUNvbXBvbmVudChjb21wb25lbnQ6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8Q29tcG9uZW50Pik6IHZvaWQge1xuICAgIHRoaXMudmVyaWZ5Tm9TdGFuZGFsb25lRmxhZ092ZXJyaWRlcyhjb21wb25lbnQsIG92ZXJyaWRlKTtcbiAgICB0aGlzLnJlc29sdmVycy5jb21wb25lbnQuYWRkT3ZlcnJpZGUoY29tcG9uZW50LCBvdmVycmlkZSk7XG4gICAgdGhpcy5wZW5kaW5nQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTtcbiAgfVxuXG4gIG92ZXJyaWRlRGlyZWN0aXZlKGRpcmVjdGl2ZTogVHlwZTxhbnk+LCBvdmVycmlkZTogTWV0YWRhdGFPdmVycmlkZTxEaXJlY3RpdmU+KTogdm9pZCB7XG4gICAgdGhpcy52ZXJpZnlOb1N0YW5kYWxvbmVGbGFnT3ZlcnJpZGVzKGRpcmVjdGl2ZSwgb3ZlcnJpZGUpO1xuICAgIHRoaXMucmVzb2x2ZXJzLmRpcmVjdGl2ZS5hZGRPdmVycmlkZShkaXJlY3RpdmUsIG92ZXJyaWRlKTtcbiAgICB0aGlzLnBlbmRpbmdEaXJlY3RpdmVzLmFkZChkaXJlY3RpdmUpO1xuICB9XG5cbiAgb3ZlcnJpZGVQaXBlKHBpcGU6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8UGlwZT4pOiB2b2lkIHtcbiAgICB0aGlzLnZlcmlmeU5vU3RhbmRhbG9uZUZsYWdPdmVycmlkZXMocGlwZSwgb3ZlcnJpZGUpO1xuICAgIHRoaXMucmVzb2x2ZXJzLnBpcGUuYWRkT3ZlcnJpZGUocGlwZSwgb3ZlcnJpZGUpO1xuICAgIHRoaXMucGVuZGluZ1BpcGVzLmFkZChwaXBlKTtcbiAgfVxuXG4gIHByaXZhdGUgdmVyaWZ5Tm9TdGFuZGFsb25lRmxhZ092ZXJyaWRlcyhcbiAgICAgIHR5cGU6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8Q29tcG9uZW50fERpcmVjdGl2ZXxQaXBlPikge1xuICAgIGlmIChvdmVycmlkZS5hZGQ/Lmhhc093blByb3BlcnR5KCdzdGFuZGFsb25lJykgfHwgb3ZlcnJpZGUuc2V0Py5oYXNPd25Qcm9wZXJ0eSgnc3RhbmRhbG9uZScpIHx8XG4gICAgICAgIG92ZXJyaWRlLnJlbW92ZT8uaGFzT3duUHJvcGVydHkoJ3N0YW5kYWxvbmUnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBBbiBvdmVycmlkZSBmb3IgdGhlICR7dHlwZS5uYW1lfSBjbGFzcyBoYXMgdGhlIFxcYHN0YW5kYWxvbmVcXGAgZmxhZy4gYCArXG4gICAgICAgICAgYENoYW5naW5nIHRoZSBcXGBzdGFuZGFsb25lXFxgIGZsYWcgdmlhIFRlc3RCZWQgb3ZlcnJpZGVzIGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGVQcm92aWRlcihcbiAgICAgIHRva2VuOiBhbnksXG4gICAgICBwcm92aWRlcjoge3VzZUZhY3Rvcnk/OiBGdW5jdGlvbiwgdXNlVmFsdWU/OiBhbnksIGRlcHM/OiBhbnlbXSwgbXVsdGk/OiBib29sZWFufSk6IHZvaWQge1xuICAgIGxldCBwcm92aWRlckRlZjogUHJvdmlkZXI7XG4gICAgaWYgKHByb3ZpZGVyLnVzZUZhY3RvcnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcHJvdmlkZXJEZWYgPSB7XG4gICAgICAgIHByb3ZpZGU6IHRva2VuLFxuICAgICAgICB1c2VGYWN0b3J5OiBwcm92aWRlci51c2VGYWN0b3J5LFxuICAgICAgICBkZXBzOiBwcm92aWRlci5kZXBzIHx8IFtdLFxuICAgICAgICBtdWx0aTogcHJvdmlkZXIubXVsdGlcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChwcm92aWRlci51c2VWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm92aWRlckRlZiA9IHtwcm92aWRlOiB0b2tlbiwgdXNlVmFsdWU6IHByb3ZpZGVyLnVzZVZhbHVlLCBtdWx0aTogcHJvdmlkZXIubXVsdGl9O1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm92aWRlckRlZiA9IHtwcm92aWRlOiB0b2tlbn07XG4gICAgfVxuXG4gICAgY29uc3QgaW5qZWN0YWJsZURlZjogSW5qZWN0YWJsZURlY2xhcmF0aW9uPGFueT58bnVsbCA9XG4gICAgICAgIHR5cGVvZiB0b2tlbiAhPT0gJ3N0cmluZycgPyBnZXRJbmplY3RhYmxlRGVmKHRva2VuKSA6IG51bGw7XG4gICAgY29uc3QgcHJvdmlkZWRJbiA9IGluamVjdGFibGVEZWYgPT09IG51bGwgPyBudWxsIDogcmVzb2x2ZUZvcndhcmRSZWYoaW5qZWN0YWJsZURlZi5wcm92aWRlZEluKTtcbiAgICBjb25zdCBvdmVycmlkZXNCdWNrZXQgPVxuICAgICAgICBwcm92aWRlZEluID09PSAncm9vdCcgPyB0aGlzLnJvb3RQcm92aWRlck92ZXJyaWRlcyA6IHRoaXMucHJvdmlkZXJPdmVycmlkZXM7XG4gICAgb3ZlcnJpZGVzQnVja2V0LnB1c2gocHJvdmlkZXJEZWYpO1xuXG4gICAgLy8gS2VlcCBvdmVycmlkZXMgZ3JvdXBlZCBieSB0b2tlbiBhcyB3ZWxsIGZvciBmYXN0IGxvb2t1cHMgdXNpbmcgdG9rZW5cbiAgICB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zZXQodG9rZW4sIHByb3ZpZGVyRGVmKTtcbiAgICBpZiAoaW5qZWN0YWJsZURlZiAhPT0gbnVsbCAmJiBwcm92aWRlZEluICE9PSBudWxsICYmIHR5cGVvZiBwcm92aWRlZEluICE9PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZXhpc3RpbmdPdmVycmlkZXMgPSB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlNb2R1bGUuZ2V0KHByb3ZpZGVkSW4pO1xuICAgICAgaWYgKGV4aXN0aW5nT3ZlcnJpZGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhpc3RpbmdPdmVycmlkZXMucHVzaChwcm92aWRlckRlZik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlNb2R1bGUuc2V0KHByb3ZpZGVkSW4sIFtwcm92aWRlckRlZl0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlVGVtcGxhdGVVc2luZ1Rlc3RpbmdNb2R1bGUodHlwZTogVHlwZTxhbnk+LCB0ZW1wbGF0ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZGVmID0gKHR5cGUgYXMgYW55KVtOR19DT01QX0RFRl07XG4gICAgY29uc3QgaGFzU3R5bGVVcmxzID0gKCk6IGJvb2xlYW4gPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5jb21wb25lbnQucmVzb2x2ZSh0eXBlKSEgYXMgQ29tcG9uZW50O1xuICAgICAgcmV0dXJuICEhbWV0YWRhdGEuc3R5bGVVcmxzICYmIG1ldGFkYXRhLnN0eWxlVXJscy5sZW5ndGggPiAwO1xuICAgIH07XG4gICAgY29uc3Qgb3ZlcnJpZGVTdHlsZVVybHMgPSAhIWRlZiAmJiAhaXNDb21wb25lbnREZWZQZW5kaW5nUmVzb2x1dGlvbih0eXBlKSAmJiBoYXNTdHlsZVVybHMoKTtcblxuICAgIC8vIEluIEl2eSwgY29tcGlsaW5nIGEgY29tcG9uZW50IGRvZXMgbm90IHJlcXVpcmUga25vd2luZyB0aGUgbW9kdWxlIHByb3ZpZGluZyB0aGVcbiAgICAvLyBjb21wb25lbnQncyBzY29wZSwgc28gb3ZlcnJpZGVUZW1wbGF0ZVVzaW5nVGVzdGluZ01vZHVsZSBjYW4gYmUgaW1wbGVtZW50ZWQgcHVyZWx5IHZpYVxuICAgIC8vIG92ZXJyaWRlQ29tcG9uZW50LiBJbXBvcnRhbnQ6IG92ZXJyaWRpbmcgdGVtcGxhdGUgcmVxdWlyZXMgZnVsbCBDb21wb25lbnQgcmUtY29tcGlsYXRpb24sXG4gICAgLy8gd2hpY2ggbWF5IGZhaWwgaW4gY2FzZSBzdHlsZVVybHMgYXJlIGFsc28gcHJlc2VudCAodGh1cyBDb21wb25lbnQgaXMgY29uc2lkZXJlZCBhcyByZXF1aXJlZFxuICAgIC8vIHJlc29sdXRpb24pLiBJbiBvcmRlciB0byBhdm9pZCB0aGlzLCB3ZSBwcmVlbXB0aXZlbHkgc2V0IHN0eWxlVXJscyB0byBhbiBlbXB0eSBhcnJheSxcbiAgICAvLyBwcmVzZXJ2ZSBjdXJyZW50IHN0eWxlcyBhdmFpbGFibGUgb24gQ29tcG9uZW50IGRlZiBhbmQgcmVzdG9yZSBzdHlsZXMgYmFjayBvbmNlIGNvbXBpbGF0aW9uXG4gICAgLy8gaXMgY29tcGxldGUuXG4gICAgY29uc3Qgb3ZlcnJpZGUgPSBvdmVycmlkZVN0eWxlVXJscyA/IHt0ZW1wbGF0ZSwgc3R5bGVzOiBbXSwgc3R5bGVVcmxzOiBbXX0gOiB7dGVtcGxhdGV9O1xuICAgIHRoaXMub3ZlcnJpZGVDb21wb25lbnQodHlwZSwge3NldDogb3ZlcnJpZGV9KTtcblxuICAgIGlmIChvdmVycmlkZVN0eWxlVXJscyAmJiBkZWYuc3R5bGVzICYmIGRlZi5zdHlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leGlzdGluZ0NvbXBvbmVudFN0eWxlcy5zZXQodHlwZSwgZGVmLnN0eWxlcyk7XG4gICAgfVxuXG4gICAgLy8gU2V0IHRoZSBjb21wb25lbnQncyBzY29wZSB0byBiZSB0aGUgdGVzdGluZyBtb2R1bGUuXG4gICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLnNldCh0eXBlLCBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuT1ZFUlJJREVfVEVNUExBVEUpO1xuICB9XG5cbiAgYXN5bmMgY29tcGlsZUNvbXBvbmVudHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jbGVhckNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSgpO1xuICAgIC8vIFJ1biBjb21waWxlcnMgZm9yIGFsbCBxdWV1ZWQgdHlwZXMuXG4gICAgbGV0IG5lZWRzQXN5bmNSZXNvdXJjZXMgPSB0aGlzLmNvbXBpbGVUeXBlc1N5bmMoKTtcblxuICAgIC8vIGNvbXBpbGVDb21wb25lbnRzKCkgc2hvdWxkIG5vdCBiZSBhc3luYyB1bmxlc3MgaXQgbmVlZHMgdG8gYmUuXG4gICAgaWYgKG5lZWRzQXN5bmNSZXNvdXJjZXMpIHtcbiAgICAgIGxldCByZXNvdXJjZUxvYWRlcjogUmVzb3VyY2VMb2FkZXI7XG4gICAgICBsZXQgcmVzb2x2ZXIgPSAodXJsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICBpZiAoIXJlc291cmNlTG9hZGVyKSB7XG4gICAgICAgICAgcmVzb3VyY2VMb2FkZXIgPSB0aGlzLmluamVjdG9yLmdldChSZXNvdXJjZUxvYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNvdXJjZUxvYWRlci5nZXQodXJsKSk7XG4gICAgICB9O1xuICAgICAgYXdhaXQgcmVzb2x2ZUNvbXBvbmVudFJlc291cmNlcyhyZXNvbHZlcik7XG4gICAgfVxuICB9XG5cbiAgZmluYWxpemUoKTogTmdNb2R1bGVSZWY8YW55PiB7XG4gICAgLy8gT25lIGxhc3QgY29tcGlsZVxuICAgIHRoaXMuY29tcGlsZVR5cGVzU3luYygpO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIG1vZHVsZSBpdHNlbGYuXG4gICAgdGhpcy5jb21waWxlVGVzdE1vZHVsZSgpO1xuXG4gICAgdGhpcy5hcHBseVRyYW5zaXRpdmVTY29wZXMoKTtcblxuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlcygpO1xuXG4gICAgLy8gUGF0Y2ggcHJldmlvdXNseSBzdG9yZWQgYHN0eWxlc2AgQ29tcG9uZW50IHZhbHVlcyAodGFrZW4gZnJvbSDJtWNtcCksIGluIGNhc2UgdGhlc2VcbiAgICAvLyBDb21wb25lbnRzIGhhdmUgYHN0eWxlVXJsc2AgZmllbGRzIGRlZmluZWQgYW5kIHRlbXBsYXRlIG92ZXJyaWRlIHdhcyByZXF1ZXN0ZWQuXG4gICAgdGhpcy5wYXRjaENvbXBvbmVudHNXaXRoRXhpc3RpbmdTdHlsZXMoKTtcblxuICAgIC8vIENsZWFyIHRoZSBjb21wb25lbnRUb01vZHVsZVNjb3BlIG1hcCwgc28gdGhhdCBmdXR1cmUgY29tcGlsYXRpb25zIGRvbid0IHJlc2V0IHRoZSBzY29wZSBvZlxuICAgIC8vIGV2ZXJ5IGNvbXBvbmVudC5cbiAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuY2xlYXIoKTtcblxuICAgIGNvbnN0IHBhcmVudEluamVjdG9yID0gdGhpcy5wbGF0Zm9ybS5pbmplY3RvcjtcbiAgICB0aGlzLnRlc3RNb2R1bGVSZWYgPSBuZXcgTmdNb2R1bGVSZWYodGhpcy50ZXN0TW9kdWxlVHlwZSwgcGFyZW50SW5qZWN0b3IsIFtdKTtcblxuICAgIC8vIEFwcGxpY2F0aW9uSW5pdFN0YXR1cy5ydW5Jbml0aWFsaXplcnMoKSBpcyBtYXJrZWQgQGludGVybmFsIHRvIGNvcmUuXG4gICAgLy8gQ2FzdCBpdCB0byBhbnkgYmVmb3JlIGFjY2Vzc2luZyBpdC5cbiAgICAodGhpcy50ZXN0TW9kdWxlUmVmLmluamVjdG9yLmdldChBcHBsaWNhdGlvbkluaXRTdGF0dXMpIGFzIGFueSkucnVuSW5pdGlhbGl6ZXJzKCk7XG5cbiAgICAvLyBTZXQgbG9jYWxlIElEIGFmdGVyIHJ1bm5pbmcgYXBwIGluaXRpYWxpemVycywgc2luY2UgbG9jYWxlIGluZm9ybWF0aW9uIG1pZ2h0IGJlIHVwZGF0ZWQgd2hpbGVcbiAgICAvLyBydW5uaW5nIGluaXRpYWxpemVycy4gVGhpcyBpcyBhbHNvIGNvbnNpc3RlbnQgd2l0aCB0aGUgZXhlY3V0aW9uIG9yZGVyIHdoaWxlIGJvb3RzdHJhcHBpbmcgYW5cbiAgICAvLyBhcHAgKHNlZSBgcGFja2FnZXMvY29yZS9zcmMvYXBwbGljYXRpb25fcmVmLnRzYCBmaWxlKS5cbiAgICBjb25zdCBsb2NhbGVJZCA9IHRoaXMudGVzdE1vZHVsZVJlZi5pbmplY3Rvci5nZXQoTE9DQUxFX0lELCBERUZBVUxUX0xPQ0FMRV9JRCk7XG4gICAgc2V0TG9jYWxlSWQobG9jYWxlSWQpO1xuXG4gICAgcmV0dXJuIHRoaXMudGVzdE1vZHVsZVJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF9jb21waWxlTmdNb2R1bGVTeW5jKG1vZHVsZVR5cGU6IFR5cGU8YW55Pik6IHZvaWQge1xuICAgIHRoaXMucXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXkoW21vZHVsZVR5cGVdKTtcbiAgICB0aGlzLmNvbXBpbGVUeXBlc1N5bmMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXNJblNjb3BlKG1vZHVsZVR5cGUpO1xuICAgIHRoaXMuYXBwbHlUcmFuc2l0aXZlU2NvcGVzKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBhc3luYyBfY29tcGlsZU5nTW9kdWxlQXN5bmMobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5xdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShbbW9kdWxlVHlwZV0pO1xuICAgIGF3YWl0IHRoaXMuY29tcGlsZUNvbXBvbmVudHMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXNJblNjb3BlKG1vZHVsZVR5cGUpO1xuICAgIHRoaXMuYXBwbHlUcmFuc2l0aXZlU2NvcGVzKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfZ2V0TW9kdWxlUmVzb2x2ZXIoKTogUmVzb2x2ZXI8TmdNb2R1bGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlcnMubW9kdWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2dldENvbXBvbmVudEZhY3Rvcmllcyhtb2R1bGVUeXBlOiBOZ01vZHVsZVR5cGUpOiBDb21wb25lbnRGYWN0b3J5PGFueT5bXSB7XG4gICAgcmV0dXJuIG1heWJlVW53cmFwRm4obW9kdWxlVHlwZS7JtW1vZC5kZWNsYXJhdGlvbnMpLnJlZHVjZSgoZmFjdG9yaWVzLCBkZWNsYXJhdGlvbikgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50RGVmID0gKGRlY2xhcmF0aW9uIGFzIGFueSkuybVjbXA7XG4gICAgICBjb21wb25lbnREZWYgJiYgZmFjdG9yaWVzLnB1c2gobmV3IENvbXBvbmVudEZhY3RvcnkoY29tcG9uZW50RGVmLCB0aGlzLnRlc3RNb2R1bGVSZWYhKSk7XG4gICAgICByZXR1cm4gZmFjdG9yaWVzO1xuICAgIH0sIFtdIGFzIENvbXBvbmVudEZhY3Rvcnk8YW55PltdKTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcGlsZVR5cGVzU3luYygpOiBib29sZWFuIHtcbiAgICAvLyBDb21waWxlIGFsbCBxdWV1ZWQgY29tcG9uZW50cywgZGlyZWN0aXZlcywgcGlwZXMuXG4gICAgbGV0IG5lZWRzQXN5bmNSZXNvdXJjZXMgPSBmYWxzZTtcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRzLmZvckVhY2goZGVjbGFyYXRpb24gPT4ge1xuICAgICAgbmVlZHNBc3luY1Jlc291cmNlcyA9IG5lZWRzQXN5bmNSZXNvdXJjZXMgfHwgaXNDb21wb25lbnREZWZQZW5kaW5nUmVzb2x1dGlvbihkZWNsYXJhdGlvbik7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5yZXNvbHZlKGRlY2xhcmF0aW9uKTtcbiAgICAgIGlmIChtZXRhZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBpbnZhbGlkVHlwZUVycm9yKGRlY2xhcmF0aW9uLm5hbWUsICdDb21wb25lbnQnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0NPTVBfREVGLCBkZWNsYXJhdGlvbik7XG4gICAgICBjb21waWxlQ29tcG9uZW50KGRlY2xhcmF0aW9uLCBtZXRhZGF0YSk7XG4gICAgfSk7XG4gICAgdGhpcy5wZW5kaW5nQ29tcG9uZW50cy5jbGVhcigpO1xuXG4gICAgdGhpcy5wZW5kaW5nRGlyZWN0aXZlcy5mb3JFYWNoKGRlY2xhcmF0aW9uID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5yZXNvbHZlcnMuZGlyZWN0aXZlLnJlc29sdmUoZGVjbGFyYXRpb24pO1xuICAgICAgaWYgKG1ldGFkYXRhID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IGludmFsaWRUeXBlRXJyb3IoZGVjbGFyYXRpb24ubmFtZSwgJ0RpcmVjdGl2ZScpO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoTkdfRElSX0RFRiwgZGVjbGFyYXRpb24pO1xuICAgICAgY29tcGlsZURpcmVjdGl2ZShkZWNsYXJhdGlvbiwgbWV0YWRhdGEpO1xuICAgIH0pO1xuICAgIHRoaXMucGVuZGluZ0RpcmVjdGl2ZXMuY2xlYXIoKTtcblxuICAgIHRoaXMucGVuZGluZ1BpcGVzLmZvckVhY2goZGVjbGFyYXRpb24gPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5waXBlLnJlc29sdmUoZGVjbGFyYXRpb24pO1xuICAgICAgaWYgKG1ldGFkYXRhID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IGludmFsaWRUeXBlRXJyb3IoZGVjbGFyYXRpb24ubmFtZSwgJ1BpcGUnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX1BJUEVfREVGLCBkZWNsYXJhdGlvbik7XG4gICAgICBjb21waWxlUGlwZShkZWNsYXJhdGlvbiwgbWV0YWRhdGEpO1xuICAgIH0pO1xuICAgIHRoaXMucGVuZGluZ1BpcGVzLmNsZWFyKCk7XG5cbiAgICByZXR1cm4gbmVlZHNBc3luY1Jlc291cmNlcztcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlUcmFuc2l0aXZlU2NvcGVzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm92ZXJyaWRkZW5Nb2R1bGVzLnNpemUgPiAwKSB7XG4gICAgICAvLyBNb2R1bGUgb3ZlcnJpZGVzICh2aWEgYFRlc3RCZWQub3ZlcnJpZGVNb2R1bGVgKSBtaWdodCBhZmZlY3Qgc2NvcGVzIHRoYXQgd2VyZSBwcmV2aW91c2x5XG4gICAgICAvLyBjYWxjdWxhdGVkIGFuZCBzdG9yZWQgaW4gYHRyYW5zaXRpdmVDb21waWxlU2NvcGVzYC4gSWYgbW9kdWxlIG92ZXJyaWRlcyBhcmUgcHJlc2VudCxcbiAgICAgIC8vIGNvbGxlY3QgYWxsIGFmZmVjdGVkIG1vZHVsZXMgYW5kIHJlc2V0IHNjb3BlcyB0byBmb3JjZSB0aGVpciByZS1jYWxjdWxhdGlvbi5cbiAgICAgIGNvbnN0IHRlc3RpbmdNb2R1bGVEZWYgPSAodGhpcy50ZXN0TW9kdWxlVHlwZSBhcyBhbnkpW05HX01PRF9ERUZdO1xuICAgICAgY29uc3QgYWZmZWN0ZWRNb2R1bGVzID0gdGhpcy5jb2xsZWN0TW9kdWxlc0FmZmVjdGVkQnlPdmVycmlkZXModGVzdGluZ01vZHVsZURlZi5pbXBvcnRzKTtcbiAgICAgIGlmIChhZmZlY3RlZE1vZHVsZXMuc2l6ZSA+IDApIHtcbiAgICAgICAgYWZmZWN0ZWRNb2R1bGVzLmZvckVhY2gobW9kdWxlVHlwZSA9PiB7XG4gICAgICAgICAgdGhpcy5zdG9yZUZpZWxkT2ZEZWZPblR5cGUobW9kdWxlVHlwZSBhcyBhbnksIE5HX01PRF9ERUYsICd0cmFuc2l0aXZlQ29tcGlsZVNjb3BlcycpO1xuICAgICAgICAgIChtb2R1bGVUeXBlIGFzIGFueSlbTkdfTU9EX0RFRl0udHJhbnNpdGl2ZUNvbXBpbGVTY29wZXMgPSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtb2R1bGVUb1Njb3BlID0gbmV3IE1hcDxUeXBlPGFueT58VGVzdGluZ01vZHVsZU92ZXJyaWRlLCBOZ01vZHVsZVRyYW5zaXRpdmVTY29wZXM+KCk7XG4gICAgY29uc3QgZ2V0U2NvcGVPZk1vZHVsZSA9XG4gICAgICAgIChtb2R1bGVUeXBlOiBUeXBlPGFueT58VGVzdGluZ01vZHVsZU92ZXJyaWRlKTogTmdNb2R1bGVUcmFuc2l0aXZlU2NvcGVzID0+IHtcbiAgICAgICAgICBpZiAoIW1vZHVsZVRvU2NvcGUuaGFzKG1vZHVsZVR5cGUpKSB7XG4gICAgICAgICAgICBjb25zdCBpc1Rlc3RpbmdNb2R1bGUgPSBpc1Rlc3RpbmdNb2R1bGVPdmVycmlkZShtb2R1bGVUeXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlYWxUeXBlID0gaXNUZXN0aW5nTW9kdWxlID8gdGhpcy50ZXN0TW9kdWxlVHlwZSA6IG1vZHVsZVR5cGUgYXMgVHlwZTxhbnk+O1xuICAgICAgICAgICAgbW9kdWxlVG9TY29wZS5zZXQobW9kdWxlVHlwZSwgdHJhbnNpdGl2ZVNjb3Blc0ZvcihyZWFsVHlwZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbW9kdWxlVG9TY29wZS5nZXQobW9kdWxlVHlwZSkhO1xuICAgICAgICB9O1xuXG4gICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLmZvckVhY2goKG1vZHVsZVR5cGUsIGNvbXBvbmVudFR5cGUpID0+IHtcbiAgICAgIGNvbnN0IG1vZHVsZVNjb3BlID0gZ2V0U2NvcGVPZk1vZHVsZShtb2R1bGVUeXBlKTtcbiAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKGNvbXBvbmVudFR5cGUsIE5HX0NPTVBfREVGLCAnZGlyZWN0aXZlRGVmcycpO1xuICAgICAgdGhpcy5zdG9yZUZpZWxkT2ZEZWZPblR5cGUoY29tcG9uZW50VHlwZSwgTkdfQ09NUF9ERUYsICdwaXBlRGVmcycpO1xuICAgICAgLy8gYHRWaWV3YCB0aGF0IGlzIHN0b3JlZCBvbiBjb21wb25lbnQgZGVmIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGRpcmVjdGl2ZXMgYW5kIHBpcGVzXG4gICAgICAvLyB0aGF0IGFyZSBpbiB0aGUgc2NvcGUgb2YgdGhpcyBjb21wb25lbnQuIFBhdGNoaW5nIGNvbXBvbmVudCBzY29wZSB3aWxsIGNhdXNlIGB0Vmlld2AgdG8gYmVcbiAgICAgIC8vIGNoYW5nZWQuIFN0b3JlIG9yaWdpbmFsIGB0Vmlld2AgYmVmb3JlIHBhdGNoaW5nIHNjb3BlLCBzbyB0aGUgYHRWaWV3YCAoaW5jbHVkaW5nIHNjb3BlXG4gICAgICAvLyBpbmZvcm1hdGlvbikgaXMgcmVzdG9yZWQgYmFjayB0byBpdHMgcHJldmlvdXMvb3JpZ2luYWwgc3RhdGUgYmVmb3JlIHJ1bm5pbmcgbmV4dCB0ZXN0LlxuICAgICAgdGhpcy5zdG9yZUZpZWxkT2ZEZWZPblR5cGUoY29tcG9uZW50VHlwZSwgTkdfQ09NUF9ERUYsICd0VmlldycpO1xuICAgICAgcGF0Y2hDb21wb25lbnREZWZXaXRoU2NvcGUoKGNvbXBvbmVudFR5cGUgYXMgYW55KS7JtWNtcCwgbW9kdWxlU2NvcGUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5UHJvdmlkZXJPdmVycmlkZXMoKTogdm9pZCB7XG4gICAgY29uc3QgbWF5YmVBcHBseU92ZXJyaWRlcyA9IChmaWVsZDogc3RyaW5nKSA9PiAodHlwZTogVHlwZTxhbnk+KSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlciA9IGZpZWxkID09PSBOR19DT01QX0RFRiA/IHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudCA6IHRoaXMucmVzb2x2ZXJzLmRpcmVjdGl2ZTtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gcmVzb2x2ZXIucmVzb2x2ZSh0eXBlKSE7XG4gICAgICBpZiAodGhpcy5oYXNQcm92aWRlck92ZXJyaWRlcyhtZXRhZGF0YS5wcm92aWRlcnMpKSB7XG4gICAgICAgIHRoaXMucGF0Y2hEZWZXaXRoUHJvdmlkZXJPdmVycmlkZXModHlwZSwgZmllbGQpO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5zZWVuQ29tcG9uZW50cy5mb3JFYWNoKG1heWJlQXBwbHlPdmVycmlkZXMoTkdfQ09NUF9ERUYpKTtcbiAgICB0aGlzLnNlZW5EaXJlY3RpdmVzLmZvckVhY2gobWF5YmVBcHBseU92ZXJyaWRlcyhOR19ESVJfREVGKSk7XG5cbiAgICB0aGlzLnNlZW5Db21wb25lbnRzLmNsZWFyKCk7XG4gICAgdGhpcy5zZWVuRGlyZWN0aXZlcy5jbGVhcigpO1xuICB9XG5cblxuICAvKipcbiAgICogQXBwbGllcyBwcm92aWRlciBvdmVycmlkZXMgdG8gYSBnaXZlbiB0eXBlIChlaXRoZXIgYW4gTmdNb2R1bGUgb3IgYSBzdGFuZGFsb25lIGNvbXBvbmVudClcbiAgICogYW5kIGFsbCBpbXBvcnRlZCBOZ01vZHVsZXMgYW5kIHN0YW5kYWxvbmUgY29tcG9uZW50cyByZWN1cnNpdmVseS5cbiAgICovXG4gIHByaXZhdGUgYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUodHlwZTogVHlwZTxhbnk+KTogdm9pZCB7XG4gICAgY29uc3QgaGFzU2NvcGUgPSBpc1N0YW5kYWxvbmVDb21wb25lbnQodHlwZSkgfHwgaXNOZ01vZHVsZSh0eXBlKTtcblxuICAgIC8vIFRoZSBmdW5jdGlvbiBjYW4gYmUgcmUtZW50ZXJlZCByZWN1cnNpdmVseSB3aGlsZSBpbnNwZWN0aW5nIGRlcGVuZGVuY2llc1xuICAgIC8vIG9mIGFuIE5nTW9kdWxlIG9yIGEgc3RhbmRhbG9uZSBjb21wb25lbnQuIEV4aXQgZWFybHkgaWYgd2UgY29tZSBhY3Jvc3MgYVxuICAgIC8vIHR5cGUgdGhhdCBjYW4gbm90IGhhdmUgYSBzY29wZSAoZGlyZWN0aXZlIG9yIHBpcGUpIG9yIHRoZSB0eXBlIGlzIGFscmVhZHlcbiAgICAvLyBwcm9jZXNzZWQgZWFybGllci5cbiAgICBpZiAoIWhhc1Njb3BlIHx8IHRoaXMuc2NvcGVzV2l0aE92ZXJyaWRkZW5Qcm92aWRlcnMuaGFzKHR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc2NvcGVzV2l0aE92ZXJyaWRkZW5Qcm92aWRlcnMuYWRkKHR5cGUpO1xuXG4gICAgLy8gTk9URTogdGhlIGxpbmUgYmVsb3cgdHJpZ2dlcnMgSklUIGNvbXBpbGF0aW9uIG9mIHRoZSBtb2R1bGUgaW5qZWN0b3IsXG4gICAgLy8gd2hpY2ggYWxzbyBpbnZva2VzIHZlcmlmaWNhdGlvbiBvZiB0aGUgTmdNb2R1bGUgc2VtYW50aWNzLCB3aGljaCBwcm9kdWNlc1xuICAgIC8vIGRldGFpbGVkIGVycm9yIG1lc3NhZ2VzLiBUaGUgZmFjdCB0aGF0IHRoZSBjb2RlIHJlbGllcyBvbiB0aGlzIGxpbmUgYmVpbmdcbiAgICAvLyBwcmVzZW50IGhlcmUgaXMgc3VzcGljaW91cyBhbmQgc2hvdWxkIGJlIHJlZmFjdG9yZWQgaW4gYSB3YXkgdGhhdCB0aGUgbGluZVxuICAgIC8vIGJlbG93IGNhbiBiZSBtb3ZlZCAoZm9yIGV4LiBhZnRlciBhbiBlYXJseSBleGl0IGNoZWNrIGJlbG93KS5cbiAgICBjb25zdCBpbmplY3RvckRlZjogYW55ID0gKHR5cGUgYXMgYW55KVtOR19JTkpfREVGXTtcblxuICAgIC8vIE5vIHByb3ZpZGVyIG92ZXJyaWRlcywgZXhpdCBlYXJseS5cbiAgICBpZiAodGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uc2l6ZSA9PT0gMCkgcmV0dXJuO1xuXG4gICAgaWYgKGlzU3RhbmRhbG9uZUNvbXBvbmVudCh0eXBlKSkge1xuICAgICAgLy8gVmlzaXQgYWxsIGNvbXBvbmVudCBkZXBlbmRlbmNpZXMgYW5kIG92ZXJyaWRlIHByb3ZpZGVycyB0aGVyZS5cbiAgICAgIGNvbnN0IGRlZiA9IGdldENvbXBvbmVudERlZih0eXBlKTtcbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IG1heWJlVW53cmFwRm4oZGVmLmRlcGVuZGVuY2llcyA/PyBbXSk7XG4gICAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUoZGVwZW5kZW5jeSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByb3ZpZGVyczogQXJyYXk8UHJvdmlkZXJ8SW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycz4gPSBbXG4gICAgICAgIC4uLmluamVjdG9yRGVmLnByb3ZpZGVycyxcbiAgICAgICAgLi4uKHRoaXMucHJvdmlkZXJPdmVycmlkZXNCeU1vZHVsZS5nZXQodHlwZSBhcyBJbmplY3RvclR5cGU8YW55PikgfHwgW10pXG4gICAgICBdO1xuICAgICAgaWYgKHRoaXMuaGFzUHJvdmlkZXJPdmVycmlkZXMocHJvdmlkZXJzKSkge1xuICAgICAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihOR19JTkpfREVGLCB0eXBlKTtcblxuICAgICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZSh0eXBlLCBOR19JTkpfREVGLCAncHJvdmlkZXJzJyk7XG4gICAgICAgIGluamVjdG9yRGVmLnByb3ZpZGVycyA9IHRoaXMuZ2V0T3ZlcnJpZGRlblByb3ZpZGVycyhwcm92aWRlcnMpO1xuICAgICAgfVxuXG4gICAgICAvLyBBcHBseSBwcm92aWRlciBvdmVycmlkZXMgdG8gaW1wb3J0ZWQgbW9kdWxlcyByZWN1cnNpdmVseVxuICAgICAgY29uc3QgbW9kdWxlRGVmID0gKHR5cGUgYXMgYW55KVtOR19NT0RfREVGXTtcbiAgICAgIGNvbnN0IGltcG9ydHMgPSBtYXliZVVud3JhcEZuKG1vZHVsZURlZi5pbXBvcnRzKTtcbiAgICAgIGZvciAoY29uc3QgaW1wb3J0ZWRNb2R1bGUgb2YgaW1wb3J0cykge1xuICAgICAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXNJblNjb3BlKGltcG9ydGVkTW9kdWxlKTtcbiAgICAgIH1cbiAgICAgIC8vIEFsc28gb3ZlcnJpZGUgdGhlIHByb3ZpZGVycyBvbiBhbnkgTW9kdWxlV2l0aFByb3ZpZGVycyBpbXBvcnRzIHNpbmNlIHRob3NlIGRvbid0IGFwcGVhciBpblxuICAgICAgLy8gdGhlIG1vZHVsZURlZi5cbiAgICAgIGZvciAoY29uc3QgaW1wb3J0ZWRNb2R1bGUgb2YgZmxhdHRlbihpbmplY3RvckRlZi5pbXBvcnRzKSkge1xuICAgICAgICBpZiAoaXNNb2R1bGVXaXRoUHJvdmlkZXJzKGltcG9ydGVkTW9kdWxlKSkge1xuICAgICAgICAgIHRoaXMuZGVmQ2xlYW51cE9wcy5wdXNoKHtcbiAgICAgICAgICAgIG9iamVjdDogaW1wb3J0ZWRNb2R1bGUsXG4gICAgICAgICAgICBmaWVsZE5hbWU6ICdwcm92aWRlcnMnLFxuICAgICAgICAgICAgb3JpZ2luYWxWYWx1ZTogaW1wb3J0ZWRNb2R1bGUucHJvdmlkZXJzXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaW1wb3J0ZWRNb2R1bGUucHJvdmlkZXJzID0gdGhpcy5nZXRPdmVycmlkZGVuUHJvdmlkZXJzKFxuICAgICAgICAgICAgICBpbXBvcnRlZE1vZHVsZS5wcm92aWRlcnMgYXMgQXJyYXk8UHJvdmlkZXJ8SW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycz4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXRjaENvbXBvbmVudHNXaXRoRXhpc3RpbmdTdHlsZXMoKTogdm9pZCB7XG4gICAgdGhpcy5leGlzdGluZ0NvbXBvbmVudFN0eWxlcy5mb3JFYWNoKFxuICAgICAgICAoc3R5bGVzLCB0eXBlKSA9PiAodHlwZSBhcyBhbnkpW05HX0NPTVBfREVGXS5zdHlsZXMgPSBzdHlsZXMpO1xuICAgIHRoaXMuZXhpc3RpbmdDb21wb25lbnRTdHlsZXMuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgcXVldWVUeXBlQXJyYXkoYXJyOiBhbnlbXSwgbW9kdWxlVHlwZTogVHlwZTxhbnk+fFRlc3RpbmdNb2R1bGVPdmVycmlkZSk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYXJyKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdGhpcy5xdWV1ZVR5cGVBcnJheSh2YWx1ZSwgbW9kdWxlVHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnF1ZXVlVHlwZSh2YWx1ZSwgbW9kdWxlVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWNvbXBpbGVOZ01vZHVsZShuZ01vZHVsZTogVHlwZTxhbnk+LCBtZXRhZGF0YTogTmdNb2R1bGUpOiB2b2lkIHtcbiAgICAvLyBDYWNoZSB0aGUgaW5pdGlhbCBuZ01vZHVsZURlZiBhcyBpdCB3aWxsIGJlIG92ZXJ3cml0dGVuLlxuICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX01PRF9ERUYsIG5nTW9kdWxlKTtcbiAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihOR19JTkpfREVGLCBuZ01vZHVsZSk7XG5cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKG5nTW9kdWxlIGFzIE5nTW9kdWxlVHlwZTxhbnk+LCBtZXRhZGF0YSk7XG4gIH1cblxuICBwcml2YXRlIHF1ZXVlVHlwZSh0eXBlOiBUeXBlPGFueT4sIG1vZHVsZVR5cGU6IFR5cGU8YW55PnxUZXN0aW5nTW9kdWxlT3ZlcnJpZGV8bnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5yZXNvbHZlKHR5cGUpO1xuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIC8vIENoZWNrIHdoZXRoZXIgYSBnaXZlIFR5cGUgaGFzIHJlc3BlY3RpdmUgTkcgZGVmICjJtWNtcCkgYW5kIGNvbXBpbGUgaWYgZGVmIGlzXG4gICAgICAvLyBtaXNzaW5nLiBUaGF0IG1pZ2h0IGhhcHBlbiBpbiBjYXNlIGEgY2xhc3Mgd2l0aG91dCBhbnkgQW5ndWxhciBkZWNvcmF0b3JzIGV4dGVuZHMgYW5vdGhlclxuICAgICAgLy8gY2xhc3Mgd2hlcmUgQ29tcG9uZW50L0RpcmVjdGl2ZS9QaXBlIGRlY29yYXRvciBpcyBkZWZpbmVkLlxuICAgICAgaWYgKGlzQ29tcG9uZW50RGVmUGVuZGluZ1Jlc29sdXRpb24odHlwZSkgfHwgIXR5cGUuaGFzT3duUHJvcGVydHkoTkdfQ09NUF9ERUYpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0NvbXBvbmVudHMuYWRkKHR5cGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZWVuQ29tcG9uZW50cy5hZGQodHlwZSk7XG5cbiAgICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWNsYXJlcyB0aGlzIGNvbXBvbmVudCwgc28gbGF0ZXIgdGhlIGNvbXBvbmVudCdzIHNjb3BlXG4gICAgICAvLyBjYW4gYmUgc2V0IGNvcnJlY3RseS4gSWYgdGhlIGNvbXBvbmVudCBoYXMgYWxyZWFkeSBiZWVuIHJlY29yZGVkIGhlcmUsIHRoZW4gb25lIG9mIHNldmVyYWxcbiAgICAgIC8vIGNhc2VzIGlzIHRydWU6XG4gICAgICAvLyAqIHRoZSBtb2R1bGUgY29udGFpbmluZyB0aGUgY29tcG9uZW50IHdhcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyAoY29tbW9uKS5cbiAgICAgIC8vICogdGhlIGNvbXBvbmVudCBpcyBkZWNsYXJlZCBpbiBtdWx0aXBsZSBtb2R1bGVzICh3aGljaCBpcyBhbiBlcnJvcikuXG4gICAgICAvLyAqIHRoZSBjb21wb25lbnQgd2FzIGluICdkZWNsYXJhdGlvbnMnIG9mIHRoZSB0ZXN0aW5nIG1vZHVsZSwgYW5kIGFsc28gaW4gYW4gaW1wb3J0ZWQgbW9kdWxlXG4gICAgICAvLyAgIGluIHdoaWNoIGNhc2UgdGhlIG1vZHVsZSBzY29wZSB3aWxsIGJlIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTi5cbiAgICAgIC8vICogb3ZlcnJpZGVUZW1wbGF0ZVVzaW5nVGVzdGluZ01vZHVsZSB3YXMgY2FsbGVkIGZvciB0aGUgY29tcG9uZW50IGluIHdoaWNoIGNhc2UgdGhlIG1vZHVsZVxuICAgICAgLy8gICBzY29wZSB3aWxsIGJlIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5PVkVSUklERV9URU1QTEFURS5cbiAgICAgIC8vXG4gICAgICAvLyBJZiB0aGUgY29tcG9uZW50IHdhcyBwcmV2aW91c2x5IGluIHRoZSB0ZXN0aW5nIG1vZHVsZSdzICdkZWNsYXJhdGlvbnMnIChtZWFuaW5nIHRoZVxuICAgICAgLy8gY3VycmVudCB2YWx1ZSBpcyBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuREVDTEFSQVRJT04pLCB0aGVuIGBtb2R1bGVUeXBlYCBpcyB0aGUgY29tcG9uZW50J3NcbiAgICAgIC8vIHJlYWwgbW9kdWxlLCB3aGljaCB3YXMgaW1wb3J0ZWQuIFRoaXMgcGF0dGVybiBpcyB1bmRlcnN0b29kIHRvIG1lYW4gdGhhdCB0aGUgY29tcG9uZW50XG4gICAgICAvLyBzaG91bGQgdXNlIGl0cyBvcmlnaW5hbCBzY29wZSwgYnV0IHRoYXQgdGhlIHRlc3RpbmcgbW9kdWxlIHNob3VsZCBhbHNvIGNvbnRhaW4gdGhlXG4gICAgICAvLyBjb21wb25lbnQgaW4gaXRzIHNjb3BlLlxuICAgICAgLy9cbiAgICAgIC8vIE5vdGU6IHN0YW5kYWxvbmUgY29tcG9uZW50cyBoYXZlIG5vIGFzc29jaWF0ZWQgTmdNb2R1bGUsIHNvIHRoZSBgbW9kdWxlVHlwZWAgY2FuIGJlIGBudWxsYC5cbiAgICAgIGlmIChtb2R1bGVUeXBlICE9PSBudWxsICYmXG4gICAgICAgICAgKCF0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuaGFzKHR5cGUpIHx8XG4gICAgICAgICAgIHRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5nZXQodHlwZSkgPT09IFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTikpIHtcbiAgICAgICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLnNldCh0eXBlLCBtb2R1bGVUeXBlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkaXJlY3RpdmUgPSB0aGlzLnJlc29sdmVycy5kaXJlY3RpdmUucmVzb2x2ZSh0eXBlKTtcbiAgICBpZiAoZGlyZWN0aXZlKSB7XG4gICAgICBpZiAoIXR5cGUuaGFzT3duUHJvcGVydHkoTkdfRElSX0RFRikpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nRGlyZWN0aXZlcy5hZGQodHlwZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNlZW5EaXJlY3RpdmVzLmFkZCh0eXBlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwaXBlID0gdGhpcy5yZXNvbHZlcnMucGlwZS5yZXNvbHZlKHR5cGUpO1xuICAgIGlmIChwaXBlICYmICF0eXBlLmhhc093blByb3BlcnR5KE5HX1BJUEVfREVGKSkge1xuICAgICAgdGhpcy5wZW5kaW5nUGlwZXMuYWRkKHR5cGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXkoYXJyOiBhbnlbXSk6IHZvaWQge1xuICAgIC8vIEJlY2F1c2Ugd2UgbWF5IGVuY291bnRlciB0aGUgc2FtZSBOZ01vZHVsZSBvciBhIHN0YW5kYWxvbmUgQ29tcG9uZW50IHdoaWxlIHByb2Nlc3NpbmdcbiAgICAvLyB0aGUgZGVwZW5kZW5jaWVzIG9mIGFuIE5nTW9kdWxlIG9yIGEgc3RhbmRhbG9uZSBDb21wb25lbnQsIHdlIGNhY2hlIHRoZW0gaW4gdGhpcyBzZXQgc28gd2VcbiAgICAvLyBjYW4gc2tpcCBvbmVzIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gc2VlbiBlbmNvdW50ZXJlZC4gSW4gc29tZSB0ZXN0IHNldHVwcywgdGhpcyBjYWNoaW5nXG4gICAgLy8gcmVzdWx0ZWQgaW4gMTBYIHJ1bnRpbWUgaW1wcm92ZW1lbnQuXG4gICAgY29uc3QgcHJvY2Vzc2VkRGVmcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyID0gKGFycjogYW55W10pOiB2b2lkID0+IHtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYXJyKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGhhc05nTW9kdWxlRGVmKHZhbHVlKSkge1xuICAgICAgICAgIGNvbnN0IGRlZiA9IHZhbHVlLsm1bW9kO1xuICAgICAgICAgIGlmIChwcm9jZXNzZWREZWZzLmhhcyhkZWYpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJvY2Vzc2VkRGVmcy5hZGQoZGVmKTtcbiAgICAgICAgICAvLyBMb29rIHRocm91Z2ggZGVjbGFyYXRpb25zLCBpbXBvcnRzLCBhbmQgZXhwb3J0cywgYW5kIHF1ZXVlXG4gICAgICAgICAgLy8gZXZlcnl0aGluZyBmb3VuZCB0aGVyZS5cbiAgICAgICAgICB0aGlzLnF1ZXVlVHlwZUFycmF5KG1heWJlVW53cmFwRm4oZGVmLmRlY2xhcmF0aW9ucyksIHZhbHVlKTtcbiAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKG1heWJlVW53cmFwRm4oZGVmLmltcG9ydHMpKTtcbiAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKG1heWJlVW53cmFwRm4oZGVmLmV4cG9ydHMpKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc01vZHVsZVdpdGhQcm92aWRlcnModmFsdWUpKSB7XG4gICAgICAgICAgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1cihbdmFsdWUubmdNb2R1bGVdKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1N0YW5kYWxvbmVDb21wb25lbnQodmFsdWUpKSB7XG4gICAgICAgICAgdGhpcy5xdWV1ZVR5cGUodmFsdWUsIG51bGwpO1xuICAgICAgICAgIGNvbnN0IGRlZiA9IGdldENvbXBvbmVudERlZih2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAocHJvY2Vzc2VkRGVmcy5oYXMoZGVmKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHByb2Nlc3NlZERlZnMuYWRkKGRlZik7XG5cbiAgICAgICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBtYXliZVVud3JhcEZuKGRlZi5kZXBlbmRlbmNpZXMgPz8gW10pO1xuICAgICAgICAgIGRlcGVuZGVuY2llcy5mb3JFYWNoKChkZXBlbmRlbmN5KSA9PiB7XG4gICAgICAgICAgICAvLyBOb3RlOiBpbiBBT1QsIHRoZSBgZGVwZW5kZW5jaWVzYCBtaWdodCBhbHNvIGNvbnRhaW4gcmVndWxhclxuICAgICAgICAgICAgLy8gKE5nTW9kdWxlLWJhc2VkKSBDb21wb25lbnQsIERpcmVjdGl2ZSBhbmQgUGlwZXMsIHNvIHdlIGhhbmRsZVxuICAgICAgICAgICAgLy8gdGhlbSBzZXBhcmF0ZWx5IGFuZCBwcm9jZWVkIHdpdGggcmVjdXJzaXZlIHByb2Nlc3MgZm9yIHN0YW5kYWxvbmVcbiAgICAgICAgICAgIC8vIENvbXBvbmVudHMgYW5kIE5nTW9kdWxlcyBvbmx5LlxuICAgICAgICAgICAgaWYgKGlzU3RhbmRhbG9uZUNvbXBvbmVudChkZXBlbmRlbmN5KSB8fCBoYXNOZ01vZHVsZURlZihkZXBlbmRlbmN5KSkge1xuICAgICAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKFtkZXBlbmRlbmN5XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnF1ZXVlVHlwZShkZXBlbmRlbmN5LCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1cihhcnIpO1xuICB9XG5cbiAgLy8gV2hlbiBtb2R1bGUgb3ZlcnJpZGVzICh2aWEgYFRlc3RCZWQub3ZlcnJpZGVNb2R1bGVgKSBhcmUgcHJlc2VudCwgaXQgbWlnaHQgYWZmZWN0IGFsbCBtb2R1bGVzXG4gIC8vIHRoYXQgaW1wb3J0IChldmVuIHRyYW5zaXRpdmVseSkgYW4gb3ZlcnJpZGRlbiBvbmUuIEZvciBhbGwgYWZmZWN0ZWQgbW9kdWxlcyB3ZSBuZWVkIHRvXG4gIC8vIHJlY2FsY3VsYXRlIHRoZWlyIHNjb3BlcyBmb3IgYSBnaXZlbiB0ZXN0IHJ1biBhbmQgcmVzdG9yZSBvcmlnaW5hbCBzY29wZXMgYXQgdGhlIGVuZC4gVGhlIGdvYWxcbiAgLy8gb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBjb2xsZWN0IGFsbCBhZmZlY3RlZCBtb2R1bGVzIGluIGEgc2V0IGZvciBmdXJ0aGVyIHByb2Nlc3NpbmcuIEV4YW1wbGU6XG4gIC8vIGlmIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBtb2R1bGUgaGllcmFyY2h5OiBBIC0+IEIgLT4gQyAod2hlcmUgYC0+YCBtZWFucyBgaW1wb3J0c2ApIGFuZCBtb2R1bGVcbiAgLy8gYENgIGlzIG92ZXJyaWRkZW4sIHdlIGNvbnNpZGVyIGBBYCBhbmQgYEJgIGFzIGFmZmVjdGVkLCBzaW5jZSB0aGVpciBzY29wZXMgbWlnaHQgYmVjb21lXG4gIC8vIGludmFsaWRhdGVkIHdpdGggdGhlIG92ZXJyaWRlLlxuICBwcml2YXRlIGNvbGxlY3RNb2R1bGVzQWZmZWN0ZWRCeU92ZXJyaWRlcyhhcnI6IGFueVtdKTogU2V0PE5nTW9kdWxlVHlwZTxhbnk+PiB7XG4gICAgY29uc3Qgc2Vlbk1vZHVsZXMgPSBuZXcgU2V0PE5nTW9kdWxlVHlwZTxhbnk+PigpO1xuICAgIGNvbnN0IGFmZmVjdGVkTW9kdWxlcyA9IG5ldyBTZXQ8TmdNb2R1bGVUeXBlPGFueT4+KCk7XG4gICAgY29uc3QgY2FsY0FmZmVjdGVkTW9kdWxlc1JlY3VyID0gKGFycjogYW55W10sIHBhdGg6IE5nTW9kdWxlVHlwZTxhbnk+W10pOiB2b2lkID0+IHtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYXJyKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIC8vIElmIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSwganVzdCBmbGF0dGVuIGl0IChieSBpbnZva2luZyB0aGlzIGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5KSxcbiAgICAgICAgICAvLyBrZWVwaW5nIFwicGF0aFwiIHRoZSBzYW1lLlxuICAgICAgICAgIGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1cih2YWx1ZSwgcGF0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaGFzTmdNb2R1bGVEZWYodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKHNlZW5Nb2R1bGVzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIHNlZW4gdGhpcyBtb2R1bGUgYmVmb3JlIGFuZCBpdCdzIGluY2x1ZGVkIGludG8gXCJhZmZlY3RlZCBtb2R1bGVzXCIgbGlzdCwgbWFya1xuICAgICAgICAgICAgLy8gdGhlIHdob2xlIHBhdGggdGhhdCBsZWFkcyB0byB0aGF0IG1vZHVsZSBhcyBhZmZlY3RlZCwgYnV0IGRvIG5vdCBkZXNjZW5kIGludG8gaXRzXG4gICAgICAgICAgICAvLyBpbXBvcnRzLCBzaW5jZSB3ZSBhbHJlYWR5IGV4YW1pbmVkIHRoZW0gYmVmb3JlLlxuICAgICAgICAgICAgaWYgKGFmZmVjdGVkTW9kdWxlcy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgIHBhdGguZm9yRWFjaChpdGVtID0+IGFmZmVjdGVkTW9kdWxlcy5hZGQoaXRlbSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlZW5Nb2R1bGVzLmFkZCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHRoaXMub3ZlcnJpZGRlbk1vZHVsZXMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgcGF0aC5mb3JFYWNoKGl0ZW0gPT4gYWZmZWN0ZWRNb2R1bGVzLmFkZChpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEV4YW1pbmUgbW9kdWxlIGltcG9ydHMgcmVjdXJzaXZlbHkgdG8gbG9vayBmb3Igb3ZlcnJpZGRlbiBtb2R1bGVzLlxuICAgICAgICAgIGNvbnN0IG1vZHVsZURlZiA9ICh2YWx1ZSBhcyBhbnkpW05HX01PRF9ERUZdO1xuICAgICAgICAgIGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1cihtYXliZVVud3JhcEZuKG1vZHVsZURlZi5pbXBvcnRzKSwgcGF0aC5jb25jYXQodmFsdWUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgY2FsY0FmZmVjdGVkTW9kdWxlc1JlY3VyKGFyciwgW10pO1xuICAgIHJldHVybiBhZmZlY3RlZE1vZHVsZXM7XG4gIH1cblxuICAvKipcbiAgICogUHJlc2VydmUgYW4gb3JpZ2luYWwgZGVmIChzdWNoIGFzIMm1bW9kLCDJtWluaiwgZXRjKSBiZWZvcmUgYXBwbHlpbmcgYW4gb3ZlcnJpZGUuXG4gICAqIE5vdGU6IG9uZSBjbGFzcyBtYXkgaGF2ZSBtdWx0aXBsZSBkZWZzIChmb3IgZXhhbXBsZTogybVtb2QgYW5kIMm1aW5qIGluIGNhc2Ugb2ZcbiAgICogYW4gTmdNb2R1bGUpLiBJZiB0aGVyZSBpcyBhIGRlZiBpbiBhIHNldCBhbHJlYWR5LCBkb24ndCBvdmVycmlkZSBpdCwgc2luY2VcbiAgICogYW4gb3JpZ2luYWwgb25lIHNob3VsZCBiZSByZXN0b3JlZCBhdCB0aGUgZW5kIG9mIGEgdGVzdC5cbiAgICovXG4gIHByaXZhdGUgbWF5YmVTdG9yZU5nRGVmKHByb3A6IHN0cmluZywgdHlwZTogVHlwZTxhbnk+KSB7XG4gICAgaWYgKCF0aGlzLmluaXRpYWxOZ0RlZnMuaGFzKHR5cGUpKSB7XG4gICAgICB0aGlzLmluaXRpYWxOZ0RlZnMuc2V0KHR5cGUsIG5ldyBNYXAoKSk7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnREZWZzID0gdGhpcy5pbml0aWFsTmdEZWZzLmdldCh0eXBlKSE7XG4gICAgaWYgKCFjdXJyZW50RGVmcy5oYXMocHJvcCkpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREZWYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHR5cGUsIHByb3ApO1xuICAgICAgY3VycmVudERlZnMuc2V0KHByb3AsIGN1cnJlbnREZWYpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RvcmVGaWVsZE9mRGVmT25UeXBlKHR5cGU6IFR5cGU8YW55PiwgZGVmRmllbGQ6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkZWY6IGFueSA9ICh0eXBlIGFzIGFueSlbZGVmRmllbGRdO1xuICAgIGNvbnN0IG9yaWdpbmFsVmFsdWU6IGFueSA9IGRlZltmaWVsZE5hbWVdO1xuICAgIHRoaXMuZGVmQ2xlYW51cE9wcy5wdXNoKHtvYmplY3Q6IGRlZiwgZmllbGROYW1lLCBvcmlnaW5hbFZhbHVlfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGN1cnJlbnQgY29tcG9uZW50cyByZXNvbHV0aW9uIHF1ZXVlLCBidXQgc3RvcmVzIHRoZSBzdGF0ZSBvZiB0aGUgcXVldWUsIHNvIHdlIGNhblxuICAgKiByZXN0b3JlIGl0IGxhdGVyLiBDbGVhcmluZyB0aGUgcXVldWUgaXMgcmVxdWlyZWQgYmVmb3JlIHdlIHRyeSB0byBjb21waWxlIGNvbXBvbmVudHMgKHZpYVxuICAgKiBgVGVzdEJlZC5jb21waWxlQ29tcG9uZW50c2ApLCBzbyB0aGF0IGNvbXBvbmVudCBkZWZzIGFyZSBpbiBzeW5jIHdpdGggdGhlIHJlc29sdXRpb24gcXVldWUuXG4gICAqL1xuICBwcml2YXRlIGNsZWFyQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID09PSBudWxsKSB7XG4gICAgICB0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlKCkuZm9yRWFjaChcbiAgICAgICAgKHZhbHVlLCBrZXkpID0+IHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUhLnNldChrZXksIHZhbHVlKSk7XG4gIH1cblxuICAvKlxuICAgKiBSZXN0b3JlcyBjb21wb25lbnQgcmVzb2x1dGlvbiBxdWV1ZSB0byB0aGUgcHJldmlvdXNseSBzYXZlZCBzdGF0ZS4gVGhpcyBvcGVyYXRpb24gaXMgcGVyZm9ybWVkXG4gICAqIGFzIGEgcGFydCBvZiByZXN0b3JpbmcgdGhlIHN0YXRlIGFmdGVyIGNvbXBsZXRpb24gb2YgdGhlIGN1cnJlbnQgc2V0IG9mIHRlc3RzICh0aGF0IG1pZ2h0XG4gICAqIHBvdGVudGlhbGx5IG11dGF0ZSB0aGUgc3RhdGUpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlICE9PSBudWxsKSB7XG4gICAgICByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUpO1xuICAgICAgdGhpcy5vcmlnaW5hbENvbXBvbmVudFJlc29sdXRpb25RdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZU9yaWdpbmFsU3RhdGUoKTogdm9pZCB7XG4gICAgLy8gUHJvY2VzcyBjbGVhbnVwIG9wcyBpbiByZXZlcnNlIG9yZGVyIHNvIHRoZSBmaWVsZCdzIG9yaWdpbmFsIHZhbHVlIGlzIHJlc3RvcmVkIGNvcnJlY3RseSAoaW5cbiAgICAvLyBjYXNlIHRoZXJlIHdlcmUgbXVsdGlwbGUgb3ZlcnJpZGVzIGZvciB0aGUgc2FtZSBmaWVsZCkuXG4gICAgZm9yRWFjaFJpZ2h0KHRoaXMuZGVmQ2xlYW51cE9wcywgKG9wOiBDbGVhbnVwT3BlcmF0aW9uKSA9PiB7XG4gICAgICBvcC5vYmplY3Rbb3AuZmllbGROYW1lXSA9IG9wLm9yaWdpbmFsVmFsdWU7XG4gICAgfSk7XG4gICAgLy8gUmVzdG9yZSBpbml0aWFsIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZSBkZWZzXG4gICAgdGhpcy5pbml0aWFsTmdEZWZzLmZvckVhY2goXG4gICAgICAgIChkZWZzOiBNYXA8c3RyaW5nLCBQcm9wZXJ0eURlc2NyaXB0b3J8dW5kZWZpbmVkPiwgdHlwZTogVHlwZTxhbnk+KSA9PiB7XG4gICAgICAgICAgZGVmcy5mb3JFYWNoKChkZXNjcmlwdG9yLCBwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgICAgICAgICAgLy8gRGVsZXRlIG9wZXJhdGlvbnMgYXJlIGdlbmVyYWxseSB1bmRlc2lyYWJsZSBzaW5jZSB0aGV5IGhhdmUgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgICAgLy8gaW1wbGljYXRpb25zIG9uIG9iamVjdHMgdGhleSB3ZXJlIGFwcGxpZWQgdG8uIEluIHRoaXMgcGFydGljdWxhciBjYXNlLCBzaXR1YXRpb25zXG4gICAgICAgICAgICAgIC8vIHdoZXJlIHRoaXMgY29kZSBpcyBpbnZva2VkIHNob3VsZCBiZSBxdWl0ZSByYXJlIHRvIGNhdXNlIGFueSBub3RpY2VhYmxlIGltcGFjdCxcbiAgICAgICAgICAgICAgLy8gc2luY2UgaXQncyBhcHBsaWVkIG9ubHkgdG8gc29tZSB0ZXN0IGNhc2VzIChmb3IgZXhhbXBsZSB3aGVuIGNsYXNzIHdpdGggbm9cbiAgICAgICAgICAgICAgLy8gYW5ub3RhdGlvbnMgZXh0ZW5kcyBzb21lIEBDb21wb25lbnQpIHdoZW4gd2UgbmVlZCB0byBjbGVhciAnybVjbXAnIGZpZWxkIG9uIGEgZ2l2ZW5cbiAgICAgICAgICAgICAgLy8gY2xhc3MgdG8gcmVzdG9yZSBpdHMgb3JpZ2luYWwgc3RhdGUgKGJlZm9yZSBhcHBseWluZyBvdmVycmlkZXMgYW5kIHJ1bm5pbmcgdGVzdHMpLlxuICAgICAgICAgICAgICBkZWxldGUgKHR5cGUgYXMgYW55KVtwcm9wXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0eXBlLCBwcm9wLCBkZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgdGhpcy5pbml0aWFsTmdEZWZzLmNsZWFyKCk7XG4gICAgdGhpcy5zY29wZXNXaXRoT3ZlcnJpZGRlblByb3ZpZGVycy5jbGVhcigpO1xuICAgIHRoaXMucmVzdG9yZUNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSgpO1xuICAgIC8vIFJlc3RvcmUgdGhlIGxvY2FsZSBJRCB0byB0aGUgZGVmYXVsdCB2YWx1ZSwgdGhpcyBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5IGJ1dCB3ZSBuZXZlciBrbm93XG4gICAgc2V0TG9jYWxlSWQoREVGQVVMVF9MT0NBTEVfSUQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21waWxlVGVzdE1vZHVsZSgpOiB2b2lkIHtcbiAgICBjbGFzcyBSb290U2NvcGVNb2R1bGUge31cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKFJvb3RTY29wZU1vZHVsZSBhcyBOZ01vZHVsZVR5cGU8YW55Piwge1xuICAgICAgcHJvdmlkZXJzOiBbLi4udGhpcy5yb290UHJvdmlkZXJPdmVycmlkZXNdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvdmlkZXJzID0gW1xuICAgICAgcHJvdmlkZVpvbmVDaGFuZ2VEZXRlY3Rpb24oKSxcbiAgICAgIHtwcm92aWRlOiBDb21waWxlciwgdXNlRmFjdG9yeTogKCkgPT4gbmV3IFIzVGVzdENvbXBpbGVyKHRoaXMpfSxcbiAgICAgIC4uLnRoaXMucHJvdmlkZXJzLFxuICAgICAgLi4udGhpcy5wcm92aWRlck92ZXJyaWRlcyxcbiAgICBdO1xuICAgIGNvbnN0IGltcG9ydHMgPSBbUm9vdFNjb3BlTW9kdWxlLCB0aGlzLmFkZGl0aW9uYWxNb2R1bGVUeXBlcywgdGhpcy5pbXBvcnRzIHx8IFtdXTtcblxuICAgIC8vIGNsYW5nLWZvcm1hdCBvZmZcbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKHRoaXMudGVzdE1vZHVsZVR5cGUsIHtcbiAgICAgIGRlY2xhcmF0aW9uczogdGhpcy5kZWNsYXJhdGlvbnMsXG4gICAgICBpbXBvcnRzLFxuICAgICAgc2NoZW1hczogdGhpcy5zY2hlbWFzLFxuICAgICAgcHJvdmlkZXJzLFxuICAgIH0sIC8qIGFsbG93RHVwbGljYXRlRGVjbGFyYXRpb25zSW5Sb290ICovIHRydWUpO1xuICAgIC8vIGNsYW5nLWZvcm1hdCBvblxuXG4gICAgdGhpcy5hcHBseVByb3ZpZGVyT3ZlcnJpZGVzSW5TY29wZSh0aGlzLnRlc3RNb2R1bGVUeXBlKTtcbiAgfVxuXG4gIGdldCBpbmplY3RvcigpOiBJbmplY3RvciB7XG4gICAgaWYgKHRoaXMuX2luamVjdG9yICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5faW5qZWN0b3I7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdmlkZXJzOiBQcm92aWRlcltdID0gW107XG4gICAgY29uc3QgY29tcGlsZXJPcHRpb25zID0gdGhpcy5wbGF0Zm9ybS5pbmplY3Rvci5nZXQoQ09NUElMRVJfT1BUSU9OUyk7XG4gICAgY29tcGlsZXJPcHRpb25zLmZvckVhY2gob3B0cyA9PiB7XG4gICAgICBpZiAob3B0cy5wcm92aWRlcnMpIHtcbiAgICAgICAgcHJvdmlkZXJzLnB1c2gob3B0cy5wcm92aWRlcnMpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICh0aGlzLmNvbXBpbGVyUHJvdmlkZXJzICE9PSBudWxsKSB7XG4gICAgICBwcm92aWRlcnMucHVzaCguLi50aGlzLmNvbXBpbGVyUHJvdmlkZXJzKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPKG9jb21iZSk6IG1ha2UgdGhpcyB3b3JrIHdpdGggYW4gSW5qZWN0b3IgZGlyZWN0bHkgaW5zdGVhZCBvZiBjcmVhdGluZyBhIG1vZHVsZSBmb3IgaXRcbiAgICBjbGFzcyBDb21waWxlck1vZHVsZSB7fVxuICAgIGNvbXBpbGVOZ01vZHVsZURlZnMoQ29tcGlsZXJNb2R1bGUgYXMgTmdNb2R1bGVUeXBlPGFueT4sIHtwcm92aWRlcnN9KTtcblxuICAgIGNvbnN0IENvbXBpbGVyTW9kdWxlRmFjdG9yeSA9IG5ldyBSM05nTW9kdWxlRmFjdG9yeShDb21waWxlck1vZHVsZSk7XG4gICAgdGhpcy5faW5qZWN0b3IgPSBDb21waWxlck1vZHVsZUZhY3RvcnkuY3JlYXRlKHRoaXMucGxhdGZvcm0uaW5qZWN0b3IpLmluamVjdG9yO1xuICAgIHJldHVybiB0aGlzLl9pbmplY3RvcjtcbiAgfVxuXG4gIC8vIGdldCBvdmVycmlkZXMgZm9yIGEgc3BlY2lmaWMgcHJvdmlkZXIgKGlmIGFueSlcbiAgcHJpdmF0ZSBnZXRTaW5nbGVQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcjogUHJvdmlkZXIpOiBQcm92aWRlcnxudWxsIHtcbiAgICBjb25zdCB0b2tlbiA9IGdldFByb3ZpZGVyVG9rZW4ocHJvdmlkZXIpO1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5nZXQodG9rZW4pIHx8IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldFByb3ZpZGVyT3ZlcnJpZGVzKHByb3ZpZGVycz86IEFycmF5PFByb3ZpZGVyfEludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnM+KTpcbiAgICAgIFByb3ZpZGVyW10ge1xuICAgIGlmICghcHJvdmlkZXJzIHx8ICFwcm92aWRlcnMubGVuZ3RoIHx8IHRoaXMucHJvdmlkZXJPdmVycmlkZXNCeVRva2VuLnNpemUgPT09IDApIHJldHVybiBbXTtcbiAgICAvLyBUaGVyZSBhcmUgdHdvIGZsYXR0ZW5pbmcgb3BlcmF0aW9ucyBoZXJlLiBUaGUgaW5uZXIgZmxhdHRlblByb3ZpZGVycygpIG9wZXJhdGVzIG9uIHRoZVxuICAgIC8vIG1ldGFkYXRhJ3MgcHJvdmlkZXJzIGFuZCBhcHBsaWVzIGEgbWFwcGluZyBmdW5jdGlvbiB3aGljaCByZXRyaWV2ZXMgb3ZlcnJpZGVzIGZvciBlYWNoXG4gICAgLy8gaW5jb21pbmcgcHJvdmlkZXIuIFRoZSBvdXRlciBmbGF0dGVuKCkgdGhlbiBmbGF0dGVucyB0aGUgcHJvZHVjZWQgb3ZlcnJpZGVzIGFycmF5LiBJZiB0aGlzIGlzXG4gICAgLy8gbm90IGRvbmUsIHRoZSBhcnJheSBjYW4gY29udGFpbiBvdGhlciBlbXB0eSBhcnJheXMgKGUuZy4gYFtbXSwgW11dYCkgd2hpY2ggbGVhayBpbnRvIHRoZVxuICAgIC8vIHByb3ZpZGVycyBhcnJheSBhbmQgY29udGFtaW5hdGUgYW55IGVycm9yIG1lc3NhZ2VzIHRoYXQgbWlnaHQgYmUgZ2VuZXJhdGVkLlxuICAgIHJldHVybiBmbGF0dGVuKGZsYXR0ZW5Qcm92aWRlcnMoXG4gICAgICAgIHByb3ZpZGVycywgKHByb3ZpZGVyOiBQcm92aWRlcikgPT4gdGhpcy5nZXRTaW5nbGVQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcikgfHwgW10pKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3ZlcnJpZGRlblByb3ZpZGVycyhwcm92aWRlcnM/OiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPik6XG4gICAgICBQcm92aWRlcltdIHtcbiAgICBpZiAoIXByb3ZpZGVycyB8fCAhcHJvdmlkZXJzLmxlbmd0aCB8fCB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zaXplID09PSAwKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBmbGF0dGVuZWRQcm92aWRlcnMgPSBmbGF0dGVuUHJvdmlkZXJzKHByb3ZpZGVycyk7XG4gICAgY29uc3Qgb3ZlcnJpZGVzID0gdGhpcy5nZXRQcm92aWRlck92ZXJyaWRlcyhmbGF0dGVuZWRQcm92aWRlcnMpO1xuICAgIGNvbnN0IG92ZXJyaWRkZW5Qcm92aWRlcnMgPSBbLi4uZmxhdHRlbmVkUHJvdmlkZXJzLCAuLi5vdmVycmlkZXNdO1xuICAgIGNvbnN0IGZpbmFsOiBQcm92aWRlcltdID0gW107XG4gICAgY29uc3Qgc2Vlbk92ZXJyaWRkZW5Qcm92aWRlcnMgPSBuZXcgU2V0PFByb3ZpZGVyPigpO1xuXG4gICAgLy8gV2UgaXRlcmF0ZSB0aHJvdWdoIHRoZSBsaXN0IG9mIHByb3ZpZGVycyBpbiByZXZlcnNlIG9yZGVyIHRvIG1ha2Ugc3VyZSBwcm92aWRlciBvdmVycmlkZXNcbiAgICAvLyB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGUgdmFsdWVzIGRlZmluZWQgaW4gcHJvdmlkZXIgbGlzdC4gV2UgYWxzbyBmaWx0ZXIgb3V0IGFsbCBwcm92aWRlcnNcbiAgICAvLyB0aGF0IGhhdmUgb3ZlcnJpZGVzLCBrZWVwaW5nIG92ZXJyaWRkZW4gdmFsdWVzIG9ubHkuIFRoaXMgaXMgbmVlZGVkLCBzaW5jZSBwcmVzZW5jZSBvZiBhXG4gICAgLy8gcHJvdmlkZXIgd2l0aCBgbmdPbkRlc3Ryb3lgIGhvb2sgd2lsbCBjYXVzZSB0aGlzIGhvb2sgdG8gYmUgcmVnaXN0ZXJlZCBhbmQgaW52b2tlZCBsYXRlci5cbiAgICBmb3JFYWNoUmlnaHQob3ZlcnJpZGRlblByb3ZpZGVycywgKHByb3ZpZGVyOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHRva2VuOiBhbnkgPSBnZXRQcm92aWRlclRva2VuKHByb3ZpZGVyKTtcbiAgICAgIGlmICh0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5oYXModG9rZW4pKSB7XG4gICAgICAgIGlmICghc2Vlbk92ZXJyaWRkZW5Qcm92aWRlcnMuaGFzKHRva2VuKSkge1xuICAgICAgICAgIHNlZW5PdmVycmlkZGVuUHJvdmlkZXJzLmFkZCh0b2tlbik7XG4gICAgICAgICAgLy8gVHJlYXQgYWxsIG92ZXJyaWRkZW4gcHJvdmlkZXJzIGFzIGB7bXVsdGk6IGZhbHNlfWAgKGV2ZW4gaWYgaXQncyBhIG11bHRpLXByb3ZpZGVyKSB0b1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHByb3ZpZGVkIG92ZXJyaWRlIHRha2VzIGhpZ2hlc3QgcHJlY2VkZW5jZSBhbmQgaXMgbm90IGNvbWJpbmVkIHdpdGhcbiAgICAgICAgICAvLyBvdGhlciBpbnN0YW5jZXMgb2YgdGhlIHNhbWUgbXVsdGkgcHJvdmlkZXIuXG4gICAgICAgICAgZmluYWwudW5zaGlmdCh7Li4ucHJvdmlkZXIsIG11bHRpOiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaW5hbC51bnNoaWZ0KHByb3ZpZGVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZmluYWw7XG4gIH1cblxuICBwcml2YXRlIGhhc1Byb3ZpZGVyT3ZlcnJpZGVzKHByb3ZpZGVycz86IEFycmF5PFByb3ZpZGVyfEludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnM+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UHJvdmlkZXJPdmVycmlkZXMocHJvdmlkZXJzKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXRjaERlZldpdGhQcm92aWRlck92ZXJyaWRlcyhkZWNsYXJhdGlvbjogVHlwZTxhbnk+LCBmaWVsZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZGVmID0gKGRlY2xhcmF0aW9uIGFzIGFueSlbZmllbGRdO1xuICAgIGlmIChkZWYgJiYgZGVmLnByb3ZpZGVyc1Jlc29sdmVyKSB7XG4gICAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihmaWVsZCwgZGVjbGFyYXRpb24pO1xuXG4gICAgICBjb25zdCByZXNvbHZlciA9IGRlZi5wcm92aWRlcnNSZXNvbHZlcjtcbiAgICAgIGNvbnN0IHByb2Nlc3NQcm92aWRlcnNGbiA9IChwcm92aWRlcnM6IFByb3ZpZGVyW10pID0+IHRoaXMuZ2V0T3ZlcnJpZGRlblByb3ZpZGVycyhwcm92aWRlcnMpO1xuICAgICAgdGhpcy5zdG9yZUZpZWxkT2ZEZWZPblR5cGUoZGVjbGFyYXRpb24sIGZpZWxkLCAncHJvdmlkZXJzUmVzb2x2ZXInKTtcbiAgICAgIGRlZi5wcm92aWRlcnNSZXNvbHZlciA9IChuZ0RlZjogRGlyZWN0aXZlRGVmPGFueT4pID0+IHJlc29sdmVyKG5nRGVmLCBwcm9jZXNzUHJvdmlkZXJzRm4pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0UmVzb2x2ZXJzKCk6IFJlc29sdmVycyB7XG4gIHJldHVybiB7XG4gICAgbW9kdWxlOiBuZXcgTmdNb2R1bGVSZXNvbHZlcigpLFxuICAgIGNvbXBvbmVudDogbmV3IENvbXBvbmVudFJlc29sdmVyKCksXG4gICAgZGlyZWN0aXZlOiBuZXcgRGlyZWN0aXZlUmVzb2x2ZXIoKSxcbiAgICBwaXBlOiBuZXcgUGlwZVJlc29sdmVyKClcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNTdGFuZGFsb25lQ29tcG9uZW50PFQ+KHZhbHVlOiBUeXBlPFQ+KTogdmFsdWUgaXMgQ29tcG9uZW50VHlwZTxUPiB7XG4gIGNvbnN0IGRlZiA9IGdldENvbXBvbmVudERlZih2YWx1ZSk7XG4gIHJldHVybiAhIWRlZj8uc3RhbmRhbG9uZTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tcG9uZW50RGVmKHZhbHVlOiBDb21wb25lbnRUeXBlPHVua25vd24+KTogQ29tcG9uZW50RGVmPHVua25vd24+O1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50RGVmKHZhbHVlOiBUeXBlPHVua25vd24+KTogQ29tcG9uZW50RGVmPHVua25vd24+fG51bGw7XG5mdW5jdGlvbiBnZXRDb21wb25lbnREZWYodmFsdWU6IFR5cGU8dW5rbm93bj4pOiBDb21wb25lbnREZWY8dW5rbm93bj58bnVsbCB7XG4gIHJldHVybiAodmFsdWUgYXMgYW55KS7JtWNtcCA/PyBudWxsO1xufVxuXG5mdW5jdGlvbiBoYXNOZ01vZHVsZURlZjxUPih2YWx1ZTogVHlwZTxUPik6IHZhbHVlIGlzIE5nTW9kdWxlVHlwZTxUPiB7XG4gIHJldHVybiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnybVtb2QnKTtcbn1cblxuZnVuY3Rpb24gaXNOZ01vZHVsZTxUPih2YWx1ZTogVHlwZTxUPik6IGJvb2xlYW4ge1xuICByZXR1cm4gaGFzTmdNb2R1bGVEZWYodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBtYXliZVVud3JhcEZuPFQ+KG1heWJlRm46ICgoKSA9PiBUKXxUKTogVCB7XG4gIHJldHVybiBtYXliZUZuIGluc3RhbmNlb2YgRnVuY3Rpb24gPyBtYXliZUZuKCkgOiBtYXliZUZuO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuPFQ+KHZhbHVlczogYW55W10pOiBUW10ge1xuICBjb25zdCBvdXQ6IFRbXSA9IFtdO1xuICB2YWx1ZXMuZm9yRWFjaCh2YWx1ZSA9PiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICBvdXQucHVzaCguLi5mbGF0dGVuPFQ+KHZhbHVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dC5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBpZGVudGl0eUZuPFQ+KHZhbHVlOiBUKTogVCB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gZmxhdHRlblByb3ZpZGVyczxUPihcbiAgICBwcm92aWRlcnM6IEFycmF5PFByb3ZpZGVyfEludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnM+LCBtYXBGbjogKHByb3ZpZGVyOiBQcm92aWRlcikgPT4gVCk6IFRbXTtcbmZ1bmN0aW9uIGZsYXR0ZW5Qcm92aWRlcnMocHJvdmlkZXJzOiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPik6IFByb3ZpZGVyW107XG5mdW5jdGlvbiBmbGF0dGVuUHJvdmlkZXJzKFxuICAgIHByb3ZpZGVyczogQXJyYXk8UHJvdmlkZXJ8SW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycz4sXG4gICAgbWFwRm46IChwcm92aWRlcjogUHJvdmlkZXIpID0+IGFueSA9IGlkZW50aXR5Rm4pOiBhbnlbXSB7XG4gIGNvbnN0IG91dDogYW55W10gPSBbXTtcbiAgZm9yIChsZXQgcHJvdmlkZXIgb2YgcHJvdmlkZXJzKSB7XG4gICAgaWYgKGlzRW52aXJvbm1lbnRQcm92aWRlcnMocHJvdmlkZXIpKSB7XG4gICAgICBwcm92aWRlciA9IHByb3ZpZGVyLsm1cHJvdmlkZXJzO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwcm92aWRlcikpIHtcbiAgICAgIG91dC5wdXNoKC4uLmZsYXR0ZW5Qcm92aWRlcnMocHJvdmlkZXIsIG1hcEZuKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dC5wdXNoKG1hcEZuKHByb3ZpZGVyKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGdldFByb3ZpZGVyRmllbGQocHJvdmlkZXI6IFByb3ZpZGVyLCBmaWVsZDogc3RyaW5nKSB7XG4gIHJldHVybiBwcm92aWRlciAmJiB0eXBlb2YgcHJvdmlkZXIgPT09ICdvYmplY3QnICYmIChwcm92aWRlciBhcyBhbnkpW2ZpZWxkXTtcbn1cblxuZnVuY3Rpb24gZ2V0UHJvdmlkZXJUb2tlbihwcm92aWRlcjogUHJvdmlkZXIpIHtcbiAgcmV0dXJuIGdldFByb3ZpZGVyRmllbGQocHJvdmlkZXIsICdwcm92aWRlJykgfHwgcHJvdmlkZXI7XG59XG5cbmZ1bmN0aW9uIGlzTW9kdWxlV2l0aFByb3ZpZGVycyh2YWx1ZTogYW55KTogdmFsdWUgaXMgTW9kdWxlV2l0aFByb3ZpZGVyczxhbnk+IHtcbiAgcmV0dXJuIHZhbHVlLmhhc093blByb3BlcnR5KCduZ01vZHVsZScpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoUmlnaHQ8VD4odmFsdWVzOiBUW10sIGZuOiAodmFsdWU6IFQsIGlkeDogbnVtYmVyKSA9PiB2b2lkKTogdm9pZCB7XG4gIGZvciAobGV0IGlkeCA9IHZhbHVlcy5sZW5ndGggLSAxOyBpZHggPj0gMDsgaWR4LS0pIHtcbiAgICBmbih2YWx1ZXNbaWR4XSwgaWR4KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZhbGlkVHlwZUVycm9yKG5hbWU6IHN0cmluZywgZXhwZWN0ZWRUeXBlOiBzdHJpbmcpOiBFcnJvciB7XG4gIHJldHVybiBuZXcgRXJyb3IoYCR7bmFtZX0gY2xhc3MgZG9lc24ndCBoYXZlIEAke2V4cGVjdGVkVHlwZX0gZGVjb3JhdG9yIG9yIGlzIG1pc3NpbmcgbWV0YWRhdGEuYCk7XG59XG5cbmNsYXNzIFIzVGVzdENvbXBpbGVyIGltcGxlbWVudHMgQ29tcGlsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRlc3RCZWQ6IFRlc3RCZWRDb21waWxlcikge31cblxuICBjb21waWxlTW9kdWxlU3luYzxUPihtb2R1bGVUeXBlOiBUeXBlPFQ+KTogTmdNb2R1bGVGYWN0b3J5PFQ+IHtcbiAgICB0aGlzLnRlc3RCZWQuX2NvbXBpbGVOZ01vZHVsZVN5bmMobW9kdWxlVHlwZSk7XG4gICAgcmV0dXJuIG5ldyBSM05nTW9kdWxlRmFjdG9yeShtb2R1bGVUeXBlKTtcbiAgfVxuXG4gIGFzeW5jIGNvbXBpbGVNb2R1bGVBc3luYzxUPihtb2R1bGVUeXBlOiBUeXBlPFQ+KTogUHJvbWlzZTxOZ01vZHVsZUZhY3Rvcnk8VD4+IHtcbiAgICBhd2FpdCB0aGlzLnRlc3RCZWQuX2NvbXBpbGVOZ01vZHVsZUFzeW5jKG1vZHVsZVR5cGUpO1xuICAgIHJldHVybiBuZXcgUjNOZ01vZHVsZUZhY3RvcnkobW9kdWxlVHlwZSk7XG4gIH1cblxuICBjb21waWxlTW9kdWxlQW5kQWxsQ29tcG9uZW50c1N5bmM8VD4obW9kdWxlVHlwZTogVHlwZTxUPik6IE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXM8VD4ge1xuICAgIGNvbnN0IG5nTW9kdWxlRmFjdG9yeSA9IHRoaXMuY29tcGlsZU1vZHVsZVN5bmMobW9kdWxlVHlwZSk7XG4gICAgY29uc3QgY29tcG9uZW50RmFjdG9yaWVzID0gdGhpcy50ZXN0QmVkLl9nZXRDb21wb25lbnRGYWN0b3JpZXMobW9kdWxlVHlwZSBhcyBOZ01vZHVsZVR5cGU8VD4pO1xuICAgIHJldHVybiBuZXcgTW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllcyhuZ01vZHVsZUZhY3RvcnksIGNvbXBvbmVudEZhY3Rvcmllcyk7XG4gIH1cblxuICBhc3luYyBjb21waWxlTW9kdWxlQW5kQWxsQ29tcG9uZW50c0FzeW5jPFQ+KG1vZHVsZVR5cGU6IFR5cGU8VD4pOlxuICAgICAgUHJvbWlzZTxNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzPFQ+PiB7XG4gICAgY29uc3QgbmdNb2R1bGVGYWN0b3J5ID0gYXdhaXQgdGhpcy5jb21waWxlTW9kdWxlQXN5bmMobW9kdWxlVHlwZSk7XG4gICAgY29uc3QgY29tcG9uZW50RmFjdG9yaWVzID0gdGhpcy50ZXN0QmVkLl9nZXRDb21wb25lbnRGYWN0b3JpZXMobW9kdWxlVHlwZSBhcyBOZ01vZHVsZVR5cGU8VD4pO1xuICAgIHJldHVybiBuZXcgTW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllcyhuZ01vZHVsZUZhY3RvcnksIGNvbXBvbmVudEZhY3Rvcmllcyk7XG4gIH1cblxuICBjbGVhckNhY2hlKCk6IHZvaWQge31cblxuICBjbGVhckNhY2hlRm9yKHR5cGU6IFR5cGU8YW55Pik6IHZvaWQge31cblxuICBnZXRNb2R1bGVJZChtb2R1bGVUeXBlOiBUeXBlPGFueT4pOiBzdHJpbmd8dW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy50ZXN0QmVkLl9nZXRNb2R1bGVSZXNvbHZlcigpLnJlc29sdmUobW9kdWxlVHlwZSk7XG4gICAgcmV0dXJuIG1ldGEgJiYgbWV0YS5pZCB8fCB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|