@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
|
@@ -1,961 +0,0 @@
|
|
|
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 { ViewEncapsulation } from '../metadata/view';
|
|
9
|
-
import { RendererStyleFlags2 } from '../render/api_flags';
|
|
10
|
-
import { addToArray, removeFromArray } from '../util/array_utils';
|
|
11
|
-
import { assertDefined, assertEqual, assertFunction, assertNumber, assertString } from '../util/assert';
|
|
12
|
-
import { escapeCommentText } from '../util/dom';
|
|
13
|
-
import { assertLContainer, assertLView, assertParentView, assertProjectionSlots, assertTNodeForLView } from './assert';
|
|
14
|
-
import { attachPatchData } from './context_discovery';
|
|
15
|
-
import { icuContainerIterate } from './i18n/i18n_tree_shaking';
|
|
16
|
-
import { CONTAINER_HEADER_OFFSET, HAS_TRANSPLANTED_VIEWS, MOVED_VIEWS, NATIVE } from './interfaces/container';
|
|
17
|
-
import { NodeInjectorFactory } from './interfaces/injector';
|
|
18
|
-
import { unregisterLView } from './interfaces/lview_tracking';
|
|
19
|
-
import { isLContainer, isLView } from './interfaces/type_checks';
|
|
20
|
-
import { CHILD_HEAD, CLEANUP, DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, FLAGS, HOST, NEXT, ON_DESTROY_HOOKS, PARENT, QUERIES, RENDERER, T_HOST, TVIEW } from './interfaces/view';
|
|
21
|
-
import { assertTNodeType } from './node_assert';
|
|
22
|
-
import { profiler } from './profiler';
|
|
23
|
-
import { setUpAttributes } from './util/attrs_utils';
|
|
24
|
-
import { getLViewParent } from './util/view_traversal_utils';
|
|
25
|
-
import { getNativeByTNode, unwrapRNode, updateTransplantedViewCount } from './util/view_utils';
|
|
26
|
-
/**
|
|
27
|
-
* NOTE: for performance reasons, the possible actions are inlined within the function instead of
|
|
28
|
-
* being passed as an argument.
|
|
29
|
-
*/
|
|
30
|
-
function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
|
|
31
|
-
// If this slot was allocated for a text node dynamically created by i18n, the text node itself
|
|
32
|
-
// won't be created until i18nApply() in the update block, so this node should be skipped.
|
|
33
|
-
// For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
|
|
34
|
-
// in `i18n_spec.ts`.
|
|
35
|
-
if (lNodeToHandle != null) {
|
|
36
|
-
let lContainer;
|
|
37
|
-
let isComponent = false;
|
|
38
|
-
// We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
|
|
39
|
-
// wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
|
|
40
|
-
// it has LContainer so that we can process all of those cases appropriately.
|
|
41
|
-
if (isLContainer(lNodeToHandle)) {
|
|
42
|
-
lContainer = lNodeToHandle;
|
|
43
|
-
}
|
|
44
|
-
else if (isLView(lNodeToHandle)) {
|
|
45
|
-
isComponent = true;
|
|
46
|
-
ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
|
|
47
|
-
lNodeToHandle = lNodeToHandle[HOST];
|
|
48
|
-
}
|
|
49
|
-
const rNode = unwrapRNode(lNodeToHandle);
|
|
50
|
-
if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
|
|
51
|
-
if (beforeNode == null) {
|
|
52
|
-
nativeAppendChild(renderer, parent, rNode);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
|
|
59
|
-
nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
|
|
60
|
-
}
|
|
61
|
-
else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
|
|
62
|
-
nativeRemoveNode(renderer, rNode, isComponent);
|
|
63
|
-
}
|
|
64
|
-
else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
|
|
65
|
-
ngDevMode && ngDevMode.rendererDestroyNode++;
|
|
66
|
-
renderer.destroyNode(rNode);
|
|
67
|
-
}
|
|
68
|
-
if (lContainer != null) {
|
|
69
|
-
applyContainer(renderer, action, lContainer, parent, beforeNode);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export function createTextNode(renderer, value) {
|
|
74
|
-
ngDevMode && ngDevMode.rendererCreateTextNode++;
|
|
75
|
-
ngDevMode && ngDevMode.rendererSetText++;
|
|
76
|
-
return renderer.createText(value);
|
|
77
|
-
}
|
|
78
|
-
export function updateTextNode(renderer, rNode, value) {
|
|
79
|
-
ngDevMode && ngDevMode.rendererSetText++;
|
|
80
|
-
renderer.setValue(rNode, value);
|
|
81
|
-
}
|
|
82
|
-
export function createCommentNode(renderer, value) {
|
|
83
|
-
ngDevMode && ngDevMode.rendererCreateComment++;
|
|
84
|
-
return renderer.createComment(escapeCommentText(value));
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Creates a native element from a tag name, using a renderer.
|
|
88
|
-
* @param renderer A renderer to use
|
|
89
|
-
* @param name the tag name
|
|
90
|
-
* @param namespace Optional namespace for element.
|
|
91
|
-
* @returns the element created
|
|
92
|
-
*/
|
|
93
|
-
export function createElementNode(renderer, name, namespace) {
|
|
94
|
-
ngDevMode && ngDevMode.rendererCreateElement++;
|
|
95
|
-
return renderer.createElement(name, namespace);
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Removes all DOM elements associated with a view.
|
|
99
|
-
*
|
|
100
|
-
* Because some root nodes of the view may be containers, we sometimes need
|
|
101
|
-
* to propagate deeply into the nested containers to remove all elements in the
|
|
102
|
-
* views beneath it.
|
|
103
|
-
*
|
|
104
|
-
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
105
|
-
* @param lView The view from which elements should be added or removed
|
|
106
|
-
*/
|
|
107
|
-
export function removeViewFromContainer(tView, lView) {
|
|
108
|
-
const renderer = lView[RENDERER];
|
|
109
|
-
applyView(tView, lView, renderer, 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
110
|
-
lView[HOST] = null;
|
|
111
|
-
lView[T_HOST] = null;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Adds all DOM elements associated with a view.
|
|
115
|
-
*
|
|
116
|
-
* Because some root nodes of the view may be containers, we sometimes need
|
|
117
|
-
* to propagate deeply into the nested containers to add all elements in the
|
|
118
|
-
* views beneath it.
|
|
119
|
-
*
|
|
120
|
-
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
121
|
-
* @param parentTNode The `TNode` where the `LView` should be attached to.
|
|
122
|
-
* @param renderer Current renderer to use for DOM manipulations.
|
|
123
|
-
* @param lView The view from which elements should be added or removed
|
|
124
|
-
* @param parentNativeNode The parent `RElement` where it should be inserted into.
|
|
125
|
-
* @param beforeNode The node before which elements should be added, if insert mode
|
|
126
|
-
*/
|
|
127
|
-
export function addViewToContainer(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
|
|
128
|
-
lView[HOST] = parentNativeNode;
|
|
129
|
-
lView[T_HOST] = parentTNode;
|
|
130
|
-
applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Detach a `LView` from the DOM by detaching its nodes.
|
|
134
|
-
*
|
|
135
|
-
* @param tView The `TView' of the `LView` to be detached
|
|
136
|
-
* @param lView the `LView` to be detached.
|
|
137
|
-
*/
|
|
138
|
-
export function renderDetachView(tView, lView) {
|
|
139
|
-
applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Traverses down and up the tree of views and containers to remove listeners and
|
|
143
|
-
* call onDestroy callbacks.
|
|
144
|
-
*
|
|
145
|
-
* Notes:
|
|
146
|
-
* - Because it's used for onDestroy calls, it needs to be bottom-up.
|
|
147
|
-
* - Must process containers instead of their views to avoid splicing
|
|
148
|
-
* when views are destroyed and re-added.
|
|
149
|
-
* - Using a while loop because it's faster than recursion
|
|
150
|
-
* - Destroy only called on movement to sibling or movement to parent (laterally or up)
|
|
151
|
-
*
|
|
152
|
-
* @param rootView The view to destroy
|
|
153
|
-
*/
|
|
154
|
-
export function destroyViewTree(rootView) {
|
|
155
|
-
// If the view has no children, we can clean it up and return early.
|
|
156
|
-
let lViewOrLContainer = rootView[CHILD_HEAD];
|
|
157
|
-
if (!lViewOrLContainer) {
|
|
158
|
-
return cleanUpView(rootView[TVIEW], rootView);
|
|
159
|
-
}
|
|
160
|
-
while (lViewOrLContainer) {
|
|
161
|
-
let next = null;
|
|
162
|
-
if (isLView(lViewOrLContainer)) {
|
|
163
|
-
// If LView, traverse down to child.
|
|
164
|
-
next = lViewOrLContainer[CHILD_HEAD];
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
ngDevMode && assertLContainer(lViewOrLContainer);
|
|
168
|
-
// If container, traverse down to its first LView.
|
|
169
|
-
const firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
|
|
170
|
-
if (firstView)
|
|
171
|
-
next = firstView;
|
|
172
|
-
}
|
|
173
|
-
if (!next) {
|
|
174
|
-
// Only clean up view when moving to the side or up, as destroy hooks
|
|
175
|
-
// should be called in order from the bottom up.
|
|
176
|
-
while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
|
|
177
|
-
if (isLView(lViewOrLContainer)) {
|
|
178
|
-
cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
|
|
179
|
-
}
|
|
180
|
-
lViewOrLContainer = lViewOrLContainer[PARENT];
|
|
181
|
-
}
|
|
182
|
-
if (lViewOrLContainer === null)
|
|
183
|
-
lViewOrLContainer = rootView;
|
|
184
|
-
if (isLView(lViewOrLContainer)) {
|
|
185
|
-
cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
|
|
186
|
-
}
|
|
187
|
-
next = lViewOrLContainer && lViewOrLContainer[NEXT];
|
|
188
|
-
}
|
|
189
|
-
lViewOrLContainer = next;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Inserts a view into a container.
|
|
194
|
-
*
|
|
195
|
-
* This adds the view to the container's array of active views in the correct
|
|
196
|
-
* position. It also adds the view's elements to the DOM if the container isn't a
|
|
197
|
-
* root node of another view (in that case, the view's elements will be added when
|
|
198
|
-
* the container's parent view is added later).
|
|
199
|
-
*
|
|
200
|
-
* @param tView The `TView' of the `LView` to insert
|
|
201
|
-
* @param lView The view to insert
|
|
202
|
-
* @param lContainer The container into which the view should be inserted
|
|
203
|
-
* @param index Which index in the container to insert the child view into
|
|
204
|
-
*/
|
|
205
|
-
export function insertView(tView, lView, lContainer, index) {
|
|
206
|
-
ngDevMode && assertLView(lView);
|
|
207
|
-
ngDevMode && assertLContainer(lContainer);
|
|
208
|
-
const indexInContainer = CONTAINER_HEADER_OFFSET + index;
|
|
209
|
-
const containerLength = lContainer.length;
|
|
210
|
-
if (index > 0) {
|
|
211
|
-
// This is a new view, we need to add it to the children.
|
|
212
|
-
lContainer[indexInContainer - 1][NEXT] = lView;
|
|
213
|
-
}
|
|
214
|
-
if (index < containerLength - CONTAINER_HEADER_OFFSET) {
|
|
215
|
-
lView[NEXT] = lContainer[indexInContainer];
|
|
216
|
-
addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
lContainer.push(lView);
|
|
220
|
-
lView[NEXT] = null;
|
|
221
|
-
}
|
|
222
|
-
lView[PARENT] = lContainer;
|
|
223
|
-
// track views where declaration and insertion points are different
|
|
224
|
-
const declarationLContainer = lView[DECLARATION_LCONTAINER];
|
|
225
|
-
if (declarationLContainer !== null && lContainer !== declarationLContainer) {
|
|
226
|
-
trackMovedView(declarationLContainer, lView);
|
|
227
|
-
}
|
|
228
|
-
// notify query that a new view has been added
|
|
229
|
-
const lQueries = lView[QUERIES];
|
|
230
|
-
if (lQueries !== null) {
|
|
231
|
-
lQueries.insertView(tView);
|
|
232
|
-
}
|
|
233
|
-
// Sets the attached flag
|
|
234
|
-
lView[FLAGS] |= 64 /* LViewFlags.Attached */;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Track views created from the declaration container (TemplateRef) and inserted into a
|
|
238
|
-
* different LContainer.
|
|
239
|
-
*/
|
|
240
|
-
function trackMovedView(declarationContainer, lView) {
|
|
241
|
-
ngDevMode && assertDefined(lView, 'LView required');
|
|
242
|
-
ngDevMode && assertLContainer(declarationContainer);
|
|
243
|
-
const movedViews = declarationContainer[MOVED_VIEWS];
|
|
244
|
-
const insertedLContainer = lView[PARENT];
|
|
245
|
-
ngDevMode && assertLContainer(insertedLContainer);
|
|
246
|
-
const insertedComponentLView = insertedLContainer[PARENT][DECLARATION_COMPONENT_VIEW];
|
|
247
|
-
ngDevMode && assertDefined(insertedComponentLView, 'Missing insertedComponentLView');
|
|
248
|
-
const declaredComponentLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
249
|
-
ngDevMode && assertDefined(declaredComponentLView, 'Missing declaredComponentLView');
|
|
250
|
-
if (declaredComponentLView !== insertedComponentLView) {
|
|
251
|
-
// At this point the declaration-component is not same as insertion-component; this means that
|
|
252
|
-
// this is a transplanted view. Mark the declared lView as having transplanted views so that
|
|
253
|
-
// those views can participate in CD.
|
|
254
|
-
declarationContainer[HAS_TRANSPLANTED_VIEWS] = true;
|
|
255
|
-
}
|
|
256
|
-
if (movedViews === null) {
|
|
257
|
-
declarationContainer[MOVED_VIEWS] = [lView];
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
movedViews.push(lView);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
function detachMovedView(declarationContainer, lView) {
|
|
264
|
-
ngDevMode && assertLContainer(declarationContainer);
|
|
265
|
-
ngDevMode &&
|
|
266
|
-
assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
|
|
267
|
-
const movedViews = declarationContainer[MOVED_VIEWS];
|
|
268
|
-
const declarationViewIndex = movedViews.indexOf(lView);
|
|
269
|
-
const insertionLContainer = lView[PARENT];
|
|
270
|
-
ngDevMode && assertLContainer(insertionLContainer);
|
|
271
|
-
// If the view was marked for refresh but then detached before it was checked (where the flag
|
|
272
|
-
// would be cleared and the counter decremented), we need to decrement the view counter here
|
|
273
|
-
// instead.
|
|
274
|
-
if (lView[FLAGS] & 512 /* LViewFlags.RefreshTransplantedView */) {
|
|
275
|
-
lView[FLAGS] &= ~512 /* LViewFlags.RefreshTransplantedView */;
|
|
276
|
-
updateTransplantedViewCount(insertionLContainer, -1);
|
|
277
|
-
}
|
|
278
|
-
movedViews.splice(declarationViewIndex, 1);
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Detaches a view from a container.
|
|
282
|
-
*
|
|
283
|
-
* This method removes the view from the container's array of active views. It also
|
|
284
|
-
* removes the view's elements from the DOM.
|
|
285
|
-
*
|
|
286
|
-
* @param lContainer The container from which to detach a view
|
|
287
|
-
* @param removeIndex The index of the view to detach
|
|
288
|
-
* @returns Detached LView instance.
|
|
289
|
-
*/
|
|
290
|
-
export function detachView(lContainer, removeIndex) {
|
|
291
|
-
if (lContainer.length <= CONTAINER_HEADER_OFFSET)
|
|
292
|
-
return;
|
|
293
|
-
const indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;
|
|
294
|
-
const viewToDetach = lContainer[indexInContainer];
|
|
295
|
-
if (viewToDetach) {
|
|
296
|
-
const declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];
|
|
297
|
-
if (declarationLContainer !== null && declarationLContainer !== lContainer) {
|
|
298
|
-
detachMovedView(declarationLContainer, viewToDetach);
|
|
299
|
-
}
|
|
300
|
-
if (removeIndex > 0) {
|
|
301
|
-
lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
|
|
302
|
-
}
|
|
303
|
-
const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
|
|
304
|
-
removeViewFromContainer(viewToDetach[TVIEW], viewToDetach);
|
|
305
|
-
// notify query that a view has been removed
|
|
306
|
-
const lQueries = removedLView[QUERIES];
|
|
307
|
-
if (lQueries !== null) {
|
|
308
|
-
lQueries.detachView(removedLView[TVIEW]);
|
|
309
|
-
}
|
|
310
|
-
viewToDetach[PARENT] = null;
|
|
311
|
-
viewToDetach[NEXT] = null;
|
|
312
|
-
// Unsets the attached flag
|
|
313
|
-
viewToDetach[FLAGS] &= ~64 /* LViewFlags.Attached */;
|
|
314
|
-
}
|
|
315
|
-
return viewToDetach;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* A standalone function which destroys an LView,
|
|
319
|
-
* conducting clean up (e.g. removing listeners, calling onDestroys).
|
|
320
|
-
*
|
|
321
|
-
* @param tView The `TView' of the `LView` to be destroyed
|
|
322
|
-
* @param lView The view to be destroyed.
|
|
323
|
-
*/
|
|
324
|
-
export function destroyLView(tView, lView) {
|
|
325
|
-
if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
|
|
326
|
-
const renderer = lView[RENDERER];
|
|
327
|
-
if (renderer.destroyNode) {
|
|
328
|
-
applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
|
|
329
|
-
}
|
|
330
|
-
destroyViewTree(lView);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Calls onDestroys hooks for all directives and pipes in a given view and then removes all
|
|
335
|
-
* listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
|
|
336
|
-
* can be propagated to @Output listeners.
|
|
337
|
-
*
|
|
338
|
-
* @param tView `TView` for the `LView` to clean up.
|
|
339
|
-
* @param lView The LView to clean up
|
|
340
|
-
*/
|
|
341
|
-
function cleanUpView(tView, lView) {
|
|
342
|
-
if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
|
|
343
|
-
// Usually the Attached flag is removed when the view is detached from its parent, however
|
|
344
|
-
// if it's a root view, the flag won't be unset hence why we're also removing on destroy.
|
|
345
|
-
lView[FLAGS] &= ~64 /* LViewFlags.Attached */;
|
|
346
|
-
// Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
|
|
347
|
-
// runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
|
|
348
|
-
// We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
|
|
349
|
-
// This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
|
|
350
|
-
// really more of an "afterDestroy" hook if you think about it.
|
|
351
|
-
lView[FLAGS] |= 128 /* LViewFlags.Destroyed */;
|
|
352
|
-
executeOnDestroys(tView, lView);
|
|
353
|
-
processCleanups(tView, lView);
|
|
354
|
-
// For component views only, the local renderer is destroyed at clean up time.
|
|
355
|
-
if (lView[TVIEW].type === 1 /* TViewType.Component */) {
|
|
356
|
-
ngDevMode && ngDevMode.rendererDestroy++;
|
|
357
|
-
lView[RENDERER].destroy();
|
|
358
|
-
}
|
|
359
|
-
const declarationContainer = lView[DECLARATION_LCONTAINER];
|
|
360
|
-
// we are dealing with an embedded view that is still inserted into a container
|
|
361
|
-
if (declarationContainer !== null && isLContainer(lView[PARENT])) {
|
|
362
|
-
// and this is a projected view
|
|
363
|
-
if (declarationContainer !== lView[PARENT]) {
|
|
364
|
-
detachMovedView(declarationContainer, lView);
|
|
365
|
-
}
|
|
366
|
-
// For embedded views still attached to a container: remove query result from this view.
|
|
367
|
-
const lQueries = lView[QUERIES];
|
|
368
|
-
if (lQueries !== null) {
|
|
369
|
-
lQueries.detachView(tView);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
// Unregister the view once everything else has been cleaned up.
|
|
373
|
-
unregisterLView(lView);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
/** Removes listeners and unsubscribes from output subscriptions */
|
|
377
|
-
function processCleanups(tView, lView) {
|
|
378
|
-
const tCleanup = tView.cleanup;
|
|
379
|
-
const lCleanup = lView[CLEANUP];
|
|
380
|
-
if (tCleanup !== null) {
|
|
381
|
-
for (let i = 0; i < tCleanup.length - 1; i += 2) {
|
|
382
|
-
if (typeof tCleanup[i] === 'string') {
|
|
383
|
-
// This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i +=
|
|
384
|
-
// 2 at the end of this block).
|
|
385
|
-
const targetIdx = tCleanup[i + 3];
|
|
386
|
-
ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
|
|
387
|
-
if (targetIdx >= 0) {
|
|
388
|
-
// unregister
|
|
389
|
-
lCleanup[targetIdx]();
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
// Subscription
|
|
393
|
-
lCleanup[-targetIdx].unsubscribe();
|
|
394
|
-
}
|
|
395
|
-
i += 2;
|
|
396
|
-
}
|
|
397
|
-
else {
|
|
398
|
-
// This is a cleanup function that is grouped with the index of its context
|
|
399
|
-
const context = lCleanup[tCleanup[i + 1]];
|
|
400
|
-
tCleanup[i].call(context);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
if (lCleanup !== null) {
|
|
405
|
-
lView[CLEANUP] = null;
|
|
406
|
-
}
|
|
407
|
-
const destroyHooks = lView[ON_DESTROY_HOOKS];
|
|
408
|
-
if (destroyHooks !== null) {
|
|
409
|
-
for (let i = 0; i < destroyHooks.length; i++) {
|
|
410
|
-
const destroyHooksFn = destroyHooks[i];
|
|
411
|
-
ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
|
|
412
|
-
destroyHooksFn();
|
|
413
|
-
}
|
|
414
|
-
lView[ON_DESTROY_HOOKS] = null;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
/** Calls onDestroy hooks for this view */
|
|
418
|
-
function executeOnDestroys(tView, lView) {
|
|
419
|
-
let destroyHooks;
|
|
420
|
-
if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
|
|
421
|
-
for (let i = 0; i < destroyHooks.length; i += 2) {
|
|
422
|
-
const context = lView[destroyHooks[i]];
|
|
423
|
-
// Only call the destroy hook if the context has been requested.
|
|
424
|
-
if (!(context instanceof NodeInjectorFactory)) {
|
|
425
|
-
const toCall = destroyHooks[i + 1];
|
|
426
|
-
if (Array.isArray(toCall)) {
|
|
427
|
-
for (let j = 0; j < toCall.length; j += 2) {
|
|
428
|
-
const callContext = context[toCall[j]];
|
|
429
|
-
const hook = toCall[j + 1];
|
|
430
|
-
profiler(4 /* ProfilerEvent.LifecycleHookStart */, callContext, hook);
|
|
431
|
-
try {
|
|
432
|
-
hook.call(callContext);
|
|
433
|
-
}
|
|
434
|
-
finally {
|
|
435
|
-
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, callContext, hook);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
profiler(4 /* ProfilerEvent.LifecycleHookStart */, context, toCall);
|
|
441
|
-
try {
|
|
442
|
-
toCall.call(context);
|
|
443
|
-
}
|
|
444
|
-
finally {
|
|
445
|
-
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, context, toCall);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Returns a native element if a node can be inserted into the given parent.
|
|
454
|
-
*
|
|
455
|
-
* There are two reasons why we may not be able to insert a element immediately.
|
|
456
|
-
* - Projection: When creating a child content element of a component, we have to skip the
|
|
457
|
-
* insertion because the content of a component will be projected.
|
|
458
|
-
* `<component><content>delayed due to projection</content></component>`
|
|
459
|
-
* - Parent container is disconnected: This can happen when we are inserting a view into
|
|
460
|
-
* parent container, which itself is disconnected. For example the parent container is part
|
|
461
|
-
* of a View which has not be inserted or is made for projection but has not been inserted
|
|
462
|
-
* into destination.
|
|
463
|
-
*
|
|
464
|
-
* @param tView: Current `TView`.
|
|
465
|
-
* @param tNode: `TNode` for which we wish to retrieve render parent.
|
|
466
|
-
* @param lView: Current `LView`.
|
|
467
|
-
*/
|
|
468
|
-
export function getParentRElement(tView, tNode, lView) {
|
|
469
|
-
return getClosestRElement(tView, tNode.parent, lView);
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Get closest `RElement` or `null` if it can't be found.
|
|
473
|
-
*
|
|
474
|
-
* If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.
|
|
475
|
-
* If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).
|
|
476
|
-
* If `TNode` is `null` then return host `RElement`:
|
|
477
|
-
* - return `null` if projection
|
|
478
|
-
* - return `null` if parent container is disconnected (we have no parent.)
|
|
479
|
-
*
|
|
480
|
-
* @param tView: Current `TView`.
|
|
481
|
-
* @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is
|
|
482
|
-
* needed).
|
|
483
|
-
* @param lView: Current `LView`.
|
|
484
|
-
* @returns `null` if the `RElement` can't be determined at this time (no parent / projection)
|
|
485
|
-
*/
|
|
486
|
-
export function getClosestRElement(tView, tNode, lView) {
|
|
487
|
-
let parentTNode = tNode;
|
|
488
|
-
// Skip over element and ICU containers as those are represented by a comment node and
|
|
489
|
-
// can't be used as a render parent.
|
|
490
|
-
while (parentTNode !== null &&
|
|
491
|
-
(parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */))) {
|
|
492
|
-
tNode = parentTNode;
|
|
493
|
-
parentTNode = tNode.parent;
|
|
494
|
-
}
|
|
495
|
-
// If the parent tNode is null, then we are inserting across views: either into an embedded view
|
|
496
|
-
// or a component view.
|
|
497
|
-
if (parentTNode === null) {
|
|
498
|
-
// We are inserting a root element of the component view into the component host element and
|
|
499
|
-
// it should always be eager.
|
|
500
|
-
return lView[HOST];
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
504
|
-
const { componentOffset } = parentTNode;
|
|
505
|
-
if (componentOffset > -1) {
|
|
506
|
-
ngDevMode && assertTNodeForLView(parentTNode, lView);
|
|
507
|
-
const { encapsulation } = tView.data[parentTNode.directiveStart + componentOffset];
|
|
508
|
-
// We've got a parent which is an element in the current view. We just need to verify if the
|
|
509
|
-
// parent element is not a component. Component's content nodes are not inserted immediately
|
|
510
|
-
// because they will be projected, and so doing insert at this point would be wasteful.
|
|
511
|
-
// Since the projection would then move it to its final destination. Note that we can't
|
|
512
|
-
// make this assumption when using the Shadow DOM, because the native projection placeholders
|
|
513
|
-
// (<content> or <slot>) have to be in place as elements are being inserted.
|
|
514
|
-
if (encapsulation === ViewEncapsulation.None ||
|
|
515
|
-
encapsulation === ViewEncapsulation.Emulated) {
|
|
516
|
-
return null;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
return getNativeByTNode(parentTNode, lView);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Inserts a native node before another native node for a given parent.
|
|
524
|
-
* This is a utility function that can be used when native nodes were determined.
|
|
525
|
-
*/
|
|
526
|
-
export function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
|
|
527
|
-
ngDevMode && ngDevMode.rendererInsertBefore++;
|
|
528
|
-
renderer.insertBefore(parent, child, beforeNode, isMove);
|
|
529
|
-
}
|
|
530
|
-
function nativeAppendChild(renderer, parent, child) {
|
|
531
|
-
ngDevMode && ngDevMode.rendererAppendChild++;
|
|
532
|
-
ngDevMode && assertDefined(parent, 'parent node must be defined');
|
|
533
|
-
renderer.appendChild(parent, child);
|
|
534
|
-
}
|
|
535
|
-
function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
|
|
536
|
-
if (beforeNode !== null) {
|
|
537
|
-
nativeInsertBefore(renderer, parent, child, beforeNode, isMove);
|
|
538
|
-
}
|
|
539
|
-
else {
|
|
540
|
-
nativeAppendChild(renderer, parent, child);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
/** Removes a node from the DOM given its native parent. */
|
|
544
|
-
function nativeRemoveChild(renderer, parent, child, isHostElement) {
|
|
545
|
-
renderer.removeChild(parent, child, isHostElement);
|
|
546
|
-
}
|
|
547
|
-
/** Checks if an element is a `<template>` node. */
|
|
548
|
-
function isTemplateNode(node) {
|
|
549
|
-
return node.tagName === 'TEMPLATE' && node.content !== undefined;
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Returns a native parent of a given native node.
|
|
553
|
-
*/
|
|
554
|
-
export function nativeParentNode(renderer, node) {
|
|
555
|
-
return renderer.parentNode(node);
|
|
556
|
-
}
|
|
557
|
-
/**
|
|
558
|
-
* Returns a native sibling of a given native node.
|
|
559
|
-
*/
|
|
560
|
-
export function nativeNextSibling(renderer, node) {
|
|
561
|
-
return renderer.nextSibling(node);
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Find a node in front of which `currentTNode` should be inserted.
|
|
565
|
-
*
|
|
566
|
-
* This method determines the `RNode` in front of which we should insert the `currentRNode`. This
|
|
567
|
-
* takes `TNode.insertBeforeIndex` into account if i18n code has been invoked.
|
|
568
|
-
*
|
|
569
|
-
* @param parentTNode parent `TNode`
|
|
570
|
-
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
571
|
-
* @param lView current `LView`
|
|
572
|
-
*/
|
|
573
|
-
function getInsertInFrontOfRNode(parentTNode, currentTNode, lView) {
|
|
574
|
-
return _getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView);
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* Find a node in front of which `currentTNode` should be inserted. (Does not take i18n into
|
|
578
|
-
* account)
|
|
579
|
-
*
|
|
580
|
-
* This method determines the `RNode` in front of which we should insert the `currentRNode`. This
|
|
581
|
-
* does not take `TNode.insertBeforeIndex` into account.
|
|
582
|
-
*
|
|
583
|
-
* @param parentTNode parent `TNode`
|
|
584
|
-
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
585
|
-
* @param lView current `LView`
|
|
586
|
-
*/
|
|
587
|
-
export function getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView) {
|
|
588
|
-
if (parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */)) {
|
|
589
|
-
return getNativeByTNode(parentTNode, lView);
|
|
590
|
-
}
|
|
591
|
-
return null;
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Tree shakable boundary for `getInsertInFrontOfRNodeWithI18n` function.
|
|
595
|
-
*
|
|
596
|
-
* This function will only be set if i18n code runs.
|
|
597
|
-
*/
|
|
598
|
-
let _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithNoI18n;
|
|
599
|
-
/**
|
|
600
|
-
* Tree shakable boundary for `processI18nInsertBefore` function.
|
|
601
|
-
*
|
|
602
|
-
* This function will only be set if i18n code runs.
|
|
603
|
-
*/
|
|
604
|
-
let _processI18nInsertBefore;
|
|
605
|
-
export function setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore) {
|
|
606
|
-
_getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithI18n;
|
|
607
|
-
_processI18nInsertBefore = processI18nInsertBefore;
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Appends the `child` native node (or a collection of nodes) to the `parent`.
|
|
611
|
-
*
|
|
612
|
-
* @param tView The `TView' to be appended
|
|
613
|
-
* @param lView The current LView
|
|
614
|
-
* @param childRNode The native child (or children) that should be appended
|
|
615
|
-
* @param childTNode The TNode of the child element
|
|
616
|
-
*/
|
|
617
|
-
export function appendChild(tView, lView, childRNode, childTNode) {
|
|
618
|
-
const parentRNode = getParentRElement(tView, childTNode, lView);
|
|
619
|
-
const renderer = lView[RENDERER];
|
|
620
|
-
const parentTNode = childTNode.parent || lView[T_HOST];
|
|
621
|
-
const anchorNode = getInsertInFrontOfRNode(parentTNode, childTNode, lView);
|
|
622
|
-
if (parentRNode != null) {
|
|
623
|
-
if (Array.isArray(childRNode)) {
|
|
624
|
-
for (let i = 0; i < childRNode.length; i++) {
|
|
625
|
-
nativeAppendOrInsertBefore(renderer, parentRNode, childRNode[i], anchorNode, false);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
else {
|
|
629
|
-
nativeAppendOrInsertBefore(renderer, parentRNode, childRNode, anchorNode, false);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
_processI18nInsertBefore !== undefined &&
|
|
633
|
-
_processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRNode);
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Returns the first native node for a given LView, starting from the provided TNode.
|
|
637
|
-
*
|
|
638
|
-
* Native nodes are returned in the order in which those appear in the native tree (DOM).
|
|
639
|
-
*/
|
|
640
|
-
export function getFirstNativeNode(lView, tNode) {
|
|
641
|
-
if (tNode !== null) {
|
|
642
|
-
ngDevMode &&
|
|
643
|
-
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 32 /* TNodeType.Icu */ | 16 /* TNodeType.Projection */);
|
|
644
|
-
const tNodeType = tNode.type;
|
|
645
|
-
if (tNodeType & 3 /* TNodeType.AnyRNode */) {
|
|
646
|
-
return getNativeByTNode(tNode, lView);
|
|
647
|
-
}
|
|
648
|
-
else if (tNodeType & 4 /* TNodeType.Container */) {
|
|
649
|
-
return getBeforeNodeForView(-1, lView[tNode.index]);
|
|
650
|
-
}
|
|
651
|
-
else if (tNodeType & 8 /* TNodeType.ElementContainer */) {
|
|
652
|
-
const elIcuContainerChild = tNode.child;
|
|
653
|
-
if (elIcuContainerChild !== null) {
|
|
654
|
-
return getFirstNativeNode(lView, elIcuContainerChild);
|
|
655
|
-
}
|
|
656
|
-
else {
|
|
657
|
-
const rNodeOrLContainer = lView[tNode.index];
|
|
658
|
-
if (isLContainer(rNodeOrLContainer)) {
|
|
659
|
-
return getBeforeNodeForView(-1, rNodeOrLContainer);
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
return unwrapRNode(rNodeOrLContainer);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
else if (tNodeType & 32 /* TNodeType.Icu */) {
|
|
667
|
-
let nextRNode = icuContainerIterate(tNode, lView);
|
|
668
|
-
let rNode = nextRNode();
|
|
669
|
-
// If the ICU container has no nodes, than we use the ICU anchor as the node.
|
|
670
|
-
return rNode || unwrapRNode(lView[tNode.index]);
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
const projectionNodes = getProjectionNodes(lView, tNode);
|
|
674
|
-
if (projectionNodes !== null) {
|
|
675
|
-
if (Array.isArray(projectionNodes)) {
|
|
676
|
-
return projectionNodes[0];
|
|
677
|
-
}
|
|
678
|
-
const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
|
|
679
|
-
ngDevMode && assertParentView(parentView);
|
|
680
|
-
return getFirstNativeNode(parentView, projectionNodes);
|
|
681
|
-
}
|
|
682
|
-
else {
|
|
683
|
-
return getFirstNativeNode(lView, tNode.next);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
return null;
|
|
688
|
-
}
|
|
689
|
-
export function getProjectionNodes(lView, tNode) {
|
|
690
|
-
if (tNode !== null) {
|
|
691
|
-
const componentView = lView[DECLARATION_COMPONENT_VIEW];
|
|
692
|
-
const componentHost = componentView[T_HOST];
|
|
693
|
-
const slotIdx = tNode.projection;
|
|
694
|
-
ngDevMode && assertProjectionSlots(lView);
|
|
695
|
-
return componentHost.projection[slotIdx];
|
|
696
|
-
}
|
|
697
|
-
return null;
|
|
698
|
-
}
|
|
699
|
-
export function getBeforeNodeForView(viewIndexInContainer, lContainer) {
|
|
700
|
-
const nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
|
|
701
|
-
if (nextViewIndex < lContainer.length) {
|
|
702
|
-
const lView = lContainer[nextViewIndex];
|
|
703
|
-
const firstTNodeOfView = lView[TVIEW].firstChild;
|
|
704
|
-
if (firstTNodeOfView !== null) {
|
|
705
|
-
return getFirstNativeNode(lView, firstTNodeOfView);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
return lContainer[NATIVE];
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Removes a native node itself using a given renderer. To remove the node we are looking up its
|
|
712
|
-
* parent from the native tree as not all platforms / browsers support the equivalent of
|
|
713
|
-
* node.remove().
|
|
714
|
-
*
|
|
715
|
-
* @param renderer A renderer to be used
|
|
716
|
-
* @param rNode The native node that should be removed
|
|
717
|
-
* @param isHostElement A flag indicating if a node to be removed is a host of a component.
|
|
718
|
-
*/
|
|
719
|
-
export function nativeRemoveNode(renderer, rNode, isHostElement) {
|
|
720
|
-
ngDevMode && ngDevMode.rendererRemoveNode++;
|
|
721
|
-
const nativeParent = nativeParentNode(renderer, rNode);
|
|
722
|
-
if (nativeParent) {
|
|
723
|
-
nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* Removes the contents of a given RElement using a given renderer.
|
|
728
|
-
*
|
|
729
|
-
* @param renderer A renderer to be used
|
|
730
|
-
* @param rElement the native RElement to be cleared
|
|
731
|
-
*/
|
|
732
|
-
export function clearElementContents(renderer, rElement) {
|
|
733
|
-
while (rElement.firstChild) {
|
|
734
|
-
nativeRemoveChild(renderer, rElement, rElement.firstChild, false);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Performs the operation of `action` on the node. Typically this involves inserting or removing
|
|
739
|
-
* nodes on the LView or projection boundary.
|
|
740
|
-
*/
|
|
741
|
-
function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
|
|
742
|
-
while (tNode != null) {
|
|
743
|
-
ngDevMode && assertTNodeForLView(tNode, lView);
|
|
744
|
-
ngDevMode &&
|
|
745
|
-
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
|
|
746
|
-
const rawSlotValue = lView[tNode.index];
|
|
747
|
-
const tNodeType = tNode.type;
|
|
748
|
-
if (isProjection) {
|
|
749
|
-
if (action === 0 /* WalkTNodeTreeAction.Create */) {
|
|
750
|
-
rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
|
|
751
|
-
tNode.flags |= 2 /* TNodeFlags.isProjected */;
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
|
|
755
|
-
if (tNodeType & 8 /* TNodeType.ElementContainer */) {
|
|
756
|
-
applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
|
|
757
|
-
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
758
|
-
}
|
|
759
|
-
else if (tNodeType & 32 /* TNodeType.Icu */) {
|
|
760
|
-
const nextRNode = icuContainerIterate(tNode, lView);
|
|
761
|
-
let rNode;
|
|
762
|
-
while (rNode = nextRNode()) {
|
|
763
|
-
applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
|
|
764
|
-
}
|
|
765
|
-
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
766
|
-
}
|
|
767
|
-
else if (tNodeType & 16 /* TNodeType.Projection */) {
|
|
768
|
-
applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
|
|
769
|
-
}
|
|
770
|
-
else {
|
|
771
|
-
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
772
|
-
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
tNode = isProjection ? tNode.projectionNext : tNode.next;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
function applyView(tView, lView, renderer, action, parentRElement, beforeNode) {
|
|
779
|
-
applyNodes(renderer, action, tView.firstChild, lView, parentRElement, beforeNode, false);
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* `applyProjection` performs operation on the projection.
|
|
783
|
-
*
|
|
784
|
-
* Inserting a projection requires us to locate the projected nodes from the parent component. The
|
|
785
|
-
* complication is that those nodes themselves could be re-projected from their parent component.
|
|
786
|
-
*
|
|
787
|
-
* @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed
|
|
788
|
-
* @param lView The `LView` which needs to be inserted, detached, destroyed.
|
|
789
|
-
* @param tProjectionNode node to project
|
|
790
|
-
*/
|
|
791
|
-
export function applyProjection(tView, lView, tProjectionNode) {
|
|
792
|
-
const renderer = lView[RENDERER];
|
|
793
|
-
const parentRNode = getParentRElement(tView, tProjectionNode, lView);
|
|
794
|
-
const parentTNode = tProjectionNode.parent || lView[T_HOST];
|
|
795
|
-
let beforeNode = getInsertInFrontOfRNode(parentTNode, tProjectionNode, lView);
|
|
796
|
-
applyProjectionRecursive(renderer, 0 /* WalkTNodeTreeAction.Create */, lView, tProjectionNode, parentRNode, beforeNode);
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* `applyProjectionRecursive` performs operation on the projection specified by `action` (insert,
|
|
800
|
-
* detach, destroy)
|
|
801
|
-
*
|
|
802
|
-
* Inserting a projection requires us to locate the projected nodes from the parent component. The
|
|
803
|
-
* complication is that those nodes themselves could be re-projected from their parent component.
|
|
804
|
-
*
|
|
805
|
-
* @param renderer Render to use
|
|
806
|
-
* @param action action to perform (insert, detach, destroy)
|
|
807
|
-
* @param lView The LView which needs to be inserted, detached, destroyed.
|
|
808
|
-
* @param tProjectionNode node to project
|
|
809
|
-
* @param parentRElement parent DOM element for insertion/removal.
|
|
810
|
-
* @param beforeNode Before which node the insertions should happen.
|
|
811
|
-
*/
|
|
812
|
-
function applyProjectionRecursive(renderer, action, lView, tProjectionNode, parentRElement, beforeNode) {
|
|
813
|
-
const componentLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
814
|
-
const componentNode = componentLView[T_HOST];
|
|
815
|
-
ngDevMode &&
|
|
816
|
-
assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index');
|
|
817
|
-
const nodeToProjectOrRNodes = componentNode.projection[tProjectionNode.projection];
|
|
818
|
-
if (Array.isArray(nodeToProjectOrRNodes)) {
|
|
819
|
-
// This should not exist, it is a bit of a hack. When we bootstrap a top level node and we
|
|
820
|
-
// need to support passing projectable nodes, so we cheat and put them in the TNode
|
|
821
|
-
// of the Host TView. (Yes we put instance info at the T Level). We can get away with it
|
|
822
|
-
// because we know that that TView is not shared and therefore it will not be a problem.
|
|
823
|
-
// This should be refactored and cleaned up.
|
|
824
|
-
for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
|
|
825
|
-
const rNode = nodeToProjectOrRNodes[i];
|
|
826
|
-
applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
let nodeToProject = nodeToProjectOrRNodes;
|
|
831
|
-
const projectedComponentLView = componentLView[PARENT];
|
|
832
|
-
applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* `applyContainer` performs an operation on the container and its views as specified by
|
|
837
|
-
* `action` (insert, detach, destroy)
|
|
838
|
-
*
|
|
839
|
-
* Inserting a Container is complicated by the fact that the container may have Views which
|
|
840
|
-
* themselves have containers or projections.
|
|
841
|
-
*
|
|
842
|
-
* @param renderer Renderer to use
|
|
843
|
-
* @param action action to perform (insert, detach, destroy)
|
|
844
|
-
* @param lContainer The LContainer which needs to be inserted, detached, destroyed.
|
|
845
|
-
* @param parentRElement parent DOM element for insertion/removal.
|
|
846
|
-
* @param beforeNode Before which node the insertions should happen.
|
|
847
|
-
*/
|
|
848
|
-
function applyContainer(renderer, action, lContainer, parentRElement, beforeNode) {
|
|
849
|
-
ngDevMode && assertLContainer(lContainer);
|
|
850
|
-
const anchor = lContainer[NATIVE]; // LContainer has its own before node.
|
|
851
|
-
const native = unwrapRNode(lContainer);
|
|
852
|
-
// An LContainer can be created dynamically on any node by injecting ViewContainerRef.
|
|
853
|
-
// Asking for a ViewContainerRef on an element will result in a creation of a separate anchor
|
|
854
|
-
// node (comment in the DOM) that will be different from the LContainer's host node. In this
|
|
855
|
-
// particular case we need to execute action on 2 nodes:
|
|
856
|
-
// - container's host node (this is done in the executeActionOnElementOrContainer)
|
|
857
|
-
// - container's host node (this is done here)
|
|
858
|
-
if (anchor !== native) {
|
|
859
|
-
// This is very strange to me (Misko). I would expect that the native is same as anchor. I
|
|
860
|
-
// don't see a reason why they should be different, but they are.
|
|
861
|
-
//
|
|
862
|
-
// If they are we need to process the second anchor as well.
|
|
863
|
-
applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
|
|
864
|
-
}
|
|
865
|
-
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
866
|
-
const lView = lContainer[i];
|
|
867
|
-
applyView(lView[TVIEW], lView, renderer, action, parentRElement, anchor);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
/**
|
|
871
|
-
* Writes class/style to element.
|
|
872
|
-
*
|
|
873
|
-
* @param renderer Renderer to use.
|
|
874
|
-
* @param isClassBased `true` if it should be written to `class` (`false` to write to `style`)
|
|
875
|
-
* @param rNode The Node to write to.
|
|
876
|
-
* @param prop Property to write to. This would be the class/style name.
|
|
877
|
-
* @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
|
|
878
|
-
* otherwise).
|
|
879
|
-
*/
|
|
880
|
-
export function applyStyling(renderer, isClassBased, rNode, prop, value) {
|
|
881
|
-
if (isClassBased) {
|
|
882
|
-
// We actually want JS true/false here because any truthy value should add the class
|
|
883
|
-
if (!value) {
|
|
884
|
-
ngDevMode && ngDevMode.rendererRemoveClass++;
|
|
885
|
-
renderer.removeClass(rNode, prop);
|
|
886
|
-
}
|
|
887
|
-
else {
|
|
888
|
-
ngDevMode && ngDevMode.rendererAddClass++;
|
|
889
|
-
renderer.addClass(rNode, prop);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
else {
|
|
893
|
-
let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
|
|
894
|
-
if (value == null /** || value === undefined */) {
|
|
895
|
-
ngDevMode && ngDevMode.rendererRemoveStyle++;
|
|
896
|
-
renderer.removeStyle(rNode, prop, flags);
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
// A value is important if it ends with `!important`. The style
|
|
900
|
-
// parser strips any semicolons at the end of the value.
|
|
901
|
-
const isImportant = typeof value === 'string' ? value.endsWith('!important') : false;
|
|
902
|
-
if (isImportant) {
|
|
903
|
-
// !important has to be stripped from the value for it to be valid.
|
|
904
|
-
value = value.slice(0, -10);
|
|
905
|
-
flags |= RendererStyleFlags2.Important;
|
|
906
|
-
}
|
|
907
|
-
ngDevMode && ngDevMode.rendererSetStyle++;
|
|
908
|
-
renderer.setStyle(rNode, prop, value, flags);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Write `cssText` to `RElement`.
|
|
914
|
-
*
|
|
915
|
-
* This function does direct write without any reconciliation. Used for writing initial values, so
|
|
916
|
-
* that static styling values do not pull in the style parser.
|
|
917
|
-
*
|
|
918
|
-
* @param renderer Renderer to use
|
|
919
|
-
* @param element The element which needs to be updated.
|
|
920
|
-
* @param newValue The new class list to write.
|
|
921
|
-
*/
|
|
922
|
-
export function writeDirectStyle(renderer, element, newValue) {
|
|
923
|
-
ngDevMode && assertString(newValue, '\'newValue\' should be a string');
|
|
924
|
-
renderer.setAttribute(element, 'style', newValue);
|
|
925
|
-
ngDevMode && ngDevMode.rendererSetStyle++;
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Write `className` to `RElement`.
|
|
929
|
-
*
|
|
930
|
-
* This function does direct write without any reconciliation. Used for writing initial values, so
|
|
931
|
-
* that static styling values do not pull in the style parser.
|
|
932
|
-
*
|
|
933
|
-
* @param renderer Renderer to use
|
|
934
|
-
* @param element The element which needs to be updated.
|
|
935
|
-
* @param newValue The new class list to write.
|
|
936
|
-
*/
|
|
937
|
-
export function writeDirectClass(renderer, element, newValue) {
|
|
938
|
-
ngDevMode && assertString(newValue, '\'newValue\' should be a string');
|
|
939
|
-
if (newValue === '') {
|
|
940
|
-
// There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
|
|
941
|
-
renderer.removeAttribute(element, 'class');
|
|
942
|
-
}
|
|
943
|
-
else {
|
|
944
|
-
renderer.setAttribute(element, 'class', newValue);
|
|
945
|
-
}
|
|
946
|
-
ngDevMode && ngDevMode.rendererSetClassName++;
|
|
947
|
-
}
|
|
948
|
-
/** Sets up the static DOM attributes on an `RNode`. */
|
|
949
|
-
export function setupStaticAttributes(renderer, element, tNode) {
|
|
950
|
-
const { mergedAttrs, classes, styles } = tNode;
|
|
951
|
-
if (mergedAttrs !== null) {
|
|
952
|
-
setUpAttributes(renderer, element, mergedAttrs);
|
|
953
|
-
}
|
|
954
|
-
if (classes !== null) {
|
|
955
|
-
writeDirectClass(renderer, element, classes);
|
|
956
|
-
}
|
|
957
|
-
if (styles !== null) {
|
|
958
|
-
writeDirectStyle(renderer, element, styles);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tYW5pcHVsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL25vZGVfbWFuaXB1bGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQ25ELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3hELE9BQU8sRUFBQyxVQUFVLEVBQUUsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDaEUsT0FBTyxFQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFFOUMsT0FBTyxFQUFDLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxxQkFBcUIsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNySCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDN0QsT0FBTyxFQUFDLHVCQUF1QixFQUFFLHNCQUFzQixFQUFjLFdBQVcsRUFBRSxNQUFNLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUV4SCxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFJNUQsT0FBTyxFQUFDLFlBQVksRUFBRSxPQUFPLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRCxPQUFPLEVBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxzQkFBc0IsRUFBbUIsS0FBSyxFQUFvQixJQUFJLEVBQXFCLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFtQixNQUFNLG1CQUFtQixDQUFDO0FBQ2pRLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxFQUFDLFFBQVEsRUFBZ0IsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ25ELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLDJCQUEyQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFxQjdGOzs7R0FHRztBQUNILFNBQVMseUJBQXlCLENBQzlCLE1BQTJCLEVBQUUsUUFBa0IsRUFBRSxNQUFxQixFQUN0RSxhQUFxQyxFQUFFLFVBQXVCO0lBQ2hFLCtGQUErRjtJQUMvRiwwRkFBMEY7SUFDMUYsOEZBQThGO0lBQzlGLHFCQUFxQjtJQUNyQixJQUFJLGFBQWEsSUFBSSxJQUFJLEVBQUU7UUFDekIsSUFBSSxVQUFnQyxDQUFDO1FBQ3JDLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN4Qix5RkFBeUY7UUFDekYsK0ZBQStGO1FBQy9GLDZFQUE2RTtRQUM3RSxJQUFJLFlBQVksQ0FBQyxhQUFhLENBQUMsRUFBRTtZQUMvQixVQUFVLEdBQUcsYUFBYSxDQUFDO1NBQzVCO2FBQU0sSUFBSSxPQUFPLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDakMsV0FBVyxHQUFHLElBQUksQ0FBQztZQUNuQixTQUFTLElBQUksYUFBYSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSw0Q0FBNEMsQ0FBQyxDQUFDO1lBQzlGLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFFLENBQUM7U0FDdEM7UUFDRCxNQUFNLEtBQUssR0FBVSxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFaEQsSUFBSSxNQUFNLHVDQUErQixJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUU7WUFDNUQsSUFBSSxVQUFVLElBQUksSUFBSSxFQUFFO2dCQUN0QixpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzVDO2lCQUFNO2dCQUNMLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFVBQVUsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDdkU7U0FDRjthQUFNLElBQUksTUFBTSx1Q0FBK0IsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO1lBQ25FLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFVBQVUsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDdkU7YUFBTSxJQUFJLE1BQU0sdUNBQStCLEVBQUU7WUFDaEQsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztTQUNoRDthQUFNLElBQUksTUFBTSx3Q0FBZ0MsRUFBRTtZQUNqRCxTQUFTLElBQUksU0FBUyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0MsUUFBUSxDQUFDLFdBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM5QjtRQUNELElBQUksVUFBVSxJQUFJLElBQUksRUFBRTtZQUN0QixjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ2xFO0tBQ0Y7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxRQUFrQixFQUFFLEtBQWE7SUFDOUQsU0FBUyxJQUFJLFNBQVMsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hELFNBQVMsSUFBSSxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDekMsT0FBTyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUFDLFFBQWtCLEVBQUUsS0FBWSxFQUFFLEtBQWE7SUFDNUUsU0FBUyxJQUFJLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN6QyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFFBQWtCLEVBQUUsS0FBYTtJQUNqRSxTQUFTLElBQUksU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDL0MsT0FBTyxRQUFRLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDN0IsUUFBa0IsRUFBRSxJQUFZLEVBQUUsU0FBc0I7SUFDMUQsU0FBUyxJQUFJLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQy9DLE9BQU8sUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDakQsQ0FBQztBQUdEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxLQUFZLEVBQUUsS0FBWTtJQUNoRSxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakMsU0FBUyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxzQ0FBOEIsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDbkIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN2QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FDOUIsS0FBWSxFQUFFLFdBQWtCLEVBQUUsUUFBa0IsRUFBRSxLQUFZLEVBQUUsZ0JBQTBCLEVBQzlGLFVBQXNCO0lBQ3hCLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQztJQUMvQixLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsV0FBVyxDQUFDO0lBQzVCLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsc0NBQThCLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQzlGLENBQUM7QUFHRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxLQUFZLEVBQUUsS0FBWTtJQUN6RCxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLHNDQUE4QixJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDbkYsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsUUFBZTtJQUM3QyxvRUFBb0U7SUFDcEUsSUFBSSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDN0MsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1FBQ3RCLE9BQU8sV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztLQUMvQztJQUVELE9BQU8saUJBQWlCLEVBQUU7UUFDeEIsSUFBSSxJQUFJLEdBQTBCLElBQUksQ0FBQztRQUV2QyxJQUFJLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFO1lBQzlCLG9DQUFvQztZQUNwQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDdEM7YUFBTTtZQUNMLFNBQVMsSUFBSSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2pELGtEQUFrRDtZQUNsRCxNQUFNLFNBQVMsR0FBb0IsaUJBQWlCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUM5RSxJQUFJLFNBQVM7Z0JBQUUsSUFBSSxHQUFHLFNBQVMsQ0FBQztTQUNqQztRQUVELElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDVCxxRUFBcUU7WUFDckUsZ0RBQWdEO1lBQ2hELE9BQU8saUJBQWlCLElBQUksQ0FBQyxpQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxpQkFBaUIsS0FBSyxRQUFRLEVBQUU7Z0JBQ3ZGLElBQUksT0FBTyxDQUFDLGlCQUFpQixDQUFDLEVBQUU7b0JBQzlCLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2lCQUMxRDtnQkFDRCxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUMvQztZQUNELElBQUksaUJBQWlCLEtBQUssSUFBSTtnQkFBRSxpQkFBaUIsR0FBRyxRQUFRLENBQUM7WUFDN0QsSUFBSSxPQUFPLENBQUMsaUJBQWlCLENBQUMsRUFBRTtnQkFDOUIsV0FBVyxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7YUFDMUQ7WUFDRCxJQUFJLEdBQUcsaUJBQWlCLElBQUksaUJBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdEQ7UUFDRCxpQkFBaUIsR0FBRyxJQUFJLENBQUM7S0FDMUI7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxLQUFZLEVBQUUsS0FBWSxFQUFFLFVBQXNCLEVBQUUsS0FBYTtJQUMxRixTQUFTLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLFNBQVMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxNQUFNLGdCQUFnQixHQUFHLHVCQUF1QixHQUFHLEtBQUssQ0FBQztJQUN6RCxNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO0lBRTFDLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRTtRQUNiLHlEQUF5RDtRQUN6RCxVQUFVLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO0tBQ2hEO0lBQ0QsSUFBSSxLQUFLLEdBQUcsZUFBZSxHQUFHLHVCQUF1QixFQUFFO1FBQ3JELEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMzQyxVQUFVLENBQUMsVUFBVSxFQUFFLHVCQUF1QixHQUFHLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztLQUNoRTtTQUFNO1FBQ0wsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO0tBQ3BCO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQztJQUUzQixtRUFBbUU7SUFDbkUsTUFBTSxxQkFBcUIsR0FBRyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUM1RCxJQUFJLHFCQUFxQixLQUFLLElBQUksSUFBSSxVQUFVLEtBQUsscUJBQXFCLEVBQUU7UUFDMUUsY0FBYyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQzlDO0lBRUQsOENBQThDO0lBQzlDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7UUFDckIsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUM1QjtJQUVELHlCQUF5QjtJQUN6QixLQUFLLENBQUMsS0FBSyxDQUFDLGdDQUF1QixDQUFDO0FBQ3RDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGNBQWMsQ0FBQyxvQkFBZ0MsRUFBRSxLQUFZO0lBQ3BFLFNBQVMsSUFBSSxhQUFhLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDcEQsU0FBUyxJQUFJLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDcEQsTUFBTSxVQUFVLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckQsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFlLENBQUM7SUFDdkQsU0FBUyxJQUFJLGdCQUFnQixDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDbEQsTUFBTSxzQkFBc0IsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUUsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0lBQ3ZGLFNBQVMsSUFBSSxhQUFhLENBQUMsc0JBQXNCLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQztJQUNyRixNQUFNLHNCQUFzQixHQUFHLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0lBQ2pFLFNBQVMsSUFBSSxhQUFhLENBQUMsc0JBQXNCLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQztJQUNyRixJQUFJLHNCQUFzQixLQUFLLHNCQUFzQixFQUFFO1FBQ3JELDhGQUE4RjtRQUM5Riw0RkFBNEY7UUFDNUYscUNBQXFDO1FBQ3JDLG9CQUFvQixDQUFDLHNCQUFzQixDQUFDLEdBQUcsSUFBSSxDQUFDO0tBQ3JEO0lBQ0QsSUFBSSxVQUFVLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDN0M7U0FBTTtRQUNMLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDeEI7QUFDSCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsb0JBQWdDLEVBQUUsS0FBWTtJQUNyRSxTQUFTLElBQUksZ0JBQWdCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNwRCxTQUFTO1FBQ0wsYUFBYSxDQUNULG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxFQUNqQywwRUFBMEUsQ0FBQyxDQUFDO0lBQ3BGLE1BQU0sVUFBVSxHQUFHLG9CQUFvQixDQUFDLFdBQVcsQ0FBRSxDQUFDO0lBQ3RELE1BQU0sb0JBQW9CLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2RCxNQUFNLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxNQUFNLENBQWUsQ0FBQztJQUN4RCxTQUFTLElBQUksZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUVuRCw2RkFBNkY7SUFDN0YsNEZBQTRGO0lBQzVGLFdBQVc7SUFDWCxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsK0NBQXFDLEVBQUU7UUFDckQsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLDZDQUFtQyxDQUFDO1FBQ3BELDJCQUEyQixDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDdEQ7SUFFRCxVQUFVLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzdDLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUFDLFVBQXNCLEVBQUUsV0FBbUI7SUFDcEUsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLHVCQUF1QjtRQUFFLE9BQU87SUFFekQsTUFBTSxnQkFBZ0IsR0FBRyx1QkFBdUIsR0FBRyxXQUFXLENBQUM7SUFDL0QsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFFbEQsSUFBSSxZQUFZLEVBQUU7UUFDaEIsTUFBTSxxQkFBcUIsR0FBRyxZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNuRSxJQUFJLHFCQUFxQixLQUFLLElBQUksSUFBSSxxQkFBcUIsS0FBSyxVQUFVLEVBQUU7WUFDMUUsZUFBZSxDQUFDLHFCQUFxQixFQUFFLFlBQVksQ0FBQyxDQUFDO1NBQ3REO1FBR0QsSUFBSSxXQUFXLEdBQUcsQ0FBQyxFQUFFO1lBQ25CLFVBQVUsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFVLENBQUM7U0FDdEU7UUFDRCxNQUFNLFlBQVksR0FBRyxlQUFlLENBQUMsVUFBVSxFQUFFLHVCQUF1QixHQUFHLFdBQVcsQ0FBQyxDQUFDO1FBQ3hGLHVCQUF1QixDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUUzRCw0Q0FBNEM7UUFDNUMsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtZQUNyQixRQUFRLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQzFDO1FBRUQsWUFBWSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUM1QixZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzFCLDJCQUEyQjtRQUMzQixZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksNkJBQW9CLENBQUM7S0FDN0M7SUFDRCxPQUFPLFlBQVksQ0FBQztBQUN0QixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxLQUFZLEVBQUUsS0FBWTtJQUNyRCxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGlDQUF1QixDQUFDLEVBQUU7UUFDMUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pDLElBQUksUUFBUSxDQUFDLFdBQVcsRUFBRTtZQUN4QixTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLHVDQUErQixJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDNUU7UUFFRCxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDeEI7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsV0FBVyxDQUFDLEtBQVksRUFBRSxLQUFZO0lBQzdDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsaUNBQXVCLENBQUMsRUFBRTtRQUMxQywwRkFBMEY7UUFDMUYseUZBQXlGO1FBQ3pGLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSw2QkFBb0IsQ0FBQztRQUVyQyx3RkFBd0Y7UUFDeEYsNkZBQTZGO1FBQzdGLDZGQUE2RjtRQUM3RiwwRkFBMEY7UUFDMUYsK0RBQStEO1FBQy9ELEtBQUssQ0FBQyxLQUFLLENBQUMsa0NBQXdCLENBQUM7UUFFckMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUIsOEVBQThFO1FBQzlFLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksZ0NBQXdCLEVBQUU7WUFDN0MsU0FBUyxJQUFJLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDM0I7UUFFRCxNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzNELCtFQUErRTtRQUMvRSxJQUFJLG9CQUFvQixLQUFLLElBQUksSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7WUFDaEUsK0JBQStCO1lBQy9CLElBQUksb0JBQW9CLEtBQUssS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMxQyxlQUFlLENBQUMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDOUM7WUFFRCx3RkFBd0Y7WUFDeEYsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtnQkFDckIsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QjtTQUNGO1FBRUQsZ0VBQWdFO1FBQ2hFLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUN4QjtBQUNILENBQUM7QUFFRCxtRUFBbUU7QUFDbkUsU0FBUyxlQUFlLENBQUMsS0FBWSxFQUFFLEtBQVk7SUFDakQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFFLENBQUM7SUFDakMsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFO1FBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQy9DLElBQUksT0FBTyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFO2dCQUNuQyw0RkFBNEY7Z0JBQzVGLCtCQUErQjtnQkFDL0IsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsU0FBUyxJQUFJLFlBQVksQ0FBQyxTQUFTLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztnQkFDeEUsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFO29CQUNsQixhQUFhO29CQUNiLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2lCQUN2QjtxQkFBTTtvQkFDTCxlQUFlO29CQUNmLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO2lCQUNwQztnQkFDRCxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ1I7aUJBQU07Z0JBQ0wsMkVBQTJFO2dCQUMzRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMxQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQzNCO1NBQ0Y7S0FDRjtJQUNELElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtRQUNyQixLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0tBQ3ZCO0lBQ0QsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0MsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFO1FBQ3pCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVDLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QyxTQUFTLElBQUksY0FBYyxDQUFDLGNBQWMsRUFBRSwwQ0FBMEMsQ0FBQyxDQUFDO1lBQ3hGLGNBQWMsRUFBRSxDQUFDO1NBQ2xCO1FBQ0QsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsSUFBSSxDQUFDO0tBQ2hDO0FBQ0gsQ0FBQztBQUVELDBDQUEwQztBQUMxQyxTQUFTLGlCQUFpQixDQUFDLEtBQVksRUFBRSxLQUFZO0lBQ25ELElBQUksWUFBa0MsQ0FBQztJQUV2QyxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksRUFBRTtRQUNoRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQy9DLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFXLENBQUMsQ0FBQztZQUVqRCxnRUFBZ0U7WUFDaEUsSUFBSSxDQUFDLENBQUMsT0FBTyxZQUFZLG1CQUFtQixDQUFDLEVBQUU7Z0JBQzdDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFzQixDQUFDO2dCQUV4RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7b0JBQ3pCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQ3pDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFXLENBQUMsQ0FBQzt3QkFDakQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQVcsQ0FBQzt3QkFDckMsUUFBUSwyQ0FBbUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO3dCQUM5RCxJQUFJOzRCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7eUJBQ3hCO2dDQUFTOzRCQUNSLFFBQVEseUNBQWlDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQzt5QkFDN0Q7cUJBQ0Y7aUJBQ0Y7cUJBQU07b0JBQ0wsUUFBUSwyQ0FBbUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUM1RCxJQUFJO3dCQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ3RCOzRCQUFTO3dCQUNSLFFBQVEseUNBQWlDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztxQkFDM0Q7aUJBQ0Y7YUFDRjtTQUNGO0tBQ0Y7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEtBQVksRUFBRSxLQUFZLEVBQUUsS0FBWTtJQUN4RSxPQUFPLGtCQUFrQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxLQUFZLEVBQUUsS0FBaUIsRUFBRSxLQUFZO0lBQzlFLElBQUksV0FBVyxHQUFlLEtBQUssQ0FBQztJQUNwQyxzRkFBc0Y7SUFDdEYsb0NBQW9DO0lBQ3BDLE9BQU8sV0FBVyxLQUFLLElBQUk7UUFDcEIsQ0FBQyxXQUFXLENBQUMsSUFBSSxHQUFHLENBQUMsMkRBQTBDLENBQUMsQ0FBQyxFQUFFO1FBQ3hFLEtBQUssR0FBRyxXQUFXLENBQUM7UUFDcEIsV0FBVyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7S0FDNUI7SUFFRCxnR0FBZ0c7SUFDaEcsdUJBQXVCO0lBQ3ZCLElBQUksV0FBVyxLQUFLLElBQUksRUFBRTtRQUN4Qiw0RkFBNEY7UUFDNUYsNkJBQTZCO1FBQzdCLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3BCO1NBQU07UUFDTCxTQUFTLElBQUksZUFBZSxDQUFDLFdBQVcsRUFBRSx3REFBd0MsQ0FBQyxDQUFDO1FBQ3BGLE1BQU0sRUFBQyxlQUFlLEVBQUMsR0FBRyxXQUFXLENBQUM7UUFDdEMsSUFBSSxlQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDeEIsU0FBUyxJQUFJLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyRCxNQUFNLEVBQUMsYUFBYSxFQUFDLEdBQ2hCLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsR0FBRyxlQUFlLENBQTJCLENBQUM7WUFDeEYsNEZBQTRGO1lBQzVGLDRGQUE0RjtZQUM1Rix1RkFBdUY7WUFDdkYsdUZBQXVGO1lBQ3ZGLDZGQUE2RjtZQUM3Riw0RUFBNEU7WUFDNUUsSUFBSSxhQUFhLEtBQUssaUJBQWlCLENBQUMsSUFBSTtnQkFDeEMsYUFBYSxLQUFLLGlCQUFpQixDQUFDLFFBQVEsRUFBRTtnQkFDaEQsT0FBTyxJQUFJLENBQUM7YUFDYjtTQUNGO1FBRUQsT0FBTyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFhLENBQUM7S0FDekQ7QUFDSCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUM5QixRQUFrQixFQUFFLE1BQWdCLEVBQUUsS0FBWSxFQUFFLFVBQXNCLEVBQzFFLE1BQWU7SUFDakIsU0FBUyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlDLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsUUFBa0IsRUFBRSxNQUFnQixFQUFFLEtBQVk7SUFDM0UsU0FBUyxJQUFJLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdDLFNBQVMsSUFBSSxhQUFhLENBQUMsTUFBTSxFQUFFLDZCQUE2QixDQUFDLENBQUM7SUFDbEUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQUVELFNBQVMsMEJBQTBCLENBQy9CLFFBQWtCLEVBQUUsTUFBZ0IsRUFBRSxLQUFZLEVBQUUsVUFBc0IsRUFBRSxNQUFlO0lBQzdGLElBQUksVUFBVSxLQUFLLElBQUksRUFBRTtRQUN2QixrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDakU7U0FBTTtRQUNMLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDNUM7QUFDSCxDQUFDO0FBRUQsMkRBQTJEO0FBQzNELFNBQVMsaUJBQWlCLENBQ3RCLFFBQWtCLEVBQUUsTUFBZ0IsRUFBRSxLQUFZLEVBQUUsYUFBdUI7SUFDN0UsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQ3JELENBQUM7QUFFRCxtREFBbUQ7QUFDbkQsU0FBUyxjQUFjLENBQUMsSUFBYztJQUNwQyxPQUFPLElBQUksQ0FBQyxPQUFPLEtBQUssVUFBVSxJQUFLLElBQWtCLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQztBQUNsRixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsUUFBa0IsRUFBRSxJQUFXO0lBQzlELE9BQU8sUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsUUFBa0IsRUFBRSxJQUFXO0lBQy9ELE9BQU8sUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBUyx1QkFBdUIsQ0FBQyxXQUFrQixFQUFFLFlBQW1CLEVBQUUsS0FBWTtJQUVwRixPQUFPLGdDQUFnQyxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDNUUsQ0FBQztBQUdEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLFVBQVUsaUNBQWlDLENBQzdDLFdBQWtCLEVBQUUsWUFBbUIsRUFBRSxLQUFZO0lBQ3ZELElBQUksV0FBVyxDQUFDLElBQUksR0FBRyxDQUFDLDJEQUEwQyxDQUFDLEVBQUU7UUFDbkUsT0FBTyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDN0M7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsSUFBSSxnQ0FBZ0MsR0FDakIsaUNBQWlDLENBQUM7QUFFckQ7Ozs7R0FJRztBQUNILElBQUksd0JBRXNDLENBQUM7QUFFM0MsTUFBTSxVQUFVLGVBQWUsQ0FDM0IsK0JBQ2dCLEVBQ2hCLHVCQUUwQztJQUM1QyxnQ0FBZ0MsR0FBRywrQkFBK0IsQ0FBQztJQUNuRSx3QkFBd0IsR0FBRyx1QkFBdUIsQ0FBQztBQUNyRCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQ3ZCLEtBQVksRUFBRSxLQUFZLEVBQUUsVUFBeUIsRUFBRSxVQUFpQjtJQUMxRSxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNqQyxNQUFNLFdBQVcsR0FBVSxVQUFVLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUUsQ0FBQztJQUMvRCxNQUFNLFVBQVUsR0FBRyx1QkFBdUIsQ0FBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNFLElBQUksV0FBVyxJQUFJLElBQUksRUFBRTtRQUN2QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzFDLDBCQUEwQixDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNyRjtTQUNGO2FBQU07WUFDTCwwQkFBMEIsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDbEY7S0FDRjtJQUVELHdCQUF3QixLQUFLLFNBQVM7UUFDbEMsd0JBQXdCLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3JGLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQVksRUFBRSxLQUFpQjtJQUNoRSxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUU7UUFDbEIsU0FBUztZQUNMLGVBQWUsQ0FDWCxLQUFLLEVBQ0wsNERBQTJDLHlCQUFnQixnQ0FBdUIsQ0FBQyxDQUFDO1FBRTVGLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDN0IsSUFBSSxTQUFTLDZCQUFxQixFQUFFO1lBQ2xDLE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3ZDO2FBQU0sSUFBSSxTQUFTLDhCQUFzQixFQUFFO1lBQzFDLE9BQU8sb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQ3JEO2FBQU0sSUFBSSxTQUFTLHFDQUE2QixFQUFFO1lBQ2pELE1BQU0sbUJBQW1CLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztZQUN4QyxJQUFJLG1CQUFtQixLQUFLLElBQUksRUFBRTtnQkFDaEMsT0FBTyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLENBQUMsQ0FBQzthQUN2RDtpQkFBTTtnQkFDTCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzdDLElBQUksWUFBWSxDQUFDLGlCQUFpQixDQUFDLEVBQUU7b0JBQ25DLE9BQU8sb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztpQkFDcEQ7cUJBQU07b0JBQ0wsT0FBTyxXQUFXLENBQUMsaUJBQWlCLENBQUMsQ0FBQztpQkFDdkM7YUFDRjtTQUNGO2FBQU0sSUFBSSxTQUFTLHlCQUFnQixFQUFFO1lBQ3BDLElBQUksU0FBUyxHQUFHLG1CQUFtQixDQUFDLEtBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDdkUsSUFBSSxLQUFLLEdBQWUsU0FBUyxFQUFFLENBQUM7WUFDcEMsNkVBQTZFO1lBQzdFLE9BQU8sS0FBSyxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDakQ7YUFBTTtZQUNMLE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN6RCxJQUFJLGVBQWUsS0FBSyxJQUFJLEVBQUU7Z0JBQzVCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRTtvQkFDbEMsT0FBTyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQzNCO2dCQUNELE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDO2dCQUNyRSxTQUFTLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzFDLE9BQU8sa0JBQWtCLENBQUMsVUFBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO2FBQ3pEO2lCQUFNO2dCQUNMLE9BQU8sa0JBQWtCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUM5QztTQUNGO0tBQ0Y7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsS0FBWSxFQUFFLEtBQWlCO0lBQ2hFLElBQUksS0FBSyxLQUFLLElBQUksRUFBRTtRQUNsQixNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUN4RCxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFpQixDQUFDO1FBQzVELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxVQUFvQixDQUFDO1FBQzNDLFNBQVMsSUFBSSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxPQUFPLGFBQWEsQ0FBQyxVQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDM0M7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsb0JBQTRCLEVBQUUsVUFBc0I7SUFFdkYsTUFBTSxhQUFhLEdBQUcsdUJBQXVCLEdBQUcsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0lBQ3pFLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUU7UUFDckMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBVSxDQUFDO1FBQ2pELE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsQ0FBQztRQUNqRCxJQUFJLGdCQUFnQixLQUFLLElBQUksRUFBRTtZQUM3QixPQUFPLGtCQUFrQixDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1NBQ3BEO0tBQ0Y7SUFFRCxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsUUFBa0IsRUFBRSxLQUFZLEVBQUUsYUFBdUI7SUFDeEYsU0FBUyxJQUFJLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVDLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RCxJQUFJLFlBQVksRUFBRTtRQUNoQixpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNqRTtBQUNILENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxRQUFrQixFQUFFLFFBQWtCO0lBQ3pFLE9BQU8sUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUMxQixpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDbkU7QUFDSCxDQUFDO0FBR0Q7OztHQUdHO0FBQ0gsU0FBUyxVQUFVLENBQ2YsUUFBa0IsRUFBRSxNQUEyQixFQUFFLEtBQWlCLEVBQUUsS0FBWSxFQUNoRixjQUE2QixFQUFFLFVBQXNCLEVBQUUsWUFBcUI7SUFDOUUsT0FBTyxLQUFLLElBQUksSUFBSSxFQUFFO1FBQ3BCLFNBQVMsSUFBSSxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0MsU0FBUztZQUNMLGVBQWUsQ0FDWCxLQUFLLEVBQ0wsNERBQTJDLGdDQUF1Qix5QkFBZ0IsQ0FBQyxDQUFDO1FBQzVGLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztRQUM3QixJQUFJLFlBQVksRUFBRTtZQUNoQixJQUFJLE1BQU0sdUNBQStCLEVBQUU7Z0JBQ3pDLFlBQVksSUFBSSxlQUFlLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNsRSxLQUFLLENBQUMsS0FBSyxrQ0FBMEIsQ0FBQzthQUN2QztTQUNGO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLGlDQUF3QixDQUFDLG1DQUEwQixFQUFFO1lBQ25FLElBQUksU0FBUyxxQ0FBNkIsRUFBRTtnQkFDMUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDcEYseUJBQXlCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3ZGO2lCQUFNLElBQUksU0FBUyx5QkFBZ0IsRUFBRTtnQkFDcEMsTUFBTSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsS0FBMEIsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDekUsSUFBSSxLQUFpQixDQUFDO2dCQUN0QixPQUFPLEtBQUssR0FBRyxTQUFTLEVBQUUsRUFBRTtvQkFDMUIseUJBQXlCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2lCQUNoRjtnQkFDRCx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDdkY7aUJBQU0sSUFBSSxTQUFTLGdDQUF1QixFQUFFO2dCQUMzQyx3QkFBd0IsQ0FDcEIsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBd0IsRUFBRSxjQUFjLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDcEY7aUJBQU07Z0JBQ0wsU0FBUyxJQUFJLGVBQWUsQ0FBQyxLQUFLLEVBQUUsd0RBQXdDLENBQUMsQ0FBQztnQkFDOUUseUJBQXlCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3ZGO1NBQ0Y7UUFDRCxLQUFLLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO0tBQzFEO0FBQ0gsQ0FBQztBQWdDRCxTQUFTLFNBQVMsQ0FDZCxLQUFZLEVBQUUsS0FBWSxFQUFFLFFBQWtCLEVBQUUsTUFBMkIsRUFDM0UsY0FBNkIsRUFBRSxVQUFzQjtJQUN2RCxVQUFVLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzNGLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLEtBQVksRUFBRSxLQUFZLEVBQUUsZUFBZ0M7SUFDMUYsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckUsTUFBTSxXQUFXLEdBQUcsZUFBZSxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFFLENBQUM7SUFDN0QsSUFBSSxVQUFVLEdBQUcsdUJBQXVCLENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM5RSx3QkFBd0IsQ0FDcEIsUUFBUSxzQ0FBOEIsS0FBSyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDN0YsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFTLHdCQUF3QixDQUM3QixRQUFrQixFQUFFLE1BQTJCLEVBQUUsS0FBWSxFQUFFLGVBQWdDLEVBQy9GLGNBQTZCLEVBQUUsVUFBc0I7SUFDdkQsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDekQsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBaUIsQ0FBQztJQUM3RCxTQUFTO1FBQ0wsV0FBVyxDQUFDLE9BQU8sZUFBZSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztJQUMzRixNQUFNLHFCQUFxQixHQUFHLGFBQWEsQ0FBQyxVQUFXLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBRSxDQUFDO0lBQ3JGLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFO1FBQ3hDLDBGQUEwRjtRQUMxRixtRkFBbUY7UUFDbkYsd0ZBQXdGO1FBQ3hGLHdGQUF3RjtRQUN4Riw0Q0FBNEM7UUFDNUMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNyRCxNQUFNLEtBQUssR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2Qyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDaEY7S0FDRjtTQUFNO1FBQ0wsSUFBSSxhQUFhLEdBQWUscUJBQXFCLENBQUM7UUFDdEQsTUFBTSx1QkFBdUIsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFVLENBQUM7UUFDaEUsVUFBVSxDQUNOLFFBQVEsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLHVCQUF1QixFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDakc7QUFDSCxDQUFDO0FBR0Q7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsU0FBUyxjQUFjLENBQ25CLFFBQWtCLEVBQUUsTUFBMkIsRUFBRSxVQUFzQixFQUN2RSxjQUE2QixFQUFFLFVBQWdDO0lBQ2pFLFNBQVMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBRSxzQ0FBc0M7SUFDMUUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZDLHNGQUFzRjtJQUN0Riw2RkFBNkY7SUFDN0YsNEZBQTRGO0lBQzVGLHdEQUF3RDtJQUN4RCxrRkFBa0Y7SUFDbEYsOENBQThDO0lBQzlDLElBQUksTUFBTSxLQUFLLE1BQU0sRUFBRTtRQUNyQiwwRkFBMEY7UUFDMUYsaUVBQWlFO1FBQ2pFLEVBQUU7UUFDRiw0REFBNEQ7UUFDNUQseUJBQXlCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0tBQ2pGO0lBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyx1QkFBdUIsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNoRSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFVLENBQUM7UUFDckMsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDMUU7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FDeEIsUUFBa0IsRUFBRSxZQUFxQixFQUFFLEtBQWUsRUFBRSxJQUFZLEVBQUUsS0FBVTtJQUN0RixJQUFJLFlBQVksRUFBRTtRQUNoQixvRkFBb0Y7UUFDcEYsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNWLFNBQVMsSUFBSSxTQUFTLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM3QyxRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNuQzthQUFNO1lBQ0wsU0FBUyxJQUFJLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQ2hDO0tBQ0Y7U0FBTTtRQUNMLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsUUFBa0IsQ0FBQztRQUMxRixJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsNkJBQTZCLEVBQUU7WUFDL0MsU0FBUyxJQUFJLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdDLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztTQUMxQzthQUFNO1lBQ0wsK0RBQStEO1lBQy9ELHdEQUF3RDtZQUN4RCxNQUFNLFdBQVcsR0FBRyxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUVyRixJQUFJLFdBQVcsRUFBRTtnQkFDZixtRUFBbUU7Z0JBQ25FLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QixLQUFNLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDO2FBQ3pDO1lBRUQsU0FBUyxJQUFJLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDOUM7S0FDRjtBQUNILENBQUM7QUFHRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsUUFBa0IsRUFBRSxPQUFpQixFQUFFLFFBQWdCO0lBQ3RGLFNBQVMsSUFBSSxZQUFZLENBQUMsUUFBUSxFQUFFLGlDQUFpQyxDQUFDLENBQUM7SUFDdkUsUUFBUSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xELFNBQVMsSUFBSSxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUM1QyxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLFFBQWtCLEVBQUUsT0FBaUIsRUFBRSxRQUFnQjtJQUN0RixTQUFTLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRSxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ3ZFLElBQUksUUFBUSxLQUFLLEVBQUUsRUFBRTtRQUNuQiwwRkFBMEY7UUFDMUYsUUFBUSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDNUM7U0FBTTtRQUNMLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztLQUNuRDtJQUNELFNBQVMsSUFBSSxTQUFTLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztBQUNoRCxDQUFDO0FBRUQsdURBQXVEO0FBQ3ZELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxRQUFrQixFQUFFLE9BQWlCLEVBQUUsS0FBWTtJQUN2RixNQUFNLEVBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUMsR0FBRyxLQUFLLENBQUM7SUFFN0MsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFO1FBQ3hCLGVBQWUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0tBQ2pEO0lBRUQsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFO1FBQ3BCLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDOUM7SUFFRCxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUU7UUFDbkIsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM3QztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtWaWV3RW5jYXBzdWxhdGlvbn0gZnJvbSAnLi4vbWV0YWRhdGEvdmlldyc7XG5pbXBvcnQge1JlbmRlcmVyU3R5bGVGbGFnczJ9IGZyb20gJy4uL3JlbmRlci9hcGlfZmxhZ3MnO1xuaW1wb3J0IHthZGRUb0FycmF5LCByZW1vdmVGcm9tQXJyYXl9IGZyb20gJy4uL3V0aWwvYXJyYXlfdXRpbHMnO1xuaW1wb3J0IHthc3NlcnREZWZpbmVkLCBhc3NlcnRFcXVhbCwgYXNzZXJ0RnVuY3Rpb24sIGFzc2VydE51bWJlciwgYXNzZXJ0U3RyaW5nfSBmcm9tICcuLi91dGlsL2Fzc2VydCc7XG5pbXBvcnQge2VzY2FwZUNvbW1lbnRUZXh0fSBmcm9tICcuLi91dGlsL2RvbSc7XG5cbmltcG9ydCB7YXNzZXJ0TENvbnRhaW5lciwgYXNzZXJ0TFZpZXcsIGFzc2VydFBhcmVudFZpZXcsIGFzc2VydFByb2plY3Rpb25TbG90cywgYXNzZXJ0VE5vZGVGb3JMVmlld30gZnJvbSAnLi9hc3NlcnQnO1xuaW1wb3J0IHthdHRhY2hQYXRjaERhdGF9IGZyb20gJy4vY29udGV4dF9kaXNjb3ZlcnknO1xuaW1wb3J0IHtpY3VDb250YWluZXJJdGVyYXRlfSBmcm9tICcuL2kxOG4vaTE4bl90cmVlX3NoYWtpbmcnO1xuaW1wb3J0IHtDT05UQUlORVJfSEVBREVSX09GRlNFVCwgSEFTX1RSQU5TUExBTlRFRF9WSUVXUywgTENvbnRhaW5lciwgTU9WRURfVklFV1MsIE5BVElWRX0gZnJvbSAnLi9pbnRlcmZhY2VzL2NvbnRhaW5lcic7XG5pbXBvcnQge0NvbXBvbmVudERlZn0gZnJvbSAnLi9pbnRlcmZhY2VzL2RlZmluaXRpb24nO1xuaW1wb3J0IHtOb2RlSW5qZWN0b3JGYWN0b3J5fSBmcm9tICcuL2ludGVyZmFjZXMvaW5qZWN0b3InO1xuaW1wb3J0IHt1bnJlZ2lzdGVyTFZpZXd9IGZyb20gJy4vaW50ZXJmYWNlcy9sdmlld190cmFja2luZyc7XG5pbXBvcnQge1RFbGVtZW50Tm9kZSwgVEljdUNvbnRhaW5lck5vZGUsIFROb2RlLCBUTm9kZUZsYWdzLCBUTm9kZVR5cGUsIFRQcm9qZWN0aW9uTm9kZX0gZnJvbSAnLi9pbnRlcmZhY2VzL25vZGUnO1xuaW1wb3J0IHtSZW5kZXJlcn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlbmRlcmVyJztcbmltcG9ydCB7UkNvbW1lbnQsIFJFbGVtZW50LCBSTm9kZSwgUlRlbXBsYXRlLCBSVGV4dH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlbmRlcmVyX2RvbSc7XG5pbXBvcnQge2lzTENvbnRhaW5lciwgaXNMVmlld30gZnJvbSAnLi9pbnRlcmZhY2VzL3R5cGVfY2hlY2tzJztcbmltcG9ydCB7Q0hJTERfSEVBRCwgQ0xFQU5VUCwgREVDTEFSQVRJT05fQ09NUE9ORU5UX1ZJRVcsIERFQ0xBUkFUSU9OX0xDT05UQUlORVIsIERlc3Ryb3lIb29rRGF0YSwgRkxBR1MsIEhvb2tEYXRhLCBIb29rRm4sIEhPU1QsIExWaWV3LCBMVmlld0ZsYWdzLCBORVhULCBPTl9ERVNUUk9ZX0hPT0tTLCBQQVJFTlQsIFFVRVJJRVMsIFJFTkRFUkVSLCBUX0hPU1QsIFRWSUVXLCBUVmlldywgVFZpZXdUeXBlfSBmcm9tICcuL2ludGVyZmFjZXMvdmlldyc7XG5pbXBvcnQge2Fzc2VydFROb2RlVHlwZX0gZnJvbSAnLi9ub2RlX2Fzc2VydCc7XG5pbXBvcnQge3Byb2ZpbGVyLCBQcm9maWxlckV2ZW50fSBmcm9tICcuL3Byb2ZpbGVyJztcbmltcG9ydCB7c2V0VXBBdHRyaWJ1dGVzfSBmcm9tICcuL3V0aWwvYXR0cnNfdXRpbHMnO1xuaW1wb3J0IHtnZXRMVmlld1BhcmVudH0gZnJvbSAnLi91dGlsL3ZpZXdfdHJhdmVyc2FsX3V0aWxzJztcbmltcG9ydCB7Z2V0TmF0aXZlQnlUTm9kZSwgdW53cmFwUk5vZGUsIHVwZGF0ZVRyYW5zcGxhbnRlZFZpZXdDb3VudH0gZnJvbSAnLi91dGlsL3ZpZXdfdXRpbHMnO1xuXG5jb25zdCBlbnVtIFdhbGtUTm9kZVRyZWVBY3Rpb24ge1xuICAvKiogbm9kZSBjcmVhdGUgaW4gdGhlIG5hdGl2ZSBlbnZpcm9ubWVudC4gUnVuIG9uIGluaXRpYWwgY3JlYXRpb24uICovXG4gIENyZWF0ZSA9IDAsXG5cbiAgLyoqXG4gICAqIG5vZGUgaW5zZXJ0IGluIHRoZSBuYXRpdmUgZW52aXJvbm1lbnQuXG4gICAqIFJ1biB3aGVuIGV4aXN0aW5nIG5vZGUgaGFzIGJlZW4gZGV0YWNoZWQgYW5kIG5lZWRzIHRvIGJlIHJlLWF0dGFjaGVkLlxuICAgKi9cbiAgSW5zZXJ0ID0gMSxcblxuICAvKiogbm9kZSBkZXRhY2ggZnJvbSB0aGUgbmF0aXZlIGVudmlyb25tZW50ICovXG4gIERldGFjaCA9IDIsXG5cbiAgLyoqIG5vZGUgZGVzdHJ1Y3Rpb24gdXNpbmcgdGhlIHJlbmRlcmVyJ3MgQVBJICovXG4gIERlc3Ryb3kgPSAzLFxufVxuXG5cblxuLyoqXG4gKiBOT1RFOiBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgdGhlIHBvc3NpYmxlIGFjdGlvbnMgYXJlIGlubGluZWQgd2l0aGluIHRoZSBmdW5jdGlvbiBpbnN0ZWFkIG9mXG4gKiBiZWluZyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGFwcGx5VG9FbGVtZW50T3JDb250YWluZXIoXG4gICAgYWN0aW9uOiBXYWxrVE5vZGVUcmVlQWN0aW9uLCByZW5kZXJlcjogUmVuZGVyZXIsIHBhcmVudDogUkVsZW1lbnR8bnVsbCxcbiAgICBsTm9kZVRvSGFuZGxlOiBSTm9kZXxMQ29udGFpbmVyfExWaWV3LCBiZWZvcmVOb2RlPzogUk5vZGV8bnVsbCkge1xuICAvLyBJZiB0aGlzIHNsb3Qgd2FzIGFsbG9jYXRlZCBmb3IgYSB0ZXh0IG5vZGUgZHluYW1pY2FsbHkgY3JlYXRlZCBieSBpMThuLCB0aGUgdGV4dCBub2RlIGl0c2VsZlxuICAvLyB3b24ndCBiZSBjcmVhdGVkIHVudGlsIGkxOG5BcHBseSgpIGluIHRoZSB1cGRhdGUgYmxvY2ssIHNvIHRoaXMgbm9kZSBzaG91bGQgYmUgc2tpcHBlZC5cbiAgLy8gRm9yIG1vcmUgaW5mbywgc2VlIFwiSUNVIGV4cHJlc3Npb25zIHNob3VsZCB3b3JrIGluc2lkZSBhbiBuZ1RlbXBsYXRlT3V0bGV0IGluc2lkZSBhbiBuZ0ZvclwiXG4gIC8vIGluIGBpMThuX3NwZWMudHNgLlxuICBpZiAobE5vZGVUb0hhbmRsZSAhPSBudWxsKSB7XG4gICAgbGV0IGxDb250YWluZXI6IExDb250YWluZXJ8dW5kZWZpbmVkO1xuICAgIGxldCBpc0NvbXBvbmVudCA9IGZhbHNlO1xuICAgIC8vIFdlIGFyZSBleHBlY3RpbmcgYW4gUk5vZGUsIGJ1dCBpbiB0aGUgY2FzZSBvZiBhIGNvbXBvbmVudCBvciBMQ29udGFpbmVyIHRoZSBgUk5vZGVgIGlzXG4gICAgLy8gd3JhcHBlZCBpbiBhbiBhcnJheSB3aGljaCBuZWVkcyB0byBiZSB1bndyYXBwZWQuIFdlIG5lZWQgdG8ga25vdyBpZiBpdCBpcyBhIGNvbXBvbmVudCBhbmQgaWZcbiAgICAvLyBpdCBoYXMgTENvbnRhaW5lciBzbyB0aGF0IHdlIGNhbiBwcm9jZXNzIGFsbCBvZiB0aG9zZSBjYXNlcyBhcHByb3ByaWF0ZWx5LlxuICAgIGlmIChpc0xDb250YWluZXIobE5vZGVUb0hhbmRsZSkpIHtcbiAgICAgIGxDb250YWluZXIgPSBsTm9kZVRvSGFuZGxlO1xuICAgIH0gZWxzZSBpZiAoaXNMVmlldyhsTm9kZVRvSGFuZGxlKSkge1xuICAgICAgaXNDb21wb25lbnQgPSB0cnVlO1xuICAgICAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQobE5vZGVUb0hhbmRsZVtIT1NUXSwgJ0hPU1QgbXVzdCBiZSBkZWZpbmVkIGZvciBhIGNvbXBvbmVudCBMVmlldycpO1xuICAgICAgbE5vZGVUb0hhbmRsZSA9IGxOb2RlVG9IYW5kbGVbSE9TVF0hO1xuICAgIH1cbiAgICBjb25zdCByTm9kZTogUk5vZGUgPSB1bndyYXBSTm9kZShsTm9kZVRvSGFuZGxlKTtcblxuICAgIGlmIChhY3Rpb24gPT09IFdhbGtUTm9kZVRyZWVBY3Rpb24uQ3JlYXRlICYmIHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgaWYgKGJlZm9yZU5vZGUgPT0gbnVsbCkge1xuICAgICAgICBuYXRpdmVBcHBlbmRDaGlsZChyZW5kZXJlciwgcGFyZW50LCByTm9kZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYXRpdmVJbnNlcnRCZWZvcmUocmVuZGVyZXIsIHBhcmVudCwgck5vZGUsIGJlZm9yZU5vZGUgfHwgbnVsbCwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09IFdhbGtUTm9kZVRyZWVBY3Rpb24uSW5zZXJ0ICYmIHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgbmF0aXZlSW5zZXJ0QmVmb3JlKHJlbmRlcmVyLCBwYXJlbnQsIHJOb2RlLCBiZWZvcmVOb2RlIHx8IG51bGwsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAoYWN0aW9uID09PSBXYWxrVE5vZGVUcmVlQWN0aW9uLkRldGFjaCkge1xuICAgICAgbmF0aXZlUmVtb3ZlTm9kZShyZW5kZXJlciwgck5vZGUsIGlzQ29tcG9uZW50KTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gV2Fsa1ROb2RlVHJlZUFjdGlvbi5EZXN0cm95KSB7XG4gICAgICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyRGVzdHJveU5vZGUrKztcbiAgICAgIHJlbmRlcmVyLmRlc3Ryb3lOb2RlIShyTm9kZSk7XG4gICAgfVxuICAgIGlmIChsQ29udGFpbmVyICE9IG51bGwpIHtcbiAgICAgIGFwcGx5Q29udGFpbmVyKHJlbmRlcmVyLCBhY3Rpb24sIGxDb250YWluZXIsIHBhcmVudCwgYmVmb3JlTm9kZSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUZXh0Tm9kZShyZW5kZXJlcjogUmVuZGVyZXIsIHZhbHVlOiBzdHJpbmcpOiBSVGV4dCB7XG4gIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJDcmVhdGVUZXh0Tm9kZSsrO1xuICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyU2V0VGV4dCsrO1xuICByZXR1cm4gcmVuZGVyZXIuY3JlYXRlVGV4dCh2YWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVUZXh0Tm9kZShyZW5kZXJlcjogUmVuZGVyZXIsIHJOb2RlOiBSVGV4dCwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyU2V0VGV4dCsrO1xuICByZW5kZXJlci5zZXRWYWx1ZShyTm9kZSwgdmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29tbWVudE5vZGUocmVuZGVyZXI6IFJlbmRlcmVyLCB2YWx1ZTogc3RyaW5nKTogUkNvbW1lbnQge1xuICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyQ3JlYXRlQ29tbWVudCsrO1xuICByZXR1cm4gcmVuZGVyZXIuY3JlYXRlQ29tbWVudChlc2NhcGVDb21tZW50VGV4dCh2YWx1ZSkpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuYXRpdmUgZWxlbWVudCBmcm9tIGEgdGFnIG5hbWUsIHVzaW5nIGEgcmVuZGVyZXIuXG4gKiBAcGFyYW0gcmVuZGVyZXIgQSByZW5kZXJlciB0byB1c2VcbiAqIEBwYXJhbSBuYW1lIHRoZSB0YWcgbmFtZVxuICogQHBhcmFtIG5hbWVzcGFjZSBPcHRpb25hbCBuYW1lc3BhY2UgZm9yIGVsZW1lbnQuXG4gKiBAcmV0dXJucyB0aGUgZWxlbWVudCBjcmVhdGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbGVtZW50Tm9kZShcbiAgICByZW5kZXJlcjogUmVuZGVyZXIsIG5hbWU6IHN0cmluZywgbmFtZXNwYWNlOiBzdHJpbmd8bnVsbCk6IFJFbGVtZW50IHtcbiAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlckNyZWF0ZUVsZW1lbnQrKztcbiAgcmV0dXJuIHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQobmFtZSwgbmFtZXNwYWNlKTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgYWxsIERPTSBlbGVtZW50cyBhc3NvY2lhdGVkIHdpdGggYSB2aWV3LlxuICpcbiAqIEJlY2F1c2Ugc29tZSByb290IG5vZGVzIG9mIHRoZSB2aWV3IG1heSBiZSBjb250YWluZXJzLCB3ZSBzb21ldGltZXMgbmVlZFxuICogdG8gcHJvcGFnYXRlIGRlZXBseSBpbnRvIHRoZSBuZXN0ZWQgY29udGFpbmVycyB0byByZW1vdmUgYWxsIGVsZW1lbnRzIGluIHRoZVxuICogdmlld3MgYmVuZWF0aCBpdC5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgVGhlIGBUVmlldycgb2YgdGhlIGBMVmlld2AgZnJvbSB3aGljaCBlbGVtZW50cyBzaG91bGQgYmUgYWRkZWQgb3IgcmVtb3ZlZFxuICogQHBhcmFtIGxWaWV3IFRoZSB2aWV3IGZyb20gd2hpY2ggZWxlbWVudHMgc2hvdWxkIGJlIGFkZGVkIG9yIHJlbW92ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVZpZXdGcm9tQ29udGFpbmVyKHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3KTogdm9pZCB7XG4gIGNvbnN0IHJlbmRlcmVyID0gbFZpZXdbUkVOREVSRVJdO1xuICBhcHBseVZpZXcodFZpZXcsIGxWaWV3LCByZW5kZXJlciwgV2Fsa1ROb2RlVHJlZUFjdGlvbi5EZXRhY2gsIG51bGwsIG51bGwpO1xuICBsVmlld1tIT1NUXSA9IG51bGw7XG4gIGxWaWV3W1RfSE9TVF0gPSBudWxsO1xufVxuXG4vKipcbiAqIEFkZHMgYWxsIERPTSBlbGVtZW50cyBhc3NvY2lhdGVkIHdpdGggYSB2aWV3LlxuICpcbiAqIEJlY2F1c2Ugc29tZSByb290IG5vZGVzIG9mIHRoZSB2aWV3IG1heSBiZSBjb250YWluZXJzLCB3ZSBzb21ldGltZXMgbmVlZFxuICogdG8gcHJvcGFnYXRlIGRlZXBseSBpbnRvIHRoZSBuZXN0ZWQgY29udGFpbmVycyB0byBhZGQgYWxsIGVsZW1lbnRzIGluIHRoZVxuICogdmlld3MgYmVuZWF0aCBpdC5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgVGhlIGBUVmlldycgb2YgdGhlIGBMVmlld2AgZnJvbSB3aGljaCBlbGVtZW50cyBzaG91bGQgYmUgYWRkZWQgb3IgcmVtb3ZlZFxuICogQHBhcmFtIHBhcmVudFROb2RlIFRoZSBgVE5vZGVgIHdoZXJlIHRoZSBgTFZpZXdgIHNob3VsZCBiZSBhdHRhY2hlZCB0by5cbiAqIEBwYXJhbSByZW5kZXJlciBDdXJyZW50IHJlbmRlcmVyIHRvIHVzZSBmb3IgRE9NIG1hbmlwdWxhdGlvbnMuXG4gKiBAcGFyYW0gbFZpZXcgVGhlIHZpZXcgZnJvbSB3aGljaCBlbGVtZW50cyBzaG91bGQgYmUgYWRkZWQgb3IgcmVtb3ZlZFxuICogQHBhcmFtIHBhcmVudE5hdGl2ZU5vZGUgVGhlIHBhcmVudCBgUkVsZW1lbnRgIHdoZXJlIGl0IHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvLlxuICogQHBhcmFtIGJlZm9yZU5vZGUgVGhlIG5vZGUgYmVmb3JlIHdoaWNoIGVsZW1lbnRzIHNob3VsZCBiZSBhZGRlZCwgaWYgaW5zZXJ0IG1vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFZpZXdUb0NvbnRhaW5lcihcbiAgICB0VmlldzogVFZpZXcsIHBhcmVudFROb2RlOiBUTm9kZSwgcmVuZGVyZXI6IFJlbmRlcmVyLCBsVmlldzogTFZpZXcsIHBhcmVudE5hdGl2ZU5vZGU6IFJFbGVtZW50LFxuICAgIGJlZm9yZU5vZGU6IFJOb2RlfG51bGwpOiB2b2lkIHtcbiAgbFZpZXdbSE9TVF0gPSBwYXJlbnROYXRpdmVOb2RlO1xuICBsVmlld1tUX0hPU1RdID0gcGFyZW50VE5vZGU7XG4gIGFwcGx5Vmlldyh0VmlldywgbFZpZXcsIHJlbmRlcmVyLCBXYWxrVE5vZGVUcmVlQWN0aW9uLkluc2VydCwgcGFyZW50TmF0aXZlTm9kZSwgYmVmb3JlTm9kZSk7XG59XG5cblxuLyoqXG4gKiBEZXRhY2ggYSBgTFZpZXdgIGZyb20gdGhlIERPTSBieSBkZXRhY2hpbmcgaXRzIG5vZGVzLlxuICpcbiAqIEBwYXJhbSB0VmlldyBUaGUgYFRWaWV3JyBvZiB0aGUgYExWaWV3YCB0byBiZSBkZXRhY2hlZFxuICogQHBhcmFtIGxWaWV3IHRoZSBgTFZpZXdgIHRvIGJlIGRldGFjaGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyRGV0YWNoVmlldyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldykge1xuICBhcHBseVZpZXcodFZpZXcsIGxWaWV3LCBsVmlld1tSRU5ERVJFUl0sIFdhbGtUTm9kZVRyZWVBY3Rpb24uRGV0YWNoLCBudWxsLCBudWxsKTtcbn1cblxuLyoqXG4gKiBUcmF2ZXJzZXMgZG93biBhbmQgdXAgdGhlIHRyZWUgb2Ygdmlld3MgYW5kIGNvbnRhaW5lcnMgdG8gcmVtb3ZlIGxpc3RlbmVycyBhbmRcbiAqIGNhbGwgb25EZXN0cm95IGNhbGxiYWNrcy5cbiAqXG4gKiBOb3RlczpcbiAqICAtIEJlY2F1c2UgaXQncyB1c2VkIGZvciBvbkRlc3Ryb3kgY2FsbHMsIGl0IG5lZWRzIHRvIGJlIGJvdHRvbS11cC5cbiAqICAtIE11c3QgcHJvY2VzcyBjb250YWluZXJzIGluc3RlYWQgb2YgdGhlaXIgdmlld3MgdG8gYXZvaWQgc3BsaWNpbmdcbiAqICB3aGVuIHZpZXdzIGFyZSBkZXN0cm95ZWQgYW5kIHJlLWFkZGVkLlxuICogIC0gVXNpbmcgYSB3aGlsZSBsb29wIGJlY2F1c2UgaXQncyBmYXN0ZXIgdGhhbiByZWN1cnNpb25cbiAqICAtIERlc3Ryb3kgb25seSBjYWxsZWQgb24gbW92ZW1lbnQgdG8gc2libGluZyBvciBtb3ZlbWVudCB0byBwYXJlbnQgKGxhdGVyYWxseSBvciB1cClcbiAqXG4gKiAgQHBhcmFtIHJvb3RWaWV3IFRoZSB2aWV3IHRvIGRlc3Ryb3lcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lWaWV3VHJlZShyb290VmlldzogTFZpZXcpOiB2b2lkIHtcbiAgLy8gSWYgdGhlIHZpZXcgaGFzIG5vIGNoaWxkcmVuLCB3ZSBjYW4gY2xlYW4gaXQgdXAgYW5kIHJldHVybiBlYXJseS5cbiAgbGV0IGxWaWV3T3JMQ29udGFpbmVyID0gcm9vdFZpZXdbQ0hJTERfSEVBRF07XG4gIGlmICghbFZpZXdPckxDb250YWluZXIpIHtcbiAgICByZXR1cm4gY2xlYW5VcFZpZXcocm9vdFZpZXdbVFZJRVddLCByb290Vmlldyk7XG4gIH1cblxuICB3aGlsZSAobFZpZXdPckxDb250YWluZXIpIHtcbiAgICBsZXQgbmV4dDogTFZpZXd8TENvbnRhaW5lcnxudWxsID0gbnVsbDtcblxuICAgIGlmIChpc0xWaWV3KGxWaWV3T3JMQ29udGFpbmVyKSkge1xuICAgICAgLy8gSWYgTFZpZXcsIHRyYXZlcnNlIGRvd24gdG8gY2hpbGQuXG4gICAgICBuZXh0ID0gbFZpZXdPckxDb250YWluZXJbQ0hJTERfSEVBRF07XG4gICAgfSBlbHNlIHtcbiAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnRMQ29udGFpbmVyKGxWaWV3T3JMQ29udGFpbmVyKTtcbiAgICAgIC8vIElmIGNvbnRhaW5lciwgdHJhdmVyc2UgZG93biB0byBpdHMgZmlyc3QgTFZpZXcuXG4gICAgICBjb25zdCBmaXJzdFZpZXc6IExWaWV3fHVuZGVmaW5lZCA9IGxWaWV3T3JMQ29udGFpbmVyW0NPTlRBSU5FUl9IRUFERVJfT0ZGU0VUXTtcbiAgICAgIGlmIChmaXJzdFZpZXcpIG5leHQgPSBmaXJzdFZpZXc7XG4gICAgfVxuXG4gICAgaWYgKCFuZXh0KSB7XG4gICAgICAvLyBPbmx5IGNsZWFuIHVwIHZpZXcgd2hlbiBtb3ZpbmcgdG8gdGhlIHNpZGUgb3IgdXAsIGFzIGRlc3Ryb3kgaG9va3NcbiAgICAgIC8vIHNob3VsZCBiZSBjYWxsZWQgaW4gb3JkZXIgZnJvbSB0aGUgYm90dG9tIHVwLlxuICAgICAgd2hpbGUgKGxWaWV3T3JMQ29udGFpbmVyICYmICFsVmlld09yTENvbnRhaW5lciFbTkVYVF0gJiYgbFZpZXdPckxDb250YWluZXIgIT09IHJvb3RWaWV3KSB7XG4gICAgICAgIGlmIChpc0xWaWV3KGxWaWV3T3JMQ29udGFpbmVyKSkge1xuICAgICAgICAgIGNsZWFuVXBWaWV3KGxWaWV3T3JMQ29udGFpbmVyW1RWSUVXXSwgbFZpZXdPckxDb250YWluZXIpO1xuICAgICAgICB9XG4gICAgICAgIGxWaWV3T3JMQ29udGFpbmVyID0gbFZpZXdPckxDb250YWluZXJbUEFSRU5UXTtcbiAgICAgIH1cbiAgICAgIGlmIChsVmlld09yTENvbnRhaW5lciA9PT0gbnVsbCkgbFZpZXdPckxDb250YWluZXIgPSByb290VmlldztcbiAgICAgIGlmIChpc0xWaWV3KGxWaWV3T3JMQ29udGFpbmVyKSkge1xuICAgICAgICBjbGVhblVwVmlldyhsVmlld09yTENvbnRhaW5lcltUVklFV10sIGxWaWV3T3JMQ29udGFpbmVyKTtcbiAgICAgIH1cbiAgICAgIG5leHQgPSBsVmlld09yTENvbnRhaW5lciAmJiBsVmlld09yTENvbnRhaW5lciFbTkVYVF07XG4gICAgfVxuICAgIGxWaWV3T3JMQ29udGFpbmVyID0gbmV4dDtcbiAgfVxufVxuXG4vKipcbiAqIEluc2VydHMgYSB2aWV3IGludG8gYSBjb250YWluZXIuXG4gKlxuICogVGhpcyBhZGRzIHRoZSB2aWV3IHRvIHRoZSBjb250YWluZXIncyBhcnJheSBvZiBhY3RpdmUgdmlld3MgaW4gdGhlIGNvcnJlY3RcbiAqIHBvc2l0aW9uLiBJdCBhbHNvIGFkZHMgdGhlIHZpZXcncyBlbGVtZW50cyB0byB0aGUgRE9NIGlmIHRoZSBjb250YWluZXIgaXNuJ3QgYVxuICogcm9vdCBub2RlIG9mIGFub3RoZXIgdmlldyAoaW4gdGhhdCBjYXNlLCB0aGUgdmlldydzIGVsZW1lbnRzIHdpbGwgYmUgYWRkZWQgd2hlblxuICogdGhlIGNvbnRhaW5lcidzIHBhcmVudCB2aWV3IGlzIGFkZGVkIGxhdGVyKS5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgVGhlIGBUVmlldycgb2YgdGhlIGBMVmlld2AgdG8gaW5zZXJ0XG4gKiBAcGFyYW0gbFZpZXcgVGhlIHZpZXcgdG8gaW5zZXJ0XG4gKiBAcGFyYW0gbENvbnRhaW5lciBUaGUgY29udGFpbmVyIGludG8gd2hpY2ggdGhlIHZpZXcgc2hvdWxkIGJlIGluc2VydGVkXG4gKiBAcGFyYW0gaW5kZXggV2hpY2ggaW5kZXggaW4gdGhlIGNvbnRhaW5lciB0byBpbnNlcnQgdGhlIGNoaWxkIHZpZXcgaW50b1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0Vmlldyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgbENvbnRhaW5lcjogTENvbnRhaW5lciwgaW5kZXg6IG51bWJlcikge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TFZpZXcobFZpZXcpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihsQ29udGFpbmVyKTtcbiAgY29uc3QgaW5kZXhJbkNvbnRhaW5lciA9IENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUICsgaW5kZXg7XG4gIGNvbnN0IGNvbnRhaW5lckxlbmd0aCA9IGxDb250YWluZXIubGVuZ3RoO1xuXG4gIGlmIChpbmRleCA+IDApIHtcbiAgICAvLyBUaGlzIGlzIGEgbmV3IHZpZXcsIHdlIG5lZWQgdG8gYWRkIGl0IHRvIHRoZSBjaGlsZHJlbi5cbiAgICBsQ29udGFpbmVyW2luZGV4SW5Db250YWluZXIgLSAxXVtORVhUXSA9IGxWaWV3O1xuICB9XG4gIGlmIChpbmRleCA8IGNvbnRhaW5lckxlbmd0aCAtIENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUKSB7XG4gICAgbFZpZXdbTkVYVF0gPSBsQ29udGFpbmVyW2luZGV4SW5Db250YWluZXJdO1xuICAgIGFkZFRvQXJyYXkobENvbnRhaW5lciwgQ09OVEFJTkVSX0hFQURFUl9PRkZTRVQgKyBpbmRleCwgbFZpZXcpO1xuICB9IGVsc2Uge1xuICAgIGxDb250YWluZXIucHVzaChsVmlldyk7XG4gICAgbFZpZXdbTkVYVF0gPSBudWxsO1xuICB9XG5cbiAgbFZpZXdbUEFSRU5UXSA9IGxDb250YWluZXI7XG5cbiAgLy8gdHJhY2sgdmlld3Mgd2hlcmUgZGVjbGFyYXRpb24gYW5kIGluc2VydGlvbiBwb2ludHMgYXJlIGRpZmZlcmVudFxuICBjb25zdCBkZWNsYXJhdGlvbkxDb250YWluZXIgPSBsVmlld1tERUNMQVJBVElPTl9MQ09OVEFJTkVSXTtcbiAgaWYgKGRlY2xhcmF0aW9uTENvbnRhaW5lciAhPT0gbnVsbCAmJiBsQ29udGFpbmVyICE9PSBkZWNsYXJhdGlvbkxDb250YWluZXIpIHtcbiAgICB0cmFja01vdmVkVmlldyhkZWNsYXJhdGlvbkxDb250YWluZXIsIGxWaWV3KTtcbiAgfVxuXG4gIC8vIG5vdGlmeSBxdWVyeSB0aGF0IGEgbmV3IHZpZXcgaGFzIGJlZW4gYWRkZWRcbiAgY29uc3QgbFF1ZXJpZXMgPSBsVmlld1tRVUVSSUVTXTtcbiAgaWYgKGxRdWVyaWVzICE9PSBudWxsKSB7XG4gICAgbFF1ZXJpZXMuaW5zZXJ0Vmlldyh0Vmlldyk7XG4gIH1cblxuICAvLyBTZXRzIHRoZSBhdHRhY2hlZCBmbGFnXG4gIGxWaWV3W0ZMQUdTXSB8PSBMVmlld0ZsYWdzLkF0dGFjaGVkO1xufVxuXG4vKipcbiAqIFRyYWNrIHZpZXdzIGNyZWF0ZWQgZnJvbSB0aGUgZGVjbGFyYXRpb24gY29udGFpbmVyIChUZW1wbGF0ZVJlZikgYW5kIGluc2VydGVkIGludG8gYVxuICogZGlmZmVyZW50IExDb250YWluZXIuXG4gKi9cbmZ1bmN0aW9uIHRyYWNrTW92ZWRWaWV3KGRlY2xhcmF0aW9uQ29udGFpbmVyOiBMQ29udGFpbmVyLCBsVmlldzogTFZpZXcpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQobFZpZXcsICdMVmlldyByZXF1aXJlZCcpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihkZWNsYXJhdGlvbkNvbnRhaW5lcik7XG4gIGNvbnN0IG1vdmVkVmlld3MgPSBkZWNsYXJhdGlvbkNvbnRhaW5lcltNT1ZFRF9WSUVXU107XG4gIGNvbnN0IGluc2VydGVkTENvbnRhaW5lciA9IGxWaWV3W1BBUkVOVF0gYXMgTENvbnRhaW5lcjtcbiAgbmdEZXZNb2RlICYmIGFzc2VydExDb250YWluZXIoaW5zZXJ0ZWRMQ29udGFpbmVyKTtcbiAgY29uc3QgaW5zZXJ0ZWRDb21wb25lbnRMVmlldyA9IGluc2VydGVkTENvbnRhaW5lcltQQVJFTlRdIVtERUNMQVJBVElPTl9DT01QT05FTlRfVklFV107XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKGluc2VydGVkQ29tcG9uZW50TFZpZXcsICdNaXNzaW5nIGluc2VydGVkQ29tcG9uZW50TFZpZXcnKTtcbiAgY29uc3QgZGVjbGFyZWRDb21wb25lbnRMVmlldyA9IGxWaWV3W0RFQ0xBUkFUSU9OX0NPTVBPTkVOVF9WSUVXXTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQoZGVjbGFyZWRDb21wb25lbnRMVmlldywgJ01pc3NpbmcgZGVjbGFyZWRDb21wb25lbnRMVmlldycpO1xuICBpZiAoZGVjbGFyZWRDb21wb25lbnRMVmlldyAhPT0gaW5zZXJ0ZWRDb21wb25lbnRMVmlldykge1xuICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIGRlY2xhcmF0aW9uLWNvbXBvbmVudCBpcyBub3Qgc2FtZSBhcyBpbnNlcnRpb24tY29tcG9uZW50OyB0aGlzIG1lYW5zIHRoYXRcbiAgICAvLyB0aGlzIGlzIGEgdHJhbnNwbGFudGVkIHZpZXcuIE1hcmsgdGhlIGRlY2xhcmVkIGxWaWV3IGFzIGhhdmluZyB0cmFuc3BsYW50ZWQgdmlld3Mgc28gdGhhdFxuICAgIC8vIHRob3NlIHZpZXdzIGNhbiBwYXJ0aWNpcGF0ZSBpbiBDRC5cbiAgICBkZWNsYXJhdGlvbkNvbnRhaW5lcltIQVNfVFJBTlNQTEFOVEVEX1ZJRVdTXSA9IHRydWU7XG4gIH1cbiAgaWYgKG1vdmVkVmlld3MgPT09IG51bGwpIHtcbiAgICBkZWNsYXJhdGlvbkNvbnRhaW5lcltNT1ZFRF9WSUVXU10gPSBbbFZpZXddO1xuICB9IGVsc2Uge1xuICAgIG1vdmVkVmlld3MucHVzaChsVmlldyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGV0YWNoTW92ZWRWaWV3KGRlY2xhcmF0aW9uQ29udGFpbmVyOiBMQ29udGFpbmVyLCBsVmlldzogTFZpZXcpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydExDb250YWluZXIoZGVjbGFyYXRpb25Db250YWluZXIpO1xuICBuZ0Rldk1vZGUgJiZcbiAgICAgIGFzc2VydERlZmluZWQoXG4gICAgICAgICAgZGVjbGFyYXRpb25Db250YWluZXJbTU9WRURfVklFV1NdLFxuICAgICAgICAgICdBIHByb2plY3RlZCB2aWV3IHNob3VsZCBiZWxvbmcgdG8gYSBub24tZW1wdHkgcHJvamVjdGVkIHZpZXdzIGNvbGxlY3Rpb24nKTtcbiAgY29uc3QgbW92ZWRWaWV3cyA9IGRlY2xhcmF0aW9uQ29udGFpbmVyW01PVkVEX1ZJRVdTXSE7XG4gIGNvbnN0IGRlY2xhcmF0aW9uVmlld0luZGV4ID0gbW92ZWRWaWV3cy5pbmRleE9mKGxWaWV3KTtcbiAgY29uc3QgaW5zZXJ0aW9uTENvbnRhaW5lciA9IGxWaWV3W1BBUkVOVF0gYXMgTENvbnRhaW5lcjtcbiAgbmdEZXZNb2RlICYmIGFzc2VydExDb250YWluZXIoaW5zZXJ0aW9uTENvbnRhaW5lcik7XG5cbiAgLy8gSWYgdGhlIHZpZXcgd2FzIG1hcmtlZCBmb3IgcmVmcmVzaCBidXQgdGhlbiBkZXRhY2hlZCBiZWZvcmUgaXQgd2FzIGNoZWNrZWQgKHdoZXJlIHRoZSBmbGFnXG4gIC8vIHdvdWxkIGJlIGNsZWFyZWQgYW5kIHRoZSBjb3VudGVyIGRlY3JlbWVudGVkKSwgd2UgbmVlZCB0byBkZWNyZW1lbnQgdGhlIHZpZXcgY291bnRlciBoZXJlXG4gIC8vIGluc3RlYWQuXG4gIGlmIChsVmlld1tGTEFHU10gJiBMVmlld0ZsYWdzLlJlZnJlc2hUcmFuc3BsYW50ZWRWaWV3KSB7XG4gICAgbFZpZXdbRkxBR1NdICY9IH5MVmlld0ZsYWdzLlJlZnJlc2hUcmFuc3BsYW50ZWRWaWV3O1xuICAgIHVwZGF0ZVRyYW5zcGxhbnRlZFZpZXdDb3VudChpbnNlcnRpb25MQ29udGFpbmVyLCAtMSk7XG4gIH1cblxuICBtb3ZlZFZpZXdzLnNwbGljZShkZWNsYXJhdGlvblZpZXdJbmRleCwgMSk7XG59XG5cbi8qKlxuICogRGV0YWNoZXMgYSB2aWV3IGZyb20gYSBjb250YWluZXIuXG4gKlxuICogVGhpcyBtZXRob2QgcmVtb3ZlcyB0aGUgdmlldyBmcm9tIHRoZSBjb250YWluZXIncyBhcnJheSBvZiBhY3RpdmUgdmlld3MuIEl0IGFsc29cbiAqIHJlbW92ZXMgdGhlIHZpZXcncyBlbGVtZW50cyBmcm9tIHRoZSBET00uXG4gKlxuICogQHBhcmFtIGxDb250YWluZXIgVGhlIGNvbnRhaW5lciBmcm9tIHdoaWNoIHRvIGRldGFjaCBhIHZpZXdcbiAqIEBwYXJhbSByZW1vdmVJbmRleCBUaGUgaW5kZXggb2YgdGhlIHZpZXcgdG8gZGV0YWNoXG4gKiBAcmV0dXJucyBEZXRhY2hlZCBMVmlldyBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGFjaFZpZXcobENvbnRhaW5lcjogTENvbnRhaW5lciwgcmVtb3ZlSW5kZXg6IG51bWJlcik6IExWaWV3fHVuZGVmaW5lZCB7XG4gIGlmIChsQ29udGFpbmVyLmxlbmd0aCA8PSBDT05UQUlORVJfSEVBREVSX09GRlNFVCkgcmV0dXJuO1xuXG4gIGNvbnN0IGluZGV4SW5Db250YWluZXIgPSBDT05UQUlORVJfSEVBREVSX09GRlNFVCArIHJlbW92ZUluZGV4O1xuICBjb25zdCB2aWV3VG9EZXRhY2ggPSBsQ29udGFpbmVyW2luZGV4SW5Db250YWluZXJdO1xuXG4gIGlmICh2aWV3VG9EZXRhY2gpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbkxDb250YWluZXIgPSB2aWV3VG9EZXRhY2hbREVDTEFSQVRJT05fTENPTlRBSU5FUl07XG4gICAgaWYgKGRlY2xhcmF0aW9uTENvbnRhaW5lciAhPT0gbnVsbCAmJiBkZWNsYXJhdGlvbkxDb250YWluZXIgIT09IGxDb250YWluZXIpIHtcbiAgICAgIGRldGFjaE1vdmVkVmlldyhkZWNsYXJhdGlvbkxDb250YWluZXIsIHZpZXdUb0RldGFjaCk7XG4gICAgfVxuXG5cbiAgICBpZiAocmVtb3ZlSW5kZXggPiAwKSB7XG4gICAgICBsQ29udGFpbmVyW2luZGV4SW5Db250YWluZXIgLSAxXVtORVhUXSA9IHZpZXdUb0RldGFjaFtORVhUXSBhcyBMVmlldztcbiAgICB9XG4gICAgY29uc3QgcmVtb3ZlZExWaWV3ID0gcmVtb3ZlRnJvbUFycmF5KGxDb250YWluZXIsIENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUICsgcmVtb3ZlSW5kZXgpO1xuICAgIHJlbW92ZVZpZXdGcm9tQ29udGFpbmVyKHZpZXdUb0RldGFjaFtUVklFV10sIHZpZXdUb0RldGFjaCk7XG5cbiAgICAvLyBub3RpZnkgcXVlcnkgdGhhdCBhIHZpZXcgaGFzIGJlZW4gcmVtb3ZlZFxuICAgIGNvbnN0IGxRdWVyaWVzID0gcmVtb3ZlZExWaWV3W1FVRVJJRVNdO1xuICAgIGlmIChsUXVlcmllcyAhPT0gbnVsbCkge1xuICAgICAgbFF1ZXJpZXMuZGV0YWNoVmlldyhyZW1vdmVkTFZpZXdbVFZJRVddKTtcbiAgICB9XG5cbiAgICB2aWV3VG9EZXRhY2hbUEFSRU5UXSA9IG51bGw7XG4gICAgdmlld1RvRGV0YWNoW05FWFRdID0gbnVsbDtcbiAgICAvLyBVbnNldHMgdGhlIGF0dGFjaGVkIGZsYWdcbiAgICB2aWV3VG9EZXRhY2hbRkxBR1NdICY9IH5MVmlld0ZsYWdzLkF0dGFjaGVkO1xuICB9XG4gIHJldHVybiB2aWV3VG9EZXRhY2g7XG59XG5cbi8qKlxuICogQSBzdGFuZGFsb25lIGZ1bmN0aW9uIHdoaWNoIGRlc3Ryb3lzIGFuIExWaWV3LFxuICogY29uZHVjdGluZyBjbGVhbiB1cCAoZS5nLiByZW1vdmluZyBsaXN0ZW5lcnMsIGNhbGxpbmcgb25EZXN0cm95cykuXG4gKlxuICogQHBhcmFtIHRWaWV3IFRoZSBgVFZpZXcnIG9mIHRoZSBgTFZpZXdgIHRvIGJlIGRlc3Ryb3llZFxuICogQHBhcmFtIGxWaWV3IFRoZSB2aWV3IHRvIGJlIGRlc3Ryb3llZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lMVmlldyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldykge1xuICBpZiAoIShsVmlld1tGTEFHU10gJiBMVmlld0ZsYWdzLkRlc3Ryb3llZCkpIHtcbiAgICBjb25zdCByZW5kZXJlciA9IGxWaWV3W1JFTkRFUkVSXTtcbiAgICBpZiAocmVuZGVyZXIuZGVzdHJveU5vZGUpIHtcbiAgICAgIGFwcGx5Vmlldyh0VmlldywgbFZpZXcsIHJlbmRlcmVyLCBXYWxrVE5vZGVUcmVlQWN0aW9uLkRlc3Ryb3ksIG51bGwsIG51bGwpO1xuICAgIH1cblxuICAgIGRlc3Ryb3lWaWV3VHJlZShsVmlldyk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxscyBvbkRlc3Ryb3lzIGhvb2tzIGZvciBhbGwgZGlyZWN0aXZlcyBhbmQgcGlwZXMgaW4gYSBnaXZlbiB2aWV3IGFuZCB0aGVuIHJlbW92ZXMgYWxsXG4gKiBsaXN0ZW5lcnMuIExpc3RlbmVycyBhcmUgcmVtb3ZlZCBhcyB0aGUgbGFzdCBzdGVwIHNvIGV2ZW50cyBkZWxpdmVyZWQgaW4gdGhlIG9uRGVzdHJveXMgaG9va3NcbiAqIGNhbiBiZSBwcm9wYWdhdGVkIHRvIEBPdXRwdXQgbGlzdGVuZXJzLlxuICpcbiAqIEBwYXJhbSB0VmlldyBgVFZpZXdgIGZvciB0aGUgYExWaWV3YCB0byBjbGVhbiB1cC5cbiAqIEBwYXJhbSBsVmlldyBUaGUgTFZpZXcgdG8gY2xlYW4gdXBcbiAqL1xuZnVuY3Rpb24gY2xlYW5VcFZpZXcodFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcpOiB2b2lkIHtcbiAgaWYgKCEobFZpZXdbRkxBR1NdICYgTFZpZXdGbGFncy5EZXN0cm95ZWQpKSB7XG4gICAgLy8gVXN1YWxseSB0aGUgQXR0YWNoZWQgZmxhZyBpcyByZW1vdmVkIHdoZW4gdGhlIHZpZXcgaXMgZGV0YWNoZWQgZnJvbSBpdHMgcGFyZW50LCBob3dldmVyXG4gICAgLy8gaWYgaXQncyBhIHJvb3QgdmlldywgdGhlIGZsYWcgd29uJ3QgYmUgdW5zZXQgaGVuY2Ugd2h5IHdlJ3JlIGFsc28gcmVtb3Zpbmcgb24gZGVzdHJveS5cbiAgICBsVmlld1tGTEFHU10gJj0gfkxWaWV3RmxhZ3MuQXR0YWNoZWQ7XG5cbiAgICAvLyBNYXJrIHRoZSBMVmlldyBhcyBkZXN0cm95ZWQgKmJlZm9yZSogZXhlY3V0aW5nIHRoZSBvbkRlc3Ryb3kgaG9va3MuIEFuIG9uRGVzdHJveSBob29rXG4gICAgLy8gcnVucyBhcmJpdHJhcnkgdXNlciBjb2RlLCB3aGljaCBjb3VsZCBpbmNsdWRlIGl0cyBvd24gYHZpZXdSZWYuZGVzdHJveSgpYCAob3Igc2ltaWxhcikuIElmXG4gICAgLy8gV2UgZG9uJ3QgZmxhZyB0aGUgdmlldyBhcyBkZXN0cm95ZWQgYmVmb3JlIHRoZSBob29rcywgdGhpcyBjb3VsZCBsZWFkIHRvIGFuIGluZmluaXRlIGxvb3AuXG4gICAgLy8gVGhpcyBhbHNvIGFsaWducyB3aXRoIHRoZSBWaWV3RW5naW5lIGJlaGF2aW9yLiBJdCBhbHNvIG1lYW5zIHRoYXQgdGhlIG9uRGVzdHJveSBob29rIGlzXG4gICAgLy8gcmVhbGx5IG1vcmUgb2YgYW4gXCJhZnRlckRlc3Ryb3lcIiBob29rIGlmIHlvdSB0aGluayBhYm91dCBpdC5cbiAgICBsVmlld1tGTEFHU10gfD0gTFZpZXdGbGFncy5EZXN0cm95ZWQ7XG5cbiAgICBleGVjdXRlT25EZXN0cm95cyh0VmlldywgbFZpZXcpO1xuICAgIHByb2Nlc3NDbGVhbnVwcyh0VmlldywgbFZpZXcpO1xuICAgIC8vIEZvciBjb21wb25lbnQgdmlld3Mgb25seSwgdGhlIGxvY2FsIHJlbmRlcmVyIGlzIGRlc3Ryb3llZCBhdCBjbGVhbiB1cCB0aW1lLlxuICAgIGlmIChsVmlld1tUVklFV10udHlwZSA9PT0gVFZpZXdUeXBlLkNvbXBvbmVudCkge1xuICAgICAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlckRlc3Ryb3krKztcbiAgICAgIGxWaWV3W1JFTkRFUkVSXS5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVjbGFyYXRpb25Db250YWluZXIgPSBsVmlld1tERUNMQVJBVElPTl9MQ09OVEFJTkVSXTtcbiAgICAvLyB3ZSBhcmUgZGVhbGluZyB3aXRoIGFuIGVtYmVkZGVkIHZpZXcgdGhhdCBpcyBzdGlsbCBpbnNlcnRlZCBpbnRvIGEgY29udGFpbmVyXG4gICAgaWYgKGRlY2xhcmF0aW9uQ29udGFpbmVyICE9PSBudWxsICYmIGlzTENvbnRhaW5lcihsVmlld1tQQVJFTlRdKSkge1xuICAgICAgLy8gYW5kIHRoaXMgaXMgYSBwcm9qZWN0ZWQgdmlld1xuICAgICAgaWYgKGRlY2xhcmF0aW9uQ29udGFpbmVyICE9PSBsVmlld1tQQVJFTlRdKSB7XG4gICAgICAgIGRldGFjaE1vdmVkVmlldyhkZWNsYXJhdGlvbkNvbnRhaW5lciwgbFZpZXcpO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3IgZW1iZWRkZWQgdmlld3Mgc3RpbGwgYXR0YWNoZWQgdG8gYSBjb250YWluZXI6IHJlbW92ZSBxdWVyeSByZXN1bHQgZnJvbSB0aGlzIHZpZXcuXG4gICAgICBjb25zdCBsUXVlcmllcyA9IGxWaWV3W1FVRVJJRVNdO1xuICAgICAgaWYgKGxRdWVyaWVzICE9PSBudWxsKSB7XG4gICAgICAgIGxRdWVyaWVzLmRldGFjaFZpZXcodFZpZXcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFVucmVnaXN0ZXIgdGhlIHZpZXcgb25jZSBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4gY2xlYW5lZCB1cC5cbiAgICB1bnJlZ2lzdGVyTFZpZXcobFZpZXcpO1xuICB9XG59XG5cbi8qKiBSZW1vdmVzIGxpc3RlbmVycyBhbmQgdW5zdWJzY3JpYmVzIGZyb20gb3V0cHV0IHN1YnNjcmlwdGlvbnMgKi9cbmZ1bmN0aW9uIHByb2Nlc3NDbGVhbnVwcyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldyk6IHZvaWQge1xuICBjb25zdCB0Q2xlYW51cCA9IHRWaWV3LmNsZWFudXA7XG4gIGNvbnN0IGxDbGVhbnVwID0gbFZpZXdbQ0xFQU5VUF0hO1xuICBpZiAodENsZWFudXAgIT09IG51bGwpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRDbGVhbnVwLmxlbmd0aCAtIDE7IGkgKz0gMikge1xuICAgICAgaWYgKHR5cGVvZiB0Q2xlYW51cFtpXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIG5hdGl2ZSBET00gbGlzdGVuZXIuIEl0IHdpbGwgb2NjdXB5IDQgZW50cmllcyBpbiB0aGUgVENsZWFudXAgYXJyYXkgKGhlbmNlIGkgKz1cbiAgICAgICAgLy8gMiBhdCB0aGUgZW5kIG9mIHRoaXMgYmxvY2spLlxuICAgICAgICBjb25zdCB0YXJnZXRJZHggPSB0Q2xlYW51cFtpICsgM107XG4gICAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnROdW1iZXIodGFyZ2V0SWR4LCAnY2xlYW51cCB0YXJnZXQgbXVzdCBiZSBhIG51bWJlcicpO1xuICAgICAgICBpZiAodGFyZ2V0SWR4ID49IDApIHtcbiAgICAgICAgICAvLyB1bnJlZ2lzdGVyXG4gICAgICAgICAgbENsZWFudXBbdGFyZ2V0SWR4XSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFN1YnNjcmlwdGlvblxuICAgICAgICAgIGxDbGVhbnVwWy10YXJnZXRJZHhdLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaSArPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIGNsZWFudXAgZnVuY3Rpb24gdGhhdCBpcyBncm91cGVkIHdpdGggdGhlIGluZGV4IG9mIGl0cyBjb250ZXh0XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBsQ2xlYW51cFt0Q2xlYW51cFtpICsgMV1dO1xuICAgICAgICB0Q2xlYW51cFtpXS5jYWxsKGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobENsZWFudXAgIT09IG51bGwpIHtcbiAgICBsVmlld1tDTEVBTlVQXSA9IG51bGw7XG4gIH1cbiAgY29uc3QgZGVzdHJveUhvb2tzID0gbFZpZXdbT05fREVTVFJPWV9IT09LU107XG4gIGlmIChkZXN0cm95SG9va3MgIT09IG51bGwpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlc3Ryb3lIb29rcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZGVzdHJveUhvb2tzRm4gPSBkZXN0cm95SG9va3NbaV07XG4gICAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RnVuY3Rpb24oZGVzdHJveUhvb2tzRm4sICdFeHBlY3RpbmcgZGVzdHJveSBob29rIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgICBkZXN0cm95SG9va3NGbigpO1xuICAgIH1cbiAgICBsVmlld1tPTl9ERVNUUk9ZX0hPT0tTXSA9IG51bGw7XG4gIH1cbn1cblxuLyoqIENhbGxzIG9uRGVzdHJveSBob29rcyBmb3IgdGhpcyB2aWV3ICovXG5mdW5jdGlvbiBleGVjdXRlT25EZXN0cm95cyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldyk6IHZvaWQge1xuICBsZXQgZGVzdHJveUhvb2tzOiBEZXN0cm95SG9va0RhdGF8bnVsbDtcblxuICBpZiAodFZpZXcgIT0gbnVsbCAmJiAoZGVzdHJveUhvb2tzID0gdFZpZXcuZGVzdHJveUhvb2tzKSAhPSBudWxsKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXN0cm95SG9va3MubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBsVmlld1tkZXN0cm95SG9va3NbaV0gYXMgbnVtYmVyXTtcblxuICAgICAgLy8gT25seSBjYWxsIHRoZSBkZXN0cm95IGhvb2sgaWYgdGhlIGNvbnRleHQgaGFzIGJlZW4gcmVxdWVzdGVkLlxuICAgICAgaWYgKCEoY29udGV4dCBpbnN0YW5jZW9mIE5vZGVJbmplY3RvckZhY3RvcnkpKSB7XG4gICAgICAgIGNvbnN0IHRvQ2FsbCA9IGRlc3Ryb3lIb29rc1tpICsgMV0gYXMgSG9va0ZuIHwgSG9va0RhdGE7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodG9DYWxsKSkge1xuICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdG9DYWxsLmxlbmd0aDsgaiArPSAyKSB7XG4gICAgICAgICAgICBjb25zdCBjYWxsQ29udGV4dCA9IGNvbnRleHRbdG9DYWxsW2pdIGFzIG51bWJlcl07XG4gICAgICAgICAgICBjb25zdCBob29rID0gdG9DYWxsW2ogKyAxXSBhcyBIb29rRm47XG4gICAgICAgICAgICBwcm9maWxlcihQcm9maWxlckV2ZW50LkxpZmVjeWNsZUhvb2tTdGFydCwgY2FsbENvbnRleHQsIGhvb2spO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaG9vay5jYWxsKGNhbGxDb250ZXh0KTtcbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgIHByb2ZpbGVyKFByb2ZpbGVyRXZlbnQuTGlmZWN5Y2xlSG9va0VuZCwgY2FsbENvbnRleHQsIGhvb2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9maWxlcihQcm9maWxlckV2ZW50LkxpZmVjeWNsZUhvb2tTdGFydCwgY29udGV4dCwgdG9DYWxsKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdG9DYWxsLmNhbGwoY29udGV4dCk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHByb2ZpbGVyKFByb2ZpbGVyRXZlbnQuTGlmZWN5Y2xlSG9va0VuZCwgY29udGV4dCwgdG9DYWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmF0aXZlIGVsZW1lbnQgaWYgYSBub2RlIGNhbiBiZSBpbnNlcnRlZCBpbnRvIHRoZSBnaXZlbiBwYXJlbnQuXG4gKlxuICogVGhlcmUgYXJlIHR3byByZWFzb25zIHdoeSB3ZSBtYXkgbm90IGJlIGFibGUgdG8gaW5zZXJ0IGEgZWxlbWVudCBpbW1lZGlhdGVseS5cbiAqIC0gUHJvamVjdGlvbjogV2hlbiBjcmVhdGluZyBhIGNoaWxkIGNvbnRlbnQgZWxlbWVudCBvZiBhIGNvbXBvbmVudCwgd2UgaGF2ZSB0byBza2lwIHRoZVxuICogICBpbnNlcnRpb24gYmVjYXVzZSB0aGUgY29udGVudCBvZiBhIGNvbXBvbmVudCB3aWxsIGJlIHByb2plY3RlZC5cbiAqICAgYDxjb21wb25lbnQ+PGNvbnRlbnQ+ZGVsYXllZCBkdWUgdG8gcHJvamVjdGlvbjwvY29udGVudD48L2NvbXBvbmVudD5gXG4gKiAtIFBhcmVudCBjb250YWluZXIgaXMgZGlzY29ubmVjdGVkOiBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSBhcmUgaW5zZXJ0aW5nIGEgdmlldyBpbnRvXG4gKiAgIHBhcmVudCBjb250YWluZXIsIHdoaWNoIGl0c2VsZiBpcyBkaXNjb25uZWN0ZWQuIEZvciBleGFtcGxlIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIHBhcnRcbiAqICAgb2YgYSBWaWV3IHdoaWNoIGhhcyBub3QgYmUgaW5zZXJ0ZWQgb3IgaXMgbWFkZSBmb3IgcHJvamVjdGlvbiBidXQgaGFzIG5vdCBiZWVuIGluc2VydGVkXG4gKiAgIGludG8gZGVzdGluYXRpb24uXG4gKlxuICogQHBhcmFtIHRWaWV3OiBDdXJyZW50IGBUVmlld2AuXG4gKiBAcGFyYW0gdE5vZGU6IGBUTm9kZWAgZm9yIHdoaWNoIHdlIHdpc2ggdG8gcmV0cmlldmUgcmVuZGVyIHBhcmVudC5cbiAqIEBwYXJhbSBsVmlldzogQ3VycmVudCBgTFZpZXdgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFyZW50UkVsZW1lbnQodFZpZXc6IFRWaWV3LCB0Tm9kZTogVE5vZGUsIGxWaWV3OiBMVmlldyk6IFJFbGVtZW50fG51bGwge1xuICByZXR1cm4gZ2V0Q2xvc2VzdFJFbGVtZW50KHRWaWV3LCB0Tm9kZS5wYXJlbnQsIGxWaWV3KTtcbn1cblxuLyoqXG4gKiBHZXQgY2xvc2VzdCBgUkVsZW1lbnRgIG9yIGBudWxsYCBpZiBpdCBjYW4ndCBiZSBmb3VuZC5cbiAqXG4gKiBJZiBgVE5vZGVgIGlzIGBUTm9kZVR5cGUuRWxlbWVudGAgPT4gcmV0dXJuIGBSRWxlbWVudGAgYXQgYExWaWV3W3ROb2RlLmluZGV4XWAgbG9jYXRpb24uXG4gKiBJZiBgVE5vZGVgIGlzIGBUTm9kZVR5cGUuRWxlbWVudENvbnRhaW5lcnxJY3VDb250YWluYCA9PiByZXR1cm4gdGhlIHBhcmVudCAocmVjdXJzaXZlbHkpLlxuICogSWYgYFROb2RlYCBpcyBgbnVsbGAgdGhlbiByZXR1cm4gaG9zdCBgUkVsZW1lbnRgOlxuICogICAtIHJldHVybiBgbnVsbGAgaWYgcHJvamVjdGlvblxuICogICAtIHJldHVybiBgbnVsbGAgaWYgcGFyZW50IGNvbnRhaW5lciBpcyBkaXNjb25uZWN0ZWQgKHdlIGhhdmUgbm8gcGFyZW50LilcbiAqXG4gKiBAcGFyYW0gdFZpZXc6IEN1cnJlbnQgYFRWaWV3YC5cbiAqIEBwYXJhbSB0Tm9kZTogYFROb2RlYCBmb3Igd2hpY2ggd2Ugd2lzaCB0byByZXRyaWV2ZSBgUkVsZW1lbnRgIChvciBgbnVsbGAgaWYgaG9zdCBlbGVtZW50IGlzXG4gKiAgICAgbmVlZGVkKS5cbiAqIEBwYXJhbSBsVmlldzogQ3VycmVudCBgTFZpZXdgLlxuICogQHJldHVybnMgYG51bGxgIGlmIHRoZSBgUkVsZW1lbnRgIGNhbid0IGJlIGRldGVybWluZWQgYXQgdGhpcyB0aW1lIChubyBwYXJlbnQgLyBwcm9qZWN0aW9uKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xvc2VzdFJFbGVtZW50KHRWaWV3OiBUVmlldywgdE5vZGU6IFROb2RlfG51bGwsIGxWaWV3OiBMVmlldyk6IFJFbGVtZW50fG51bGwge1xuICBsZXQgcGFyZW50VE5vZGU6IFROb2RlfG51bGwgPSB0Tm9kZTtcbiAgLy8gU2tpcCBvdmVyIGVsZW1lbnQgYW5kIElDVSBjb250YWluZXJzIGFzIHRob3NlIGFyZSByZXByZXNlbnRlZCBieSBhIGNvbW1lbnQgbm9kZSBhbmRcbiAgLy8gY2FuJ3QgYmUgdXNlZCBhcyBhIHJlbmRlciBwYXJlbnQuXG4gIHdoaWxlIChwYXJlbnRUTm9kZSAhPT0gbnVsbCAmJlxuICAgICAgICAgKHBhcmVudFROb2RlLnR5cGUgJiAoVE5vZGVUeXBlLkVsZW1lbnRDb250YWluZXIgfCBUTm9kZVR5cGUuSWN1KSkpIHtcbiAgICB0Tm9kZSA9IHBhcmVudFROb2RlO1xuICAgIHBhcmVudFROb2RlID0gdE5vZGUucGFyZW50O1xuICB9XG5cbiAgLy8gSWYgdGhlIHBhcmVudCB0Tm9kZSBpcyBudWxsLCB0aGVuIHdlIGFyZSBpbnNlcnRpbmcgYWNyb3NzIHZpZXdzOiBlaXRoZXIgaW50byBhbiBlbWJlZGRlZCB2aWV3XG4gIC8vIG9yIGEgY29tcG9uZW50IHZpZXcuXG4gIGlmIChwYXJlbnRUTm9kZSA9PT0gbnVsbCkge1xuICAgIC8vIFdlIGFyZSBpbnNlcnRpbmcgYSByb290IGVsZW1lbnQgb2YgdGhlIGNvbXBvbmVudCB2aWV3IGludG8gdGhlIGNvbXBvbmVudCBob3N0IGVsZW1lbnQgYW5kXG4gICAgLy8gaXQgc2hvdWxkIGFsd2F5cyBiZSBlYWdlci5cbiAgICByZXR1cm4gbFZpZXdbSE9TVF07XG4gIH0gZWxzZSB7XG4gICAgbmdEZXZNb2RlICYmIGFzc2VydFROb2RlVHlwZShwYXJlbnRUTm9kZSwgVE5vZGVUeXBlLkFueVJOb2RlIHwgVE5vZGVUeXBlLkNvbnRhaW5lcik7XG4gICAgY29uc3Qge2NvbXBvbmVudE9mZnNldH0gPSBwYXJlbnRUTm9kZTtcbiAgICBpZiAoY29tcG9uZW50T2Zmc2V0ID4gLTEpIHtcbiAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnRUTm9kZUZvckxWaWV3KHBhcmVudFROb2RlLCBsVmlldyk7XG4gICAgICBjb25zdCB7ZW5jYXBzdWxhdGlvbn0gPVxuICAgICAgICAgICh0Vmlldy5kYXRhW3BhcmVudFROb2RlLmRpcmVjdGl2ZVN0YXJ0ICsgY29tcG9uZW50T2Zmc2V0XSBhcyBDb21wb25lbnREZWY8dW5rbm93bj4pO1xuICAgICAgLy8gV2UndmUgZ290IGEgcGFyZW50IHdoaWNoIGlzIGFuIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgdmlldy4gV2UganVzdCBuZWVkIHRvIHZlcmlmeSBpZiB0aGVcbiAgICAgIC8vIHBhcmVudCBlbGVtZW50IGlzIG5vdCBhIGNvbXBvbmVudC4gQ29tcG9uZW50J3MgY29udGVudCBub2RlcyBhcmUgbm90IGluc2VydGVkIGltbWVkaWF0ZWx5XG4gICAgICAvLyBiZWNhdXNlIHRoZXkgd2lsbCBiZSBwcm9qZWN0ZWQsIGFuZCBzbyBkb2luZyBpbnNlcnQgYXQgdGhpcyBwb2ludCB3b3VsZCBiZSB3YXN0ZWZ1bC5cbiAgICAgIC8vIFNpbmNlIHRoZSBwcm9qZWN0aW9uIHdvdWxkIHRoZW4gbW92ZSBpdCB0byBpdHMgZmluYWwgZGVzdGluYXRpb24uIE5vdGUgdGhhdCB3ZSBjYW4ndFxuICAgICAgLy8gbWFrZSB0aGlzIGFzc3VtcHRpb24gd2hlbiB1c2luZyB0aGUgU2hhZG93IERPTSwgYmVjYXVzZSB0aGUgbmF0aXZlIHByb2plY3Rpb24gcGxhY2Vob2xkZXJzXG4gICAgICAvLyAoPGNvbnRlbnQ+IG9yIDxzbG90PikgaGF2ZSB0byBiZSBpbiBwbGFjZSBhcyBlbGVtZW50cyBhcmUgYmVpbmcgaW5zZXJ0ZWQuXG4gICAgICBpZiAoZW5jYXBzdWxhdGlvbiA9PT0gVmlld0VuY2Fwc3VsYXRpb24uTm9uZSB8fFxuICAgICAgICAgIGVuY2Fwc3VsYXRpb24gPT09IFZpZXdFbmNhcHN1bGF0aW9uLkVtdWxhdGVkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBnZXROYXRpdmVCeVROb2RlKHBhcmVudFROb2RlLCBsVmlldykgYXMgUkVsZW1lbnQ7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnNlcnRzIGEgbmF0aXZlIG5vZGUgYmVmb3JlIGFub3RoZXIgbmF0aXZlIG5vZGUgZm9yIGEgZ2l2ZW4gcGFyZW50LlxuICogVGhpcyBpcyBhIHV0aWxpdHkgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB3aGVuIG5hdGl2ZSBub2RlcyB3ZXJlIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuYXRpdmVJbnNlcnRCZWZvcmUoXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyLCBwYXJlbnQ6IFJFbGVtZW50LCBjaGlsZDogUk5vZGUsIGJlZm9yZU5vZGU6IFJOb2RlfG51bGwsXG4gICAgaXNNb3ZlOiBib29sZWFuKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJJbnNlcnRCZWZvcmUrKztcbiAgcmVuZGVyZXIuaW5zZXJ0QmVmb3JlKHBhcmVudCwgY2hpbGQsIGJlZm9yZU5vZGUsIGlzTW92ZSk7XG59XG5cbmZ1bmN0aW9uIG5hdGl2ZUFwcGVuZENoaWxkKHJlbmRlcmVyOiBSZW5kZXJlciwgcGFyZW50OiBSRWxlbWVudCwgY2hpbGQ6IFJOb2RlKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJBcHBlbmRDaGlsZCsrO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZChwYXJlbnQsICdwYXJlbnQgbm9kZSBtdXN0IGJlIGRlZmluZWQnKTtcbiAgcmVuZGVyZXIuYXBwZW5kQ2hpbGQocGFyZW50LCBjaGlsZCk7XG59XG5cbmZ1bmN0aW9uIG5hdGl2ZUFwcGVuZE9ySW5zZXJ0QmVmb3JlKFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlciwgcGFyZW50OiBSRWxlbWVudCwgY2hpbGQ6IFJOb2RlLCBiZWZvcmVOb2RlOiBSTm9kZXxudWxsLCBpc01vdmU6IGJvb2xlYW4pIHtcbiAgaWYgKGJlZm9yZU5vZGUgIT09IG51bGwpIHtcbiAgICBuYXRpdmVJbnNlcnRCZWZvcmUocmVuZGVyZXIsIHBhcmVudCwgY2hpbGQsIGJlZm9yZU5vZGUsIGlzTW92ZSk7XG4gIH0gZWxzZSB7XG4gICAgbmF0aXZlQXBwZW5kQ2hpbGQocmVuZGVyZXIsIHBhcmVudCwgY2hpbGQpO1xuICB9XG59XG5cbi8qKiBSZW1vdmVzIGEgbm9kZSBmcm9tIHRoZSBET00gZ2l2ZW4gaXRzIG5hdGl2ZSBwYXJlbnQuICovXG5mdW5jdGlvbiBuYXRpdmVSZW1vdmVDaGlsZChcbiAgICByZW5kZXJlcjogUmVuZGVyZXIsIHBhcmVudDogUkVsZW1lbnQsIGNoaWxkOiBSTm9kZSwgaXNIb3N0RWxlbWVudD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgcmVuZGVyZXIucmVtb3ZlQ2hpbGQocGFyZW50LCBjaGlsZCwgaXNIb3N0RWxlbWVudCk7XG59XG5cbi8qKiBDaGVja3MgaWYgYW4gZWxlbWVudCBpcyBhIGA8dGVtcGxhdGU+YCBub2RlLiAqL1xuZnVuY3Rpb24gaXNUZW1wbGF0ZU5vZGUobm9kZTogUkVsZW1lbnQpOiBub2RlIGlzIFJUZW1wbGF0ZSB7XG4gIHJldHVybiBub2RlLnRhZ05hbWUgPT09ICdURU1QTEFURScgJiYgKG5vZGUgYXMgUlRlbXBsYXRlKS5jb250ZW50ICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5hdGl2ZSBwYXJlbnQgb2YgYSBnaXZlbiBuYXRpdmUgbm9kZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hdGl2ZVBhcmVudE5vZGUocmVuZGVyZXI6IFJlbmRlcmVyLCBub2RlOiBSTm9kZSk6IFJFbGVtZW50fG51bGwge1xuICByZXR1cm4gcmVuZGVyZXIucGFyZW50Tm9kZShub2RlKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmF0aXZlIHNpYmxpbmcgb2YgYSBnaXZlbiBuYXRpdmUgbm9kZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hdGl2ZU5leHRTaWJsaW5nKHJlbmRlcmVyOiBSZW5kZXJlciwgbm9kZTogUk5vZGUpOiBSTm9kZXxudWxsIHtcbiAgcmV0dXJuIHJlbmRlcmVyLm5leHRTaWJsaW5nKG5vZGUpO1xufVxuXG4vKipcbiAqIEZpbmQgYSBub2RlIGluIGZyb250IG9mIHdoaWNoIGBjdXJyZW50VE5vZGVgIHNob3VsZCBiZSBpbnNlcnRlZC5cbiAqXG4gKiBUaGlzIG1ldGhvZCBkZXRlcm1pbmVzIHRoZSBgUk5vZGVgIGluIGZyb250IG9mIHdoaWNoIHdlIHNob3VsZCBpbnNlcnQgdGhlIGBjdXJyZW50Uk5vZGVgLiBUaGlzXG4gKiB0YWtlcyBgVE5vZGUuaW5zZXJ0QmVmb3JlSW5kZXhgIGludG8gYWNjb3VudCBpZiBpMThuIGNvZGUgaGFzIGJlZW4gaW52b2tlZC5cbiAqXG4gKiBAcGFyYW0gcGFyZW50VE5vZGUgcGFyZW50IGBUTm9kZWBcbiAqIEBwYXJhbSBjdXJyZW50VE5vZGUgY3VycmVudCBgVE5vZGVgIChUaGUgbm9kZSB3aGljaCB3ZSB3b3VsZCBsaWtlIHRvIGluc2VydCBpbnRvIHRoZSBET00pXG4gKiBAcGFyYW0gbFZpZXcgY3VycmVudCBgTFZpZXdgXG4gKi9cbmZ1bmN0aW9uIGdldEluc2VydEluRnJvbnRPZlJOb2RlKHBhcmVudFROb2RlOiBUTm9kZSwgY3VycmVudFROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3KTogUk5vZGV8XG4gICAgbnVsbCB7XG4gIHJldHVybiBfZ2V0SW5zZXJ0SW5Gcm9udE9mUk5vZGVXaXRoSTE4bihwYXJlbnRUTm9kZSwgY3VycmVudFROb2RlLCBsVmlldyk7XG59XG5cblxuLyoqXG4gKiBGaW5kIGEgbm9kZSBpbiBmcm9udCBvZiB3aGljaCBgY3VycmVudFROb2RlYCBzaG91bGQgYmUgaW5zZXJ0ZWQuIChEb2VzIG5vdCB0YWtlIGkxOG4gaW50b1xuICogYWNjb3VudClcbiAqXG4gKiBUaGlzIG1ldGhvZCBkZXRlcm1pbmVzIHRoZSBgUk5vZGVgIGluIGZyb250IG9mIHdoaWNoIHdlIHNob3VsZCBpbnNlcnQgdGhlIGBjdXJyZW50Uk5vZGVgLiBUaGlzXG4gKiBkb2VzIG5vdCB0YWtlIGBUTm9kZS5pbnNlcnRCZWZvcmVJbmRleGAgaW50byBhY2NvdW50LlxuICpcbiAqIEBwYXJhbSBwYXJlbnRUTm9kZSBwYXJlbnQgYFROb2RlYFxuICogQHBhcmFtIGN1cnJlbnRUTm9kZSBjdXJyZW50IGBUTm9kZWAgKFRoZSBub2RlIHdoaWNoIHdlIHdvdWxkIGxpa2UgdG8gaW5zZXJ0IGludG8gdGhlIERPTSlcbiAqIEBwYXJhbSBsVmlldyBjdXJyZW50IGBMVmlld2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEluc2VydEluRnJvbnRPZlJOb2RlV2l0aE5vSTE4bihcbiAgICBwYXJlbnRUTm9kZTogVE5vZGUsIGN1cnJlbnRUTm9kZTogVE5vZGUsIGxWaWV3OiBMVmlldyk6IFJOb2RlfG51bGwge1xuICBpZiAocGFyZW50VE5vZGUudHlwZSAmIChUTm9kZVR5cGUuRWxlbWVudENvbnRhaW5lciB8IFROb2RlVHlwZS5JY3UpKSB7XG4gICAgcmV0dXJuIGdldE5hdGl2ZUJ5VE5vZGUocGFyZW50VE5vZGUsIGxWaWV3KTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBUcmVlIHNoYWthYmxlIGJvdW5kYXJ5IGZvciBgZ2V0SW5zZXJ0SW5Gcm9udE9mUk5vZGVXaXRoSTE4bmAgZnVuY3Rpb24uXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIG9ubHkgYmUgc2V0IGlmIGkxOG4gY29kZSBydW5zLlxuICovXG5sZXQgX2dldEluc2VydEluRnJvbnRPZlJOb2RlV2l0aEkxOG46IChwYXJlbnRUTm9kZTogVE5vZGUsIGN1cnJlbnRUTm9kZTogVE5vZGUsIGxWaWV3OiBMVmlldykgPT5cbiAgICBSTm9kZSB8IG51bGwgPSBnZXRJbnNlcnRJbkZyb250T2ZSTm9kZVdpdGhOb0kxOG47XG5cbi8qKlxuICogVHJlZSBzaGFrYWJsZSBib3VuZGFyeSBmb3IgYHByb2Nlc3NJMThuSW5zZXJ0QmVmb3JlYCBmdW5jdGlvbi5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgb25seSBiZSBzZXQgaWYgaTE4biBjb2RlIHJ1bnMuXG4gKi9cbmxldCBfcHJvY2Vzc0kxOG5JbnNlcnRCZWZvcmU6IChcbiAgICByZW5kZXJlcjogUmVuZGVyZXIsIGNoaWxkVE5vZGU6IFROb2RlLCBsVmlldzogTFZpZXcsIGNoaWxkUk5vZGU6IFJOb2RlfFJOb2RlW10sXG4gICAgcGFyZW50UkVsZW1lbnQ6IFJFbGVtZW50fG51bGwpID0+IHZvaWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRJMThuSGFuZGxpbmcoXG4gICAgZ2V0SW5zZXJ0SW5Gcm9udE9mUk5vZGVXaXRoSTE4bjogKHBhcmVudFROb2RlOiBUTm9kZSwgY3VycmVudFROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3KSA9PlxuICAgICAgICBSTm9kZSB8IG51bGwsXG4gICAgcHJvY2Vzc0kxOG5JbnNlcnRCZWZvcmU6IChcbiAgICAgICAgcmVuZGVyZXI6IFJlbmRlcmVyLCBjaGlsZFROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3LCBjaGlsZFJOb2RlOiBSTm9kZXxSTm9kZVtdLFxuICAgICAgICBwYXJlbnRSRWxlbWVudDogUkVsZW1lbnR8bnVsbCkgPT4gdm9pZCkge1xuICBfZ2V0SW5zZXJ0SW5Gcm9udE9mUk5vZGVXaXRoSTE4biA9IGdldEluc2VydEluRnJvbnRPZlJOb2RlV2l0aEkxOG47XG4gIF9wcm9jZXNzSTE4bkluc2VydEJlZm9yZSA9IHByb2Nlc3NJMThuSW5zZXJ0QmVmb3JlO1xufVxuXG4vKipcbiAqIEFwcGVuZHMgdGhlIGBjaGlsZGAgbmF0aXZlIG5vZGUgKG9yIGEgY29sbGVjdGlvbiBvZiBub2RlcykgdG8gdGhlIGBwYXJlbnRgLlxuICpcbiAqIEBwYXJhbSB0VmlldyBUaGUgYFRWaWV3JyB0byBiZSBhcHBlbmRlZFxuICogQHBhcmFtIGxWaWV3IFRoZSBjdXJyZW50IExWaWV3XG4gKiBAcGFyYW0gY2hpbGRSTm9kZSBUaGUgbmF0aXZlIGNoaWxkIChvciBjaGlsZHJlbikgdGhhdCBzaG91bGQgYmUgYXBwZW5kZWRcbiAqIEBwYXJhbSBjaGlsZFROb2RlIFRoZSBUTm9kZSBvZiB0aGUgY2hpbGQgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kQ2hpbGQoXG4gICAgdFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcsIGNoaWxkUk5vZGU6IFJOb2RlfFJOb2RlW10sIGNoaWxkVE5vZGU6IFROb2RlKTogdm9pZCB7XG4gIGNvbnN0IHBhcmVudFJOb2RlID0gZ2V0UGFyZW50UkVsZW1lbnQodFZpZXcsIGNoaWxkVE5vZGUsIGxWaWV3KTtcbiAgY29uc3QgcmVuZGVyZXIgPSBsVmlld1tSRU5ERVJFUl07XG4gIGNvbnN0IHBhcmVudFROb2RlOiBUTm9kZSA9IGNoaWxkVE5vZGUucGFyZW50IHx8IGxWaWV3W1RfSE9TVF0hO1xuICBjb25zdCBhbmNob3JOb2RlID0gZ2V0SW5zZXJ0SW5Gcm9udE9mUk5vZGUocGFyZW50VE5vZGUsIGNoaWxkVE5vZGUsIGxWaWV3KTtcbiAgaWYgKHBhcmVudFJOb2RlICE9IG51bGwpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZFJOb2RlKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZFJOb2RlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG5hdGl2ZUFwcGVuZE9ySW5zZXJ0QmVmb3JlKHJlbmRlcmVyLCBwYXJlbnRSTm9kZSwgY2hpbGRSTm9kZVtpXSwgYW5jaG9yTm9kZSwgZmFsc2UpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBuYXRpdmVBcHBlbmRPckluc2VydEJlZm9yZShyZW5kZXJlciwgcGFyZW50Uk5vZGUsIGNoaWxkUk5vZGUsIGFuY2hvck5vZGUsIGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBfcHJvY2Vzc0kxOG5JbnNlcnRCZWZvcmUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgX3Byb2Nlc3NJMThuSW5zZXJ0QmVmb3JlKHJlbmRlcmVyLCBjaGlsZFROb2RlLCBsVmlldywgY2hpbGRSTm9kZSwgcGFyZW50Uk5vZGUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IG5hdGl2ZSBub2RlIGZvciBhIGdpdmVuIExWaWV3LCBzdGFydGluZyBmcm9tIHRoZSBwcm92aWRlZCBUTm9kZS5cbiAqXG4gKiBOYXRpdmUgbm9kZXMgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aG9zZSBhcHBlYXIgaW4gdGhlIG5hdGl2ZSB0cmVlIChET00pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3ROYXRpdmVOb2RlKGxWaWV3OiBMVmlldywgdE5vZGU6IFROb2RlfG51bGwpOiBSTm9kZXxudWxsIHtcbiAgaWYgKHROb2RlICE9PSBudWxsKSB7XG4gICAgbmdEZXZNb2RlICYmXG4gICAgICAgIGFzc2VydFROb2RlVHlwZShcbiAgICAgICAgICAgIHROb2RlLFxuICAgICAgICAgICAgVE5vZGVUeXBlLkFueVJOb2RlIHwgVE5vZGVUeXBlLkFueUNvbnRhaW5lciB8IFROb2RlVHlwZS5JY3UgfCBUTm9kZVR5cGUuUHJvamVjdGlvbik7XG5cbiAgICBjb25zdCB0Tm9kZVR5cGUgPSB0Tm9kZS50eXBlO1xuICAgIGlmICh0Tm9kZVR5cGUgJiBUTm9kZVR5cGUuQW55Uk5vZGUpIHtcbiAgICAgIHJldHVybiBnZXROYXRpdmVCeVROb2RlKHROb2RlLCBsVmlldyk7XG4gICAgfSBlbHNlIGlmICh0Tm9kZVR5cGUgJiBUTm9kZVR5cGUuQ29udGFpbmVyKSB7XG4gICAgICByZXR1cm4gZ2V0QmVmb3JlTm9kZUZvclZpZXcoLTEsIGxWaWV3W3ROb2RlLmluZGV4XSk7XG4gICAgfSBlbHNlIGlmICh0Tm9kZVR5cGUgJiBUTm9kZVR5cGUuRWxlbWVudENvbnRhaW5lcikge1xuICAgICAgY29uc3QgZWxJY3VDb250YWluZXJDaGlsZCA9IHROb2RlLmNoaWxkO1xuICAgICAgaWYgKGVsSWN1Q29udGFpbmVyQ2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGdldEZpcnN0TmF0aXZlTm9kZShsVmlldywgZWxJY3VDb250YWluZXJDaGlsZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByTm9kZU9yTENvbnRhaW5lciA9IGxWaWV3W3ROb2RlLmluZGV4XTtcbiAgICAgICAgaWYgKGlzTENvbnRhaW5lcihyTm9kZU9yTENvbnRhaW5lcikpIHtcbiAgICAgICAgICByZXR1cm4gZ2V0QmVmb3JlTm9kZUZvclZpZXcoLTEsIHJOb2RlT3JMQ29udGFpbmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdW53cmFwUk5vZGUock5vZGVPckxDb250YWluZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0Tm9kZVR5cGUgJiBUTm9kZVR5cGUuSWN1KSB7XG4gICAgICBsZXQgbmV4dFJOb2RlID0gaWN1Q29udGFpbmVySXRlcmF0ZSh0Tm9kZSBhcyBUSWN1Q29udGFpbmVyTm9kZSwgbFZpZXcpO1xuICAgICAgbGV0IHJOb2RlOiBSTm9kZXxudWxsID0gbmV4dFJOb2RlKCk7XG4gICAgICAvLyBJZiB0aGUgSUNVIGNvbnRhaW5lciBoYXMgbm8gbm9kZXMsIHRoYW4gd2UgdXNlIHRoZSBJQ1UgYW5jaG9yIGFzIHRoZSBub2RlLlxuICAgICAgcmV0dXJuIHJOb2RlIHx8IHVud3JhcFJOb2RlKGxWaWV3W3ROb2RlLmluZGV4XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByb2plY3Rpb25Ob2RlcyA9IGdldFByb2plY3Rpb25Ob2RlcyhsVmlldywgdE5vZGUpO1xuICAgICAgaWYgKHByb2plY3Rpb25Ob2RlcyAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwcm9qZWN0aW9uTm9kZXMpKSB7XG4gICAgICAgICAgcmV0dXJuIHByb2plY3Rpb25Ob2Rlc1swXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJlbnRWaWV3ID0gZ2V0TFZpZXdQYXJlbnQobFZpZXdbREVDTEFSQVRJT05fQ09NUE9ORU5UX1ZJRVddKTtcbiAgICAgICAgbmdEZXZNb2RlICYmIGFzc2VydFBhcmVudFZpZXcocGFyZW50Vmlldyk7XG4gICAgICAgIHJldHVybiBnZXRGaXJzdE5hdGl2ZU5vZGUocGFyZW50VmlldyEsIHByb2plY3Rpb25Ob2Rlcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZ2V0Rmlyc3ROYXRpdmVOb2RlKGxWaWV3LCB0Tm9kZS5uZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByb2plY3Rpb25Ob2RlcyhsVmlldzogTFZpZXcsIHROb2RlOiBUTm9kZXxudWxsKTogVE5vZGV8Uk5vZGVbXXxudWxsIHtcbiAgaWYgKHROb2RlICE9PSBudWxsKSB7XG4gICAgY29uc3QgY29tcG9uZW50VmlldyA9IGxWaWV3W0RFQ0xBUkFUSU9OX0NPTVBPTkVOVF9WSUVXXTtcbiAgICBjb25zdCBjb21wb25lbnRIb3N0ID0gY29tcG9uZW50Vmlld1tUX0hPU1RdIGFzIFRFbGVtZW50Tm9kZTtcbiAgICBjb25zdCBzbG90SWR4ID0gdE5vZGUucHJvamVjdGlvbiBhcyBudW1iZXI7XG4gICAgbmdEZXZNb2RlICYmIGFzc2VydFByb2plY3Rpb25TbG90cyhsVmlldyk7XG4gICAgcmV0dXJuIGNvbXBvbmVudEhvc3QucHJvamVjdGlvbiFbc2xvdElkeF07XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCZWZvcmVOb2RlRm9yVmlldyh2aWV3SW5kZXhJbkNvbnRhaW5lcjogbnVtYmVyLCBsQ29udGFpbmVyOiBMQ29udGFpbmVyKTogUk5vZGV8XG4gICAgbnVsbCB7XG4gIGNvbnN0IG5leHRWaWV3SW5kZXggPSBDT05UQUlORVJfSEVBREVSX09GRlNFVCArIHZpZXdJbmRleEluQ29udGFpbmVyICsgMTtcbiAgaWYgKG5leHRWaWV3SW5kZXggPCBsQ29udGFpbmVyLmxlbmd0aCkge1xuICAgIGNvbnN0IGxWaWV3ID0gbENvbnRhaW5lcltuZXh0Vmlld0luZGV4XSBhcyBMVmlldztcbiAgICBjb25zdCBmaXJzdFROb2RlT2ZWaWV3ID0gbFZpZXdbVFZJRVddLmZpcnN0Q2hpbGQ7XG4gICAgaWYgKGZpcnN0VE5vZGVPZlZpZXcgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiBnZXRGaXJzdE5hdGl2ZU5vZGUobFZpZXcsIGZpcnN0VE5vZGVPZlZpZXcpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBsQ29udGFpbmVyW05BVElWRV07XG59XG5cbi8qKlxuICogUmVtb3ZlcyBhIG5hdGl2ZSBub2RlIGl0c2VsZiB1c2luZyBhIGdpdmVuIHJlbmRlcmVyLiBUbyByZW1vdmUgdGhlIG5vZGUgd2UgYXJlIGxvb2tpbmcgdXAgaXRzXG4gKiBwYXJlbnQgZnJvbSB0aGUgbmF0aXZlIHRyZWUgYXMgbm90IGFsbCBwbGF0Zm9ybXMgLyBicm93c2VycyBzdXBwb3J0IHRoZSBlcXVpdmFsZW50IG9mXG4gKiBub2RlLnJlbW92ZSgpLlxuICpcbiAqIEBwYXJhbSByZW5kZXJlciBBIHJlbmRlcmVyIHRvIGJlIHVzZWRcbiAqIEBwYXJhbSByTm9kZSBUaGUgbmF0aXZlIG5vZGUgdGhhdCBzaG91bGQgYmUgcmVtb3ZlZFxuICogQHBhcmFtIGlzSG9zdEVsZW1lbnQgQSBmbGFnIGluZGljYXRpbmcgaWYgYSBub2RlIHRvIGJlIHJlbW92ZWQgaXMgYSBob3N0IG9mIGEgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmF0aXZlUmVtb3ZlTm9kZShyZW5kZXJlcjogUmVuZGVyZXIsIHJOb2RlOiBSTm9kZSwgaXNIb3N0RWxlbWVudD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlclJlbW92ZU5vZGUrKztcbiAgY29uc3QgbmF0aXZlUGFyZW50ID0gbmF0aXZlUGFyZW50Tm9kZShyZW5kZXJlciwgck5vZGUpO1xuICBpZiAobmF0aXZlUGFyZW50KSB7XG4gICAgbmF0aXZlUmVtb3ZlQ2hpbGQocmVuZGVyZXIsIG5hdGl2ZVBhcmVudCwgck5vZGUsIGlzSG9zdEVsZW1lbnQpO1xuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgY29udGVudHMgb2YgYSBnaXZlbiBSRWxlbWVudCB1c2luZyBhIGdpdmVuIHJlbmRlcmVyLlxuICpcbiAqIEBwYXJhbSByZW5kZXJlciBBIHJlbmRlcmVyIHRvIGJlIHVzZWRcbiAqIEBwYXJhbSByRWxlbWVudCB0aGUgbmF0aXZlIFJFbGVtZW50IHRvIGJlIGNsZWFyZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyRWxlbWVudENvbnRlbnRzKHJlbmRlcmVyOiBSZW5kZXJlciwgckVsZW1lbnQ6IFJFbGVtZW50KTogdm9pZCB7XG4gIHdoaWxlIChyRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgbmF0aXZlUmVtb3ZlQ2hpbGQocmVuZGVyZXIsIHJFbGVtZW50LCByRWxlbWVudC5maXJzdENoaWxkLCBmYWxzZSk7XG4gIH1cbn1cblxuXG4vKipcbiAqIFBlcmZvcm1zIHRoZSBvcGVyYXRpb24gb2YgYGFjdGlvbmAgb24gdGhlIG5vZGUuIFR5cGljYWxseSB0aGlzIGludm9sdmVzIGluc2VydGluZyBvciByZW1vdmluZ1xuICogbm9kZXMgb24gdGhlIExWaWV3IG9yIHByb2plY3Rpb24gYm91bmRhcnkuXG4gKi9cbmZ1bmN0aW9uIGFwcGx5Tm9kZXMoXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyLCBhY3Rpb246IFdhbGtUTm9kZVRyZWVBY3Rpb24sIHROb2RlOiBUTm9kZXxudWxsLCBsVmlldzogTFZpZXcsXG4gICAgcGFyZW50UkVsZW1lbnQ6IFJFbGVtZW50fG51bGwsIGJlZm9yZU5vZGU6IFJOb2RlfG51bGwsIGlzUHJvamVjdGlvbjogYm9vbGVhbikge1xuICB3aGlsZSAodE5vZGUgIT0gbnVsbCkge1xuICAgIG5nRGV2TW9kZSAmJiBhc3NlcnRUTm9kZUZvckxWaWV3KHROb2RlLCBsVmlldyk7XG4gICAgbmdEZXZNb2RlICYmXG4gICAgICAgIGFzc2VydFROb2RlVHlwZShcbiAgICAgICAgICAgIHROb2RlLFxuICAgICAgICAgICAgVE5vZGVUeXBlLkFueVJOb2RlIHwgVE5vZGVUeXBlLkFueUNvbnRhaW5lciB8IFROb2RlVHlwZS5Qcm9qZWN0aW9uIHwgVE5vZGVUeXBlLkljdSk7XG4gICAgY29uc3QgcmF3U2xvdFZhbHVlID0gbFZpZXdbdE5vZGUuaW5kZXhdO1xuICAgIGNvbnN0IHROb2RlVHlwZSA9IHROb2RlLnR5cGU7XG4gICAgaWYgKGlzUHJvamVjdGlvbikge1xuICAgICAgaWYgKGFjdGlvbiA9PT0gV2Fsa1ROb2RlVHJlZUFjdGlvbi5DcmVhdGUpIHtcbiAgICAgICAgcmF3U2xvdFZhbHVlICYmIGF0dGFjaFBhdGNoRGF0YSh1bndyYXBSTm9kZShyYXdTbG90VmFsdWUpLCBsVmlldyk7XG4gICAgICAgIHROb2RlLmZsYWdzIHw9IFROb2RlRmxhZ3MuaXNQcm9qZWN0ZWQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICgodE5vZGUuZmxhZ3MgJiBUTm9kZUZsYWdzLmlzRGV0YWNoZWQpICE9PSBUTm9kZUZsYWdzLmlzRGV0YWNoZWQpIHtcbiAgICAgIGlmICh0Tm9kZVR5cGUgJiBUTm9kZVR5cGUuRWxlbWVudENvbnRhaW5lcikge1xuICAgICAgICBhcHBseU5vZGVzKHJlbmRlcmVyLCBhY3Rpb24sIHROb2RlLmNoaWxkLCBsVmlldywgcGFyZW50UkVsZW1lbnQsIGJlZm9yZU5vZGUsIGZhbHNlKTtcbiAgICAgICAgYXBwbHlUb0VsZW1lbnRPckNvbnRhaW5lcihhY3Rpb24sIHJlbmRlcmVyLCBwYXJlbnRSRWxlbWVudCwgcmF3U2xvdFZhbHVlLCBiZWZvcmVOb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAodE5vZGVUeXBlICYgVE5vZGVUeXBlLkljdSkge1xuICAgICAgICBjb25zdCBuZXh0Uk5vZGUgPSBpY3VDb250YWluZXJJdGVyYXRlKHROb2RlIGFzIFRJY3VDb250YWluZXJOb2RlLCBsVmlldyk7XG4gICAgICAgIGxldCByTm9kZTogUk5vZGV8bnVsbDtcbiAgICAgICAgd2hpbGUgKHJOb2RlID0gbmV4dFJOb2RlKCkpIHtcbiAgICAgICAgICBhcHBseVRvRWxlbWVudE9yQ29udGFpbmVyKGFjdGlvbiwgcmVuZGVyZXIsIHBhcmVudFJFbGVtZW50LCByTm9kZSwgYmVmb3JlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgYXBwbHlUb0VsZW1lbnRPckNvbnRhaW5lcihhY3Rpb24sIHJlbmRlcmVyLCBwYXJlbnRSRWxlbWVudCwgcmF3U2xvdFZhbHVlLCBiZWZvcmVOb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAodE5vZGVUeXBlICYgVE5vZGVUeXBlLlByb2plY3Rpb24pIHtcbiAgICAgICAgYXBwbHlQcm9qZWN0aW9uUmVjdXJzaXZlKFxuICAgICAgICAgICAgcmVuZGVyZXIsIGFjdGlvbiwgbFZpZXcsIHROb2RlIGFzIFRQcm9qZWN0aW9uTm9kZSwgcGFyZW50UkVsZW1lbnQsIGJlZm9yZU5vZGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmdEZXZNb2RlICYmIGFzc2VydFROb2RlVHlwZSh0Tm9kZSwgVE5vZGVUeXBlLkFueVJOb2RlIHwgVE5vZGVUeXBlLkNvbnRhaW5lcik7XG4gICAgICAgIGFwcGx5VG9FbGVtZW50T3JDb250YWluZXIoYWN0aW9uLCByZW5kZXJlciwgcGFyZW50UkVsZW1lbnQsIHJhd1Nsb3RWYWx1ZSwgYmVmb3JlTm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHROb2RlID0gaXNQcm9qZWN0aW9uID8gdE5vZGUucHJvamVjdGlvbk5leHQgOiB0Tm9kZS5uZXh0O1xuICB9XG59XG5cblxuLyoqXG4gKiBgYXBwbHlWaWV3YCBwZXJmb3JtcyBvcGVyYXRpb24gb24gdGhlIHZpZXcgYXMgc3BlY2lmaWVkIGluIGBhY3Rpb25gIChpbnNlcnQsIGRldGFjaCwgZGVzdHJveSlcbiAqXG4gKiBJbnNlcnRpbmcgYSB2aWV3IHdpdGhvdXQgcHJvamVjdGlvbiBvciBjb250YWluZXJzIGF0IHRvcCBsZXZlbCBpcyBzaW1wbGUuIEp1c3QgaXRlcmF0ZSBvdmVyIHRoZVxuICogcm9vdCBub2RlcyBvZiB0aGUgVmlldywgYW5kIGZvciBlYWNoIG5vZGUgcGVyZm9ybSB0aGUgYGFjdGlvbmAuXG4gKlxuICogVGhpbmdzIGdldCBtb3JlIGNvbXBsaWNhdGVkIHdpdGggY29udGFpbmVycyBhbmQgcHJvamVjdGlvbnMuIFRoYXQgaXMgYmVjYXVzZSBjb21pbmcgYWNyb3NzOlxuICogLSBDb250YWluZXI6IGltcGxpZXMgdGhhdCB3ZSBoYXZlIHRvIGluc2VydC9yZW1vdmUvZGVzdHJveSB0aGUgdmlld3Mgb2YgdGhhdCBjb250YWluZXIgYXMgd2VsbFxuICogICAgICAgICAgICAgIHdoaWNoIGluIHR1cm4gY2FuIGhhdmUgdGhlaXIgb3duIENvbnRhaW5lcnMgYXQgdGhlIFZpZXcgcm9vdHMuXG4gKiAtIFByb2plY3Rpb246IGltcGxpZXMgdGhhdCB3ZSBoYXZlIHRvIGluc2VydC9yZW1vdmUvZGVzdHJveSB0aGUgbm9kZXMgb2YgdGhlIHByb2plY3Rpb24uIFRoZVxuICogICAgICAgICAgICAgICBjb21wbGljYXRpb24gaXMgdGhhdCB0aGUgbm9kZXMgd2UgYXJlIHByb2plY3RpbmcgY2FuIHRoZW1zZWx2ZXMgaGF2ZSBDb250YWluZXJzXG4gKiAgICAgICAgICAgICAgIG9yIG90aGVyIFByb2plY3Rpb25zLlxuICpcbiAqIEFzIHlvdSBjYW4gc2VlIHRoaXMgaXMgYSB2ZXJ5IHJlY3Vyc2l2ZSBwcm9ibGVtLiBZZXMgcmVjdXJzaW9uIGlzIG5vdCBtb3N0IGVmZmljaWVudCBidXQgdGhlXG4gKiBjb2RlIGlzIGNvbXBsaWNhdGVkIGVub3VnaCB0aGF0IHRyeWluZyB0byBpbXBsZW1lbnRlZCB3aXRoIHJlY3Vyc2lvbiBiZWNvbWVzIHVubWFpbnRhaW5hYmxlLlxuICpcbiAqIEBwYXJhbSB0VmlldyBUaGUgYFRWaWV3JyB3aGljaCBuZWVkcyB0byBiZSBpbnNlcnRlZCwgZGV0YWNoZWQsIGRlc3Ryb3llZFxuICogQHBhcmFtIGxWaWV3IFRoZSBMVmlldyB3aGljaCBuZWVkcyB0byBiZSBpbnNlcnRlZCwgZGV0YWNoZWQsIGRlc3Ryb3llZC5cbiAqIEBwYXJhbSByZW5kZXJlciBSZW5kZXJlciB0byB1c2VcbiAqIEBwYXJhbSBhY3Rpb24gYWN0aW9uIHRvIHBlcmZvcm0gKGluc2VydCwgZGV0YWNoLCBkZXN0cm95KVxuICogQHBhcmFtIHBhcmVudFJFbGVtZW50IHBhcmVudCBET00gZWxlbWVudCBmb3IgaW5zZXJ0aW9uIChSZW1vdmFsIGRvZXMgbm90IG5lZWQgaXQpLlxuICogQHBhcmFtIGJlZm9yZU5vZGUgQmVmb3JlIHdoaWNoIG5vZGUgdGhlIGluc2VydGlvbnMgc2hvdWxkIGhhcHBlbi5cbiAqL1xuZnVuY3Rpb24gYXBwbHlWaWV3KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCByZW5kZXJlcjogUmVuZGVyZXIsIGFjdGlvbjogV2Fsa1ROb2RlVHJlZUFjdGlvbi5EZXN0cm95LFxuICAgIHBhcmVudFJFbGVtZW50OiBudWxsLCBiZWZvcmVOb2RlOiBudWxsKTogdm9pZDtcbmZ1bmN0aW9uIGFwcGx5VmlldyhcbiAgICB0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgcmVuZGVyZXI6IFJlbmRlcmVyLCBhY3Rpb246IFdhbGtUTm9kZVRyZWVBY3Rpb24sXG4gICAgcGFyZW50UkVsZW1lbnQ6IFJFbGVtZW50fG51bGwsIGJlZm9yZU5vZGU6IFJOb2RlfG51bGwpOiB2b2lkO1xuZnVuY3Rpb24gYXBwbHlWaWV3KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCByZW5kZXJlcjogUmVuZGVyZXIsIGFjdGlvbjogV2Fsa1ROb2RlVHJlZUFjdGlvbixcbiAgICBwYXJlbnRSRWxlbWVudDogUkVsZW1lbnR8bnVsbCwgYmVmb3JlTm9kZTogUk5vZGV8bnVsbCk6IHZvaWQge1xuICBhcHBseU5vZGVzKHJlbmRlcmVyLCBhY3Rpb24sIHRWaWV3LmZpcnN0Q2hpbGQsIGxWaWV3LCBwYXJlbnRSRWxlbWVudCwgYmVmb3JlTm9kZSwgZmFsc2UpO1xufVxuXG4vKipcbiAqIGBhcHBseVByb2plY3Rpb25gIHBlcmZvcm1zIG9wZXJhdGlvbiBvbiB0aGUgcHJvamVjdGlvbi5cbiAqXG4gKiBJbnNlcnRpbmcgYSBwcm9qZWN0aW9uIHJlcXVpcmVzIHVzIHRvIGxvY2F0ZSB0aGUgcHJvamVjdGVkIG5vZGVzIGZyb20gdGhlIHBhcmVudCBjb21wb25lbnQuIFRoZVxuICogY29tcGxpY2F0aW9uIGlzIHRoYXQgdGhvc2Ugbm9kZXMgdGhlbXNlbHZlcyBjb3VsZCBiZSByZS1wcm9qZWN0ZWQgZnJvbSB0aGVpciBwYXJlbnQgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB0VmlldyBUaGUgYFRWaWV3YCBvZiBgTFZpZXdgIHdoaWNoIG5lZWRzIHRvIGJlIGluc2VydGVkLCBkZXRhY2hlZCwgZGVzdHJveWVkXG4gKiBAcGFyYW0gbFZpZXcgVGhlIGBMVmlld2Agd2hpY2ggbmVlZHMgdG8gYmUgaW5zZXJ0ZWQsIGRldGFjaGVkLCBkZXN0cm95ZWQuXG4gKiBAcGFyYW0gdFByb2plY3Rpb25Ob2RlIG5vZGUgdG8gcHJvamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQcm9qZWN0aW9uKHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCB0UHJvamVjdGlvbk5vZGU6IFRQcm9qZWN0aW9uTm9kZSkge1xuICBjb25zdCByZW5kZXJlciA9IGxWaWV3W1JFTkRFUkVSXTtcbiAgY29uc3QgcGFyZW50Uk5vZGUgPSBnZXRQYXJlbnRSRWxlbWVudCh0VmlldywgdFByb2plY3Rpb25Ob2RlLCBsVmlldyk7XG4gIGNvbnN0IHBhcmVudFROb2RlID0gdFByb2plY3Rpb25Ob2RlLnBhcmVudCB8fCBsVmlld1tUX0hPU1RdITtcbiAgbGV0IGJlZm9yZU5vZGUgPSBnZXRJbnNlcnRJbkZyb250T2ZSTm9kZShwYXJlbnRUTm9kZSwgdFByb2plY3Rpb25Ob2RlLCBsVmlldyk7XG4gIGFwcGx5UHJvamVjdGlvblJlY3Vyc2l2ZShcbiAgICAgIHJlbmRlcmVyLCBXYWxrVE5vZGVUcmVlQWN0aW9uLkNyZWF0ZSwgbFZpZXcsIHRQcm9qZWN0aW9uTm9kZSwgcGFyZW50Uk5vZGUsIGJlZm9yZU5vZGUpO1xufVxuXG4vKipcbiAqIGBhcHBseVByb2plY3Rpb25SZWN1cnNpdmVgIHBlcmZvcm1zIG9wZXJhdGlvbiBvbiB0aGUgcHJvamVjdGlvbiBzcGVjaWZpZWQgYnkgYGFjdGlvbmAgKGluc2VydCxcbiAqIGRldGFjaCwgZGVzdHJveSlcbiAqXG4gKiBJbnNlcnRpbmcgYSBwcm9qZWN0aW9uIHJlcXVpcmVzIHVzIHRvIGxvY2F0ZSB0aGUgcHJvamVjdGVkIG5vZGVzIGZyb20gdGhlIHBhcmVudCBjb21wb25lbnQuIFRoZVxuICogY29tcGxpY2F0aW9uIGlzIHRoYXQgdGhvc2Ugbm9kZXMgdGhlbXNlbHZlcyBjb3VsZCBiZSByZS1wcm9qZWN0ZWQgZnJvbSB0aGVpciBwYXJlbnQgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSByZW5kZXJlciBSZW5kZXIgdG8gdXNlXG4gKiBAcGFyYW0gYWN0aW9uIGFjdGlvbiB0byBwZXJmb3JtIChpbnNlcnQsIGRldGFjaCwgZGVzdHJveSlcbiAqIEBwYXJhbSBsVmlldyBUaGUgTFZpZXcgd2hpY2ggbmVlZHMgdG8gYmUgaW5zZXJ0ZWQsIGRldGFjaGVkLCBkZXN0cm95ZWQuXG4gKiBAcGFyYW0gdFByb2plY3Rpb25Ob2RlIG5vZGUgdG8gcHJvamVjdFxuICogQHBhcmFtIHBhcmVudFJFbGVtZW50IHBhcmVudCBET00gZWxlbWVudCBmb3IgaW5zZXJ0aW9uL3JlbW92YWwuXG4gKiBAcGFyYW0gYmVmb3JlTm9kZSBCZWZvcmUgd2hpY2ggbm9kZSB0aGUgaW5zZXJ0aW9ucyBzaG91bGQgaGFwcGVuLlxuICovXG5mdW5jdGlvbiBhcHBseVByb2plY3Rpb25SZWN1cnNpdmUoXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyLCBhY3Rpb246IFdhbGtUTm9kZVRyZWVBY3Rpb24sIGxWaWV3OiBMVmlldywgdFByb2plY3Rpb25Ob2RlOiBUUHJvamVjdGlvbk5vZGUsXG4gICAgcGFyZW50UkVsZW1lbnQ6IFJFbGVtZW50fG51bGwsIGJlZm9yZU5vZGU6IFJOb2RlfG51bGwpIHtcbiAgY29uc3QgY29tcG9uZW50TFZpZXcgPSBsVmlld1tERUNMQVJBVElPTl9DT01QT05FTlRfVklFV107XG4gIGNvbnN0IGNvbXBvbmVudE5vZGUgPSBjb21wb25lbnRMVmlld1tUX0hPU1RdIGFzIFRFbGVtZW50Tm9kZTtcbiAgbmdEZXZNb2RlICYmXG4gICAgICBhc3NlcnRFcXVhbCh0eXBlb2YgdFByb2plY3Rpb25Ob2RlLnByb2plY3Rpb24sICdudW1iZXInLCAnZXhwZWN0aW5nIHByb2plY3Rpb24gaW5kZXgnKTtcbiAgY29uc3Qgbm9kZVRvUHJvamVjdE9yUk5vZGVzID0gY29tcG9uZW50Tm9kZS5wcm9qZWN0aW9uIVt0UHJvamVjdGlvbk5vZGUucHJvamVjdGlvbl0hO1xuICBpZiAoQXJyYXkuaXNBcnJheShub2RlVG9Qcm9qZWN0T3JSTm9kZXMpKSB7XG4gICAgLy8gVGhpcyBzaG91bGQgbm90IGV4aXN0LCBpdCBpcyBhIGJpdCBvZiBhIGhhY2suIFdoZW4gd2UgYm9vdHN0cmFwIGEgdG9wIGxldmVsIG5vZGUgYW5kIHdlXG4gICAgLy8gbmVlZCB0byBzdXBwb3J0IHBhc3NpbmcgcHJvamVjdGFibGUgbm9kZXMsIHNvIHdlIGNoZWF0IGFuZCBwdXQgdGhlbSBpbiB0aGUgVE5vZGVcbiAgICAvLyBvZiB0aGUgSG9zdCBUVmlldy4gKFllcyB3ZSBwdXQgaW5zdGFuY2UgaW5mbyBhdCB0aGUgVCBMZXZlbCkuIFdlIGNhbiBnZXQgYXdheSB3aXRoIGl0XG4gICAgLy8gYmVjYXVzZSB3ZSBrbm93IHRoYXQgdGhhdCBUVmlldyBpcyBub3Qgc2hhcmVkIGFuZCB0aGVyZWZvcmUgaXQgd2lsbCBub3QgYmUgYSBwcm9ibGVtLlxuICAgIC8vIFRoaXMgc2hvdWxkIGJlIHJlZmFjdG9yZWQgYW5kIGNsZWFuZWQgdXAuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlVG9Qcm9qZWN0T3JSTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJOb2RlID0gbm9kZVRvUHJvamVjdE9yUk5vZGVzW2ldO1xuICAgICAgYXBwbHlUb0VsZW1lbnRPckNvbnRhaW5lcihhY3Rpb24sIHJlbmRlcmVyLCBwYXJlbnRSRWxlbWVudCwgck5vZGUsIGJlZm9yZU5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBsZXQgbm9kZVRvUHJvamVjdDogVE5vZGV8bnVsbCA9IG5vZGVUb1Byb2plY3RPclJOb2RlcztcbiAgICBjb25zdCBwcm9qZWN0ZWRDb21wb25lbnRMVmlldyA9IGNvbXBvbmVudExWaWV3W1BBUkVOVF0gYXMgTFZpZXc7XG4gICAgYXBwbHlOb2RlcyhcbiAgICAgICAgcmVuZGVyZXIsIGFjdGlvbiwgbm9kZVRvUHJvamVjdCwgcHJvamVjdGVkQ29tcG9uZW50TFZpZXcsIHBhcmVudFJFbGVtZW50LCBiZWZvcmVOb2RlLCB0cnVlKTtcbiAgfVxufVxuXG5cbi8qKlxuICogYGFwcGx5Q29udGFpbmVyYCBwZXJmb3JtcyBhbiBvcGVyYXRpb24gb24gdGhlIGNvbnRhaW5lciBhbmQgaXRzIHZpZXdzIGFzIHNwZWNpZmllZCBieVxuICogYGFjdGlvbmAgKGluc2VydCwgZGV0YWNoLCBkZXN0cm95KVxuICpcbiAqIEluc2VydGluZyBhIENvbnRhaW5lciBpcyBjb21wbGljYXRlZCBieSB0aGUgZmFjdCB0aGF0IHRoZSBjb250YWluZXIgbWF5IGhhdmUgVmlld3Mgd2hpY2hcbiAqIHRoZW1zZWx2ZXMgaGF2ZSBjb250YWluZXJzIG9yIHByb2plY3Rpb25zLlxuICpcbiAqIEBwYXJhbSByZW5kZXJlciBSZW5kZXJlciB0byB1c2VcbiAqIEBwYXJhbSBhY3Rpb24gYWN0aW9uIHRvIHBlcmZvcm0gKGluc2VydCwgZGV0YWNoLCBkZXN0cm95KVxuICogQHBhcmFtIGxDb250YWluZXIgVGhlIExDb250YWluZXIgd2hpY2ggbmVlZHMgdG8gYmUgaW5zZXJ0ZWQsIGRldGFjaGVkLCBkZXN0cm95ZWQuXG4gKiBAcGFyYW0gcGFyZW50UkVsZW1lbnQgcGFyZW50IERPTSBlbGVtZW50IGZvciBpbnNlcnRpb24vcmVtb3ZhbC5cbiAqIEBwYXJhbSBiZWZvcmVOb2RlIEJlZm9yZSB3aGljaCBub2RlIHRoZSBpbnNlcnRpb25zIHNob3VsZCBoYXBwZW4uXG4gKi9cbmZ1bmN0aW9uIGFwcGx5Q29udGFpbmVyKFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlciwgYWN0aW9uOiBXYWxrVE5vZGVUcmVlQWN0aW9uLCBsQ29udGFpbmVyOiBMQ29udGFpbmVyLFxuICAgIHBhcmVudFJFbGVtZW50OiBSRWxlbWVudHxudWxsLCBiZWZvcmVOb2RlOiBSTm9kZXxudWxsfHVuZGVmaW5lZCkge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihsQ29udGFpbmVyKTtcbiAgY29uc3QgYW5jaG9yID0gbENvbnRhaW5lcltOQVRJVkVdOyAgLy8gTENvbnRhaW5lciBoYXMgaXRzIG93biBiZWZvcmUgbm9kZS5cbiAgY29uc3QgbmF0aXZlID0gdW53cmFwUk5vZGUobENvbnRhaW5lcik7XG4gIC8vIEFuIExDb250YWluZXIgY2FuIGJlIGNyZWF0ZWQgZHluYW1pY2FsbHkgb24gYW55IG5vZGUgYnkgaW5qZWN0aW5nIFZpZXdDb250YWluZXJSZWYuXG4gIC8vIEFza2luZyBmb3IgYSBWaWV3Q29udGFpbmVyUmVmIG9uIGFuIGVsZW1lbnQgd2lsbCByZXN1bHQgaW4gYSBjcmVhdGlvbiBvZiBhIHNlcGFyYXRlIGFuY2hvclxuICAvLyBub2RlIChjb21tZW50IGluIHRoZSBET00pIHRoYXQgd2lsbCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgTENvbnRhaW5lcidzIGhvc3Qgbm9kZS4gSW4gdGhpc1xuICAvLyBwYXJ0aWN1bGFyIGNhc2Ugd2UgbmVlZCB0byBleGVjdXRlIGFjdGlvbiBvbiAyIG5vZGVzOlxuICAvLyAtIGNvbnRhaW5lcidzIGhvc3Qgbm9kZSAodGhpcyBpcyBkb25lIGluIHRoZSBleGVjdXRlQWN0aW9uT25FbGVtZW50T3JDb250YWluZXIpXG4gIC8vIC0gY29udGFpbmVyJ3MgaG9zdCBub2RlICh0aGlzIGlzIGRvbmUgaGVyZSlcbiAgaWYgKGFuY2hvciAhPT0gbmF0aXZlKSB7XG4gICAgLy8gVGhpcyBpcyB2ZXJ5IHN0cmFuZ2UgdG8gbWUgKE1pc2tvKS4gSSB3b3VsZCBleHBlY3QgdGhhdCB0aGUgbmF0aXZlIGlzIHNhbWUgYXMgYW5jaG9yLiBJXG4gICAgLy8gZG9uJ3Qgc2VlIGEgcmVhc29uIHdoeSB0aGV5IHNob3VsZCBiZSBkaWZmZXJlbnQsIGJ1dCB0aGV5IGFyZS5cbiAgICAvL1xuICAgIC8vIElmIHRoZXkgYXJlIHdlIG5lZWQgdG8gcHJvY2VzcyB0aGUgc2Vjb25kIGFuY2hvciBhcyB3ZWxsLlxuICAgIGFwcGx5VG9FbGVtZW50T3JDb250YWluZXIoYWN0aW9uLCByZW5kZXJlciwgcGFyZW50UkVsZW1lbnQsIGFuY2hvciwgYmVmb3JlTm9kZSk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUOyBpIDwgbENvbnRhaW5lci5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxWaWV3ID0gbENvbnRhaW5lcltpXSBhcyBMVmlldztcbiAgICBhcHBseVZpZXcobFZpZXdbVFZJRVddLCBsVmlldywgcmVuZGVyZXIsIGFjdGlvbiwgcGFyZW50UkVsZW1lbnQsIGFuY2hvcik7XG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZXMgY2xhc3Mvc3R5bGUgdG8gZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gcmVuZGVyZXIgUmVuZGVyZXIgdG8gdXNlLlxuICogQHBhcmFtIGlzQ2xhc3NCYXNlZCBgdHJ1ZWAgaWYgaXQgc2hvdWxkIGJlIHdyaXR0ZW4gdG8gYGNsYXNzYCAoYGZhbHNlYCB0byB3cml0ZSB0byBgc3R5bGVgKVxuICogQHBhcmFtIHJOb2RlIFRoZSBOb2RlIHRvIHdyaXRlIHRvLlxuICogQHBhcmFtIHByb3AgUHJvcGVydHkgdG8gd3JpdGUgdG8uIFRoaXMgd291bGQgYmUgdGhlIGNsYXNzL3N0eWxlIG5hbWUuXG4gKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gd3JpdGUuIElmIGBudWxsYC9gdW5kZWZpbmVkYC9gZmFsc2VgIHRoaXMgaXMgY29uc2lkZXJlZCBhIHJlbW92ZSAoc2V0L2FkZFxuICogICAgICAgIG90aGVyd2lzZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVN0eWxpbmcoXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyLCBpc0NsYXNzQmFzZWQ6IGJvb2xlYW4sIHJOb2RlOiBSRWxlbWVudCwgcHJvcDogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gIGlmIChpc0NsYXNzQmFzZWQpIHtcbiAgICAvLyBXZSBhY3R1YWxseSB3YW50IEpTIHRydWUvZmFsc2UgaGVyZSBiZWNhdXNlIGFueSB0cnV0aHkgdmFsdWUgc2hvdWxkIGFkZCB0aGUgY2xhc3NcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyUmVtb3ZlQ2xhc3MrKztcbiAgICAgIHJlbmRlcmVyLnJlbW92ZUNsYXNzKHJOb2RlLCBwcm9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlckFkZENsYXNzKys7XG4gICAgICByZW5kZXJlci5hZGRDbGFzcyhyTm9kZSwgcHJvcCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxldCBmbGFncyA9IHByb3AuaW5kZXhPZignLScpID09PSAtMSA/IHVuZGVmaW5lZCA6IFJlbmRlcmVyU3R5bGVGbGFnczIuRGFzaENhc2UgYXMgbnVtYmVyO1xuICAgIGlmICh2YWx1ZSA9PSBudWxsIC8qKiB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkICovKSB7XG4gICAgICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyUmVtb3ZlU3R5bGUrKztcbiAgICAgIHJlbmRlcmVyLnJlbW92ZVN0eWxlKHJOb2RlLCBwcm9wLCBmbGFncyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEEgdmFsdWUgaXMgaW1wb3J0YW50IGlmIGl0IGVuZHMgd2l0aCBgIWltcG9ydGFudGAuIFRoZSBzdHlsZVxuICAgICAgLy8gcGFyc2VyIHN0cmlwcyBhbnkgc2VtaWNvbG9ucyBhdCB0aGUgZW5kIG9mIHRoZSB2YWx1ZS5cbiAgICAgIGNvbnN0IGlzSW1wb3J0YW50ID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlLmVuZHNXaXRoKCchaW1wb3J0YW50JykgOiBmYWxzZTtcblxuICAgICAgaWYgKGlzSW1wb3J0YW50KSB7XG4gICAgICAgIC8vICFpbXBvcnRhbnQgaGFzIHRvIGJlIHN0cmlwcGVkIGZyb20gdGhlIHZhbHVlIGZvciBpdCB0byBiZSB2YWxpZC5cbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLCAtMTApO1xuICAgICAgICBmbGFncyEgfD0gUmVuZGVyZXJTdHlsZUZsYWdzMi5JbXBvcnRhbnQ7XG4gICAgICB9XG5cbiAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJTZXRTdHlsZSsrO1xuICAgICAgcmVuZGVyZXIuc2V0U3R5bGUock5vZGUsIHByb3AsIHZhbHVlLCBmbGFncyk7XG4gICAgfVxuICB9XG59XG5cblxuLyoqXG4gKiBXcml0ZSBgY3NzVGV4dGAgdG8gYFJFbGVtZW50YC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGRvZXMgZGlyZWN0IHdyaXRlIHdpdGhvdXQgYW55IHJlY29uY2lsaWF0aW9uLiBVc2VkIGZvciB3cml0aW5nIGluaXRpYWwgdmFsdWVzLCBzb1xuICogdGhhdCBzdGF0aWMgc3R5bGluZyB2YWx1ZXMgZG8gbm90IHB1bGwgaW4gdGhlIHN0eWxlIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gcmVuZGVyZXIgUmVuZGVyZXIgdG8gdXNlXG4gKiBAcGFyYW0gZWxlbWVudCBUaGUgZWxlbWVudCB3aGljaCBuZWVkcyB0byBiZSB1cGRhdGVkLlxuICogQHBhcmFtIG5ld1ZhbHVlIFRoZSBuZXcgY2xhc3MgbGlzdCB0byB3cml0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlRGlyZWN0U3R5bGUocmVuZGVyZXI6IFJlbmRlcmVyLCBlbGVtZW50OiBSRWxlbWVudCwgbmV3VmFsdWU6IHN0cmluZykge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0U3RyaW5nKG5ld1ZhbHVlLCAnXFwnbmV3VmFsdWVcXCcgc2hvdWxkIGJlIGEgc3RyaW5nJyk7XG4gIHJlbmRlcmVyLnNldEF0dHJpYnV0ZShlbGVtZW50LCAnc3R5bGUnLCBuZXdWYWx1ZSk7XG4gIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJTZXRTdHlsZSsrO1xufVxuXG4vKipcbiAqIFdyaXRlIGBjbGFzc05hbWVgIHRvIGBSRWxlbWVudGAuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBkb2VzIGRpcmVjdCB3cml0ZSB3aXRob3V0IGFueSByZWNvbmNpbGlhdGlvbi4gVXNlZCBmb3Igd3JpdGluZyBpbml0aWFsIHZhbHVlcywgc29cbiAqIHRoYXQgc3RhdGljIHN0eWxpbmcgdmFsdWVzIGRvIG5vdCBwdWxsIGluIHRoZSBzdHlsZSBwYXJzZXIuXG4gKlxuICogQHBhcmFtIHJlbmRlcmVyIFJlbmRlcmVyIHRvIHVzZVxuICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAqIEBwYXJhbSBuZXdWYWx1ZSBUaGUgbmV3IGNsYXNzIGxpc3QgdG8gd3JpdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZURpcmVjdENsYXNzKHJlbmRlcmVyOiBSZW5kZXJlciwgZWxlbWVudDogUkVsZW1lbnQsIG5ld1ZhbHVlOiBzdHJpbmcpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydFN0cmluZyhuZXdWYWx1ZSwgJ1xcJ25ld1ZhbHVlXFwnIHNob3VsZCBiZSBhIHN0cmluZycpO1xuICBpZiAobmV3VmFsdWUgPT09ICcnKSB7XG4gICAgLy8gVGhlcmUgYXJlIHRlc3RzIGluIGBnb29nbGUzYCB3aGljaCBleHBlY3QgYGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdjbGFzcycpYCB0byBiZSBgbnVsbGAuXG4gICAgcmVuZGVyZXIucmVtb3ZlQXR0cmlidXRlKGVsZW1lbnQsICdjbGFzcycpO1xuICB9IGVsc2Uge1xuICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZShlbGVtZW50LCAnY2xhc3MnLCBuZXdWYWx1ZSk7XG4gIH1cbiAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlclNldENsYXNzTmFtZSsrO1xufVxuXG4vKiogU2V0cyB1cCB0aGUgc3RhdGljIERPTSBhdHRyaWJ1dGVzIG9uIGFuIGBSTm9kZWAuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBTdGF0aWNBdHRyaWJ1dGVzKHJlbmRlcmVyOiBSZW5kZXJlciwgZWxlbWVudDogUkVsZW1lbnQsIHROb2RlOiBUTm9kZSkge1xuICBjb25zdCB7bWVyZ2VkQXR0cnMsIGNsYXNzZXMsIHN0eWxlc30gPSB0Tm9kZTtcblxuICBpZiAobWVyZ2VkQXR0cnMgIT09IG51bGwpIHtcbiAgICBzZXRVcEF0dHJpYnV0ZXMocmVuZGVyZXIsIGVsZW1lbnQsIG1lcmdlZEF0dHJzKTtcbiAgfVxuXG4gIGlmIChjbGFzc2VzICE9PSBudWxsKSB7XG4gICAgd3JpdGVEaXJlY3RDbGFzcyhyZW5kZXJlciwgZWxlbWVudCwgY2xhc3Nlcyk7XG4gIH1cblxuICBpZiAoc3R5bGVzICE9PSBudWxsKSB7XG4gICAgd3JpdGVEaXJlY3RTdHlsZShyZW5kZXJlciwgZWxlbWVudCwgc3R5bGVzKTtcbiAgfVxufVxuIl19
|