From 53c14883c67d491b10ca263693ca9485605193f6 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Tue, 28 Nov 2023 17:14:37 -0500 Subject: [PATCH] feat(mesh-io): add mesh-io-emscripten bindgen output --- .../itkwasm-mesh-io-emscripten/README.md | 23 ++++++ .../itkwasm_mesh_io_emscripten/__init__.py | 26 +++++++ .../itkwasm_mesh_io_emscripten/_version.py | 1 + .../byu_read_mesh_async.py | 60 +++++++++++++++ .../byu_write_mesh_async.py | 73 +++++++++++++++++++ .../free_surfer_ascii_read_mesh_async.py | 60 +++++++++++++++ .../free_surfer_ascii_write_mesh_async.py | 73 +++++++++++++++++++ .../free_surfer_binary_read_mesh_async.py | 60 +++++++++++++++ .../free_surfer_binary_write_mesh_async.py | 73 +++++++++++++++++++ .../itkwasm_mesh_io_emscripten/js_package.py | 8 ++ .../obj_read_mesh_async.py | 60 +++++++++++++++ .../obj_write_mesh_async.py | 73 +++++++++++++++++++ .../off_read_mesh_async.py | 60 +++++++++++++++ .../off_write_mesh_async.py | 73 +++++++++++++++++++ .../stl_read_mesh_async.py | 60 +++++++++++++++ .../stl_write_mesh_async.py | 73 +++++++++++++++++++ .../swc_read_mesh_async.py | 60 +++++++++++++++ .../swc_write_mesh_async.py | 73 +++++++++++++++++++ .../vtk_poly_data_read_mesh_async.py | 60 +++++++++++++++ .../vtk_poly_data_write_mesh_async.py | 73 +++++++++++++++++++ .../wasm_read_mesh_async.py | 60 +++++++++++++++ .../wasm_write_mesh_async.py | 73 +++++++++++++++++++ .../wasm_zstd_read_mesh_async.py | 60 +++++++++++++++ .../wasm_zstd_write_mesh_async.py | 73 +++++++++++++++++++ .../wasm_ztd_read_mesh_async.py | 60 +++++++++++++++ .../wasm_ztd_write_mesh_async.py | 73 +++++++++++++++++++ .../itkwasm-mesh-io-emscripten/pyproject.toml | 73 +++++++++++++++++++ .../test/__init__.py | 0 .../test/fixtures.py | 28 +++++++ .../test/test_itkwasm_mesh_io.py | 20 +++++ .../python/itkwasm-mesh-io-wasi/.gitignore | 1 + 31 files changed, 1643 insertions(+) create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/README.md create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/__init__.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/_version.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/js_package.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_read_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_write_mesh_async.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/pyproject.toml create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/__init__.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/fixtures.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/test_itkwasm_mesh_io.py create mode 100644 packages/mesh-io/python/itkwasm-mesh-io-wasi/.gitignore diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/README.md b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/README.md new file mode 100644 index 000000000..ad8bf8aa9 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/README.md @@ -0,0 +1,23 @@ +# itkwasm-mesh-io-emscripten + +[![PyPI version](https://badge.fury.io/py/itkwasm-mesh-io-emscripten.svg)](https://badge.fury.io/py/itkwasm-mesh-io-emscripten) + +Input and output for scientific and medical image file formats. Emscripten implementation. + +This package provides the Emscripten WebAssembly implementation. It is usually not called directly. Please use the [`itkwasm-mesh-io`](https://pypi.org/project/itkwasm-mesh-io/) instead. + + +## Installation + +```sh +import micropip +await micropip.install('itkwasm-mesh-io-emscripten') +``` + +## Development + +```sh +pip install hatch +hatch run download-pyodide +hatch run test +``` diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/__init__.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/__init__.py new file mode 100644 index 000000000..ae7c1e164 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/__init__.py @@ -0,0 +1,26 @@ +# Generated file. To retain edits, remove this comment. + +"""itkwasm-mesh-io-emscripten: Input and output for scientific and medical image file formats. Emscripten implementation.""" + +from .byu_read_mesh_async import byu_read_mesh_async +from .byu_write_mesh_async import byu_write_mesh_async +from .free_surfer_ascii_read_mesh_async import free_surfer_ascii_read_mesh_async +from .free_surfer_ascii_write_mesh_async import free_surfer_ascii_write_mesh_async +from .free_surfer_binary_read_mesh_async import free_surfer_binary_read_mesh_async +from .free_surfer_binary_write_mesh_async import free_surfer_binary_write_mesh_async +from .obj_read_mesh_async import obj_read_mesh_async +from .obj_write_mesh_async import obj_write_mesh_async +from .off_read_mesh_async import off_read_mesh_async +from .off_write_mesh_async import off_write_mesh_async +from .stl_read_mesh_async import stl_read_mesh_async +from .stl_write_mesh_async import stl_write_mesh_async +from .swc_read_mesh_async import swc_read_mesh_async +from .swc_write_mesh_async import swc_write_mesh_async +from .vtk_poly_data_read_mesh_async import vtk_poly_data_read_mesh_async +from .vtk_poly_data_write_mesh_async import vtk_poly_data_write_mesh_async +from .wasm_read_mesh_async import wasm_read_mesh_async +from .wasm_write_mesh_async import wasm_write_mesh_async +from .wasm_zstd_read_mesh_async import wasm_zstd_read_mesh_async +from .wasm_zstd_write_mesh_async import wasm_zstd_write_mesh_async + +from ._version import __version__ diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/_version.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/_version.py new file mode 100644 index 000000000..3dc1f76bc --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/_version.py @@ -0,0 +1 @@ +__version__ = "0.1.0" diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_read_mesh_async.py new file mode 100644 index 000000000..27144ebad --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def byu_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.byuReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_write_mesh_async.py new file mode 100644 index 000000000..367a88bf7 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/byu_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def byu_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.byuWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_read_mesh_async.py new file mode 100644 index 000000000..ab9a6d548 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def free_surfer_ascii_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.freeSurferAsciiReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_write_mesh_async.py new file mode 100644 index 000000000..3a48b5d97 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_ascii_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def free_surfer_ascii_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.freeSurferAsciiWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_read_mesh_async.py new file mode 100644 index 000000000..01fe90707 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def free_surfer_binary_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.freeSurferBinaryReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_write_mesh_async.py new file mode 100644 index 000000000..a776ab238 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/free_surfer_binary_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def free_surfer_binary_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.freeSurferBinaryWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/js_package.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/js_package.py new file mode 100644 index 000000000..4bebadc47 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/js_package.py @@ -0,0 +1,8 @@ +# Generated file. To retain edits, remove this comment. + +from itkwasm.pyodide import JsPackageConfig, JsPackage + +from ._version import __version__ +default_js_module = """data:text/javascript;base64,dmFyIE10PU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgUHQ9KEEsZSk9Pntmb3IodmFyIHQgaW4gZSlNdChBLHQse2dldDplW3RdLGVudW1lcmFibGU6ITB9KX07dmFyIHh0PSIxLjAuMC1iLjE1NiIsZUE9eHQ7dmFyIFd0PXtwaXBlbGluZVdvcmtlclVybDpgaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9pdGstd2FzbUAke2VBfS9kaXN0L2NvcmUvd2ViLXdvcmtlcnMvYnVuZGxlcy9waXBlbGluZS5taW4ud29ya2VyLmpzYCxpbWFnZUlPVXJsOmBodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2l0ay1pbWFnZS1pb0Ake2VBfWAsbWVzaElPVXJsOmBodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2l0ay1tZXNoLWlvQCR7ZUF9YCxwaXBlbGluZXNVcmw6YGh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vaXRrLXdhc21AJHtlQX0vZGlzdC9waXBlbGluZXNgfSxxPVd0O3ZhciBHdD17VGV4dEZpbGU6IkludGVyZmFjZVRleHRGaWxlIixCaW5hcnlGaWxlOiJJbnRlcmZhY2VCaW5hcnlGaWxlIixUZXh0U3RyZWFtOiJJbnRlcmZhY2VUZXh0U3RyZWFtIixCaW5hcnlTdHJlYW06IkludGVyZmFjZUJpbmFyeVN0cmVhbSIsSW1hZ2U6IkludGVyZmFjZUltYWdlIixNZXNoOiJJbnRlcmZhY2VNZXNoIixQb2x5RGF0YToiSW50ZXJmYWNlUG9seURhdGEiLEpzb25Db21wYXRpYmxlOiJJbnRlcmZhY2VKc29uQ29tcGF0aWJsZSJ9LEI9R3Q7dmFyIFR0PXtJbnQ4OiJpbnQ4IixVSW50ODoidWludDgiLEludDE2OiJpbnQxNiIsVUludDE2OiJ1aW50MTYiLEludDMyOiJpbnQzMiIsVUludDMyOiJ1aW50MzIiLEludDY0OiJpbnQ2NCIsVUludDY0OiJ1aW50NjQiLFNpemVWYWx1ZVR5cGU6InVpbnQ2NCIsSWRlbnRpZmllclR5cGU6InVpbnQ2NCIsSW5kZXhWYWx1ZVR5cGU6ImludDY0IixPZmZzZXRWYWx1ZVR5cGU6ImludDY0In0sTz1UdDt2YXIgTHQ9e0Zsb2F0MzI6ImZsb2F0MzIiLEZsb2F0NjQ6ImZsb2F0NjQiLFNwYWNlUHJlY2lzaW9uVHlwZToiZmxvYXQ2NCJ9LEo9THQ7dmFyIEp0PXtUZXh0OiJUZXh0IixCaW5hcnk6IkJpbmFyeSIsSW1hZ2U6IkltYWdlIixNZXNoOiJNZXNoIn0sVT1KdDtmdW5jdGlvbiBIdChBLGUpe2xldCB0PW51bGw7c3dpdGNoKEEpe2Nhc2UgTy5VSW50ODp7dD1uZXcgVWludDhBcnJheShlKTticmVha31jYXNlIE8uSW50ODp7dD1uZXcgSW50OEFycmF5KGUpO2JyZWFrfWNhc2UgTy5VSW50MTY6e3Q9bmV3IFVpbnQxNkFycmF5KGUpO2JyZWFrfWNhc2UgTy5JbnQxNjp7dD1uZXcgSW50MTZBcnJheShlKTticmVha31jYXNlIE8uVUludDMyOnt0PW5ldyBVaW50MzJBcnJheShlKTticmVha31jYXNlIE8uSW50MzI6e3Q9bmV3IEludDMyQXJyYXkoZSk7YnJlYWt9Y2FzZSBPLlVJbnQ2NDp7dHlwZW9mIGdsb2JhbFRoaXMuQmlnVWludDY0QXJyYXk9PSJmdW5jdGlvbiI/dD1uZXcgQmlnVWludDY0QXJyYXkoZSk6dD1uZXcgVWludDhBcnJheShlKTticmVha31jYXNlIE8uSW50NjQ6e3R5cGVvZiBnbG9iYWxUaGlzLkJpZ0ludDY0QXJyYXk9PSJmdW5jdGlvbiI/dD1uZXcgQmlnSW50NjRBcnJheShlKTp0PW5ldyBVaW50OEFycmF5KGUpO2JyZWFrfWNhc2UgSi5GbG9hdDMyOnt0PW5ldyBGbG9hdDMyQXJyYXkoZSk7YnJlYWt9Y2FzZSBKLkZsb2F0NjQ6e3Q9bmV3IEZsb2F0NjRBcnJheShlKTticmVha31jYXNlIm51bGwiOnt0PW51bGw7YnJlYWt9Y2FzZSBudWxsOnt0PW51bGw7YnJlYWt9ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoIlR5cGUgaXMgbm90IHN1cHBvcnRlZCBhcyBhIFR5cGVkQXJyYXkiKX1yZXR1cm4gdH12YXIgRj1IdDt2YXIgWXQ9dHlwZW9mIGdsb2JhbFRoaXMuU2hhcmVkQXJyYXlCdWZmZXI8InUiO2Z1bmN0aW9uIHF0KEEpe2lmKEE9PW51bGwpcmV0dXJuW107bGV0IGU9W107Zm9yKGxldCB0PTA7dDxBLmxlbmd0aDt0Kyspe2xldCByPUt0KEFbdF0pO3IhPT1udWxsJiZlLnB1c2gocil9cmV0dXJuIGV9ZnVuY3Rpb24gS3QoQSl7aWYoQT09bnVsbClyZXR1cm4gbnVsbDtsZXQgZT1udWxsO3JldHVybiBBLmJ1ZmZlciE9PXZvaWQgMD9lPUEuYnVmZmVyOkEuYnl0ZUxlbmd0aCE9PXZvaWQgMCYmKGU9QSksWXQmJmUgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcj9udWxsOmV9dmFyIFJlPXF0O2Z1bmN0aW9uIHRBKEEsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIEEuYXBwbHkoZSxhcmd1bWVudHMpfX12YXJ7dG9TdHJpbmc6dnR9PU9iamVjdC5wcm90b3R5cGUse2dldFByb3RvdHlwZU9mOk5BfT1PYmplY3QsZkE9KEE9PmU9PntsZXQgdD12dC5jYWxsKGUpO3JldHVybiBBW3RdfHwoQVt0XT10LnNsaWNlKDgsLTEpLnRvTG93ZXJDYXNlKCkpfSkoT2JqZWN0LmNyZWF0ZShudWxsKSksUD1BPT4oQT1BLnRvTG93ZXJDYXNlKCksZT0+ZkEoZSk9PT1BKSxwQT1BPT5lPT50eXBlb2YgZT09PUEse2lzQXJyYXk6S309QXJyYXksckE9cEEoInVuZGVmaW5lZCIpO2Z1bmN0aW9uIGp0KEEpe3JldHVybiBBIT09bnVsbCYmIXJBKEEpJiZBLmNvbnN0cnVjdG9yIT09bnVsbCYmIXJBKEEuY29uc3RydWN0b3IpJiZNKEEuY29uc3RydWN0b3IuaXNCdWZmZXIpJiZBLmNvbnN0cnVjdG9yLmlzQnVmZmVyKEEpfXZhciBPZT1QKCJBcnJheUJ1ZmZlciIpO2Z1bmN0aW9uIF90KEEpe2xldCBlO3JldHVybiB0eXBlb2YgQXJyYXlCdWZmZXI8InUiJiZBcnJheUJ1ZmZlci5pc1ZpZXc/ZT1BcnJheUJ1ZmZlci5pc1ZpZXcoQSk6ZT1BJiZBLmJ1ZmZlciYmT2UoQS5idWZmZXIpLGV9dmFyIHp0PXBBKCJzdHJpbmciKSxNPXBBKCJmdW5jdGlvbiIpLFVlPXBBKCJudW1iZXIiKSxjQT1BPT5BIT09bnVsbCYmdHlwZW9mIEE9PSJvYmplY3QiLFZ0PUE9PkE9PT0hMHx8QT09PSExLHVBPUE9PntpZihmQShBKSE9PSJvYmplY3QiKXJldHVybiExO2xldCBlPU5BKEEpO3JldHVybihlPT09bnVsbHx8ZT09PU9iamVjdC5wcm90b3R5cGV8fE9iamVjdC5nZXRQcm90b3R5cGVPZihlKT09PW51bGwpJiYhKFN5bWJvbC50b1N0cmluZ1RhZyBpbiBBKSYmIShTeW1ib2wuaXRlcmF0b3IgaW4gQSl9LFp0PVAoIkRhdGUiKSxYdD1QKCJGaWxlIiksJHQ9UCgiQmxvYiIpLEFyPVAoIkZpbGVMaXN0IiksZXI9QT0+Y0EoQSkmJk0oQS5waXBlKSx0cj1BPT57bGV0IGU7cmV0dXJuIEEmJih0eXBlb2YgRm9ybURhdGE9PSJmdW5jdGlvbiImJkEgaW5zdGFuY2VvZiBGb3JtRGF0YXx8TShBLmFwcGVuZCkmJigoZT1mQShBKSk9PT0iZm9ybWRhdGEifHxlPT09Im9iamVjdCImJk0oQS50b1N0cmluZykmJkEudG9TdHJpbmcoKT09PSJbb2JqZWN0IEZvcm1EYXRhXSIpKX0scnI9UCgiVVJMU2VhcmNoUGFyYW1zIiksaXI9QT0+QS50cmltP0EudHJpbSgpOkEucmVwbGFjZSgvXltcc1x1RkVGRlx4QTBdK3xbXHNcdUZFRkZceEEwXSskL2csIiIpO2Z1bmN0aW9uIGlBKEEsZSx7YWxsT3duS2V5czp0PSExfT17fSl7aWYoQT09PW51bGx8fHR5cGVvZiBBPiJ1IilyZXR1cm47bGV0IHIsbjtpZih0eXBlb2YgQSE9Im9iamVjdCImJihBPVtBXSksSyhBKSlmb3Iocj0wLG49QS5sZW5ndGg7cjxuO3IrKyllLmNhbGwobnVsbCxBW3JdLHIsQSk7ZWxzZXtsZXQgbz10P09iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKEEpOk9iamVjdC5rZXlzKEEpLGk9by5sZW5ndGgsbDtmb3Iocj0wO3I8aTtyKyspbD1vW3JdLGUuY2FsbChudWxsLEFbbF0sbCxBKX19ZnVuY3Rpb24gTmUoQSxlKXtlPWUudG9Mb3dlckNhc2UoKTtsZXQgdD1PYmplY3Qua2V5cyhBKSxyPXQubGVuZ3RoLG47Zm9yKDtyLS0gPjA7KWlmKG49dFtyXSxlPT09bi50b0xvd2VyQ2FzZSgpKXJldHVybiBuO3JldHVybiBudWxsfXZhciBNZT10eXBlb2YgZ2xvYmFsVGhpczwidSI/Z2xvYmFsVGhpczp0eXBlb2Ygc2VsZjwidSI/c2VsZjp0eXBlb2Ygd2luZG93PCJ1Ij93aW5kb3c6Z2xvYmFsLFBlPUE9PiFyQShBKSYmQSE9PU1lO2Z1bmN0aW9uIFVBKCl7bGV0e2Nhc2VsZXNzOkF9PVBlKHRoaXMpJiZ0aGlzfHx7fSxlPXt9LHQ9KHIsbik9PntsZXQgbz1BJiZOZShlLG4pfHxuO3VBKGVbb10pJiZ1QShyKT9lW29dPVVBKGVbb10scik6dUEocik/ZVtvXT1VQSh7fSxyKTpLKHIpP2Vbb109ci5zbGljZSgpOmVbb109cn07Zm9yKGxldCByPTAsbj1hcmd1bWVudHMubGVuZ3RoO3I8bjtyKyspYXJndW1lbnRzW3JdJiZpQShhcmd1bWVudHNbcl0sdCk7cmV0dXJuIGV9dmFyIG5yPShBLGUsdCx7YWxsT3duS2V5czpyfT17fSk9PihpQShlLChuLG8pPT57dCYmTShuKT9BW29dPXRBKG4sdCk6QVtvXT1ufSx7YWxsT3duS2V5czpyfSksQSksb3I9QT0+KEEuY2hhckNvZGVBdCgwKT09PTY1Mjc5JiYoQT1BLnNsaWNlKDEpKSxBKSxhcj0oQSxlLHQscik9PntBLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKGUucHJvdG90eXBlLHIpLEEucHJvdG90eXBlLmNvbnN0cnVjdG9yPUEsT2JqZWN0LmRlZmluZVByb3BlcnR5KEEsInN1cGVyIix7dmFsdWU6ZS5wcm90b3R5cGV9KSx0JiZPYmplY3QuYXNzaWduKEEucHJvdG90eXBlLHQpfSxzcj0oQSxlLHQscik9PntsZXQgbixvLGksbD17fTtpZihlPWV8fHt9LEE9PW51bGwpcmV0dXJuIGU7ZG97Zm9yKG49T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoQSksbz1uLmxlbmd0aDtvLS0gPjA7KWk9bltvXSwoIXJ8fHIoaSxBLGUpKSYmIWxbaV0mJihlW2ldPUFbaV0sbFtpXT0hMCk7QT10IT09ITEmJk5BKEEpfXdoaWxlKEEmJighdHx8dChBLGUpKSYmQSE9PU9iamVjdC5wcm90b3R5cGUpO3JldHVybiBlfSxJcj0oQSxlLHQpPT57QT1TdHJpbmcoQSksKHQ9PT12b2lkIDB8fHQ+QS5sZW5ndGgpJiYodD1BLmxlbmd0aCksdC09ZS5sZW5ndGg7bGV0IHI9QS5pbmRleE9mKGUsdCk7cmV0dXJuIHIhPT0tMSYmcj09PXR9LGxyPUE9PntpZighQSlyZXR1cm4gbnVsbDtpZihLKEEpKXJldHVybiBBO2xldCBlPUEubGVuZ3RoO2lmKCFVZShlKSlyZXR1cm4gbnVsbDtsZXQgdD1uZXcgQXJyYXkoZSk7Zm9yKDtlLS0gPjA7KXRbZV09QVtlXTtyZXR1cm4gdH0sZ3I9KEE9PmU9PkEmJmUgaW5zdGFuY2VvZiBBKSh0eXBlb2YgVWludDhBcnJheTwidSImJk5BKFVpbnQ4QXJyYXkpKSx1cj0oQSxlKT0+e2xldCByPShBJiZBW1N5bWJvbC5pdGVyYXRvcl0pLmNhbGwoQSksbjtmb3IoOyhuPXIubmV4dCgpKSYmIW4uZG9uZTspe2xldCBvPW4udmFsdWU7ZS5jYWxsKEEsb1swXSxvWzFdKX19LGZyPShBLGUpPT57bGV0IHQscj1bXTtmb3IoOyh0PUEuZXhlYyhlKSkhPT1udWxsOylyLnB1c2godCk7cmV0dXJuIHJ9LHByPVAoIkhUTUxGb3JtRWxlbWVudCIpLGNyPUE9PkEudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9cc10oW2EtelxkXSkoXHcqKS9nLGZ1bmN0aW9uKHQscixuKXtyZXR1cm4gci50b1VwcGVyQ2FzZSgpK259KSxTZT0oKHtoYXNPd25Qcm9wZXJ0eTpBfSk9PihlLHQpPT5BLmNhbGwoZSx0KSkoT2JqZWN0LnByb3RvdHlwZSksQnI9UCgiUmVnRXhwIikseGU9KEEsZSk9PntsZXQgdD1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhBKSxyPXt9O2lBKHQsKG4sbyk9PntsZXQgaTsoaT1lKG4sbyxBKSkhPT0hMSYmKHJbb109aXx8bil9KSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyhBLHIpfSxDcj1BPT57eGUoQSwoZSx0KT0+e2lmKE0oQSkmJlsiYXJndW1lbnRzIiwiY2FsbGVyIiwiY2FsbGVlIl0uaW5kZXhPZih0KSE9PS0xKXJldHVybiExO2xldCByPUFbdF07aWYoTShyKSl7aWYoZS5lbnVtZXJhYmxlPSExLCJ3cml0YWJsZSJpbiBlKXtlLndyaXRhYmxlPSExO3JldHVybn1lLnNldHx8KGUuc2V0PSgpPT57dGhyb3cgRXJyb3IoIkNhbiBub3QgcmV3cml0ZSByZWFkLW9ubHkgbWV0aG9kICciK3QrIiciKX0pfX0pfSxtcj0oQSxlKT0+e2xldCB0PXt9LHI9bj0+e24uZm9yRWFjaChvPT57dFtvXT0hMH0pfTtyZXR1cm4gSyhBKT9yKEEpOnIoU3RyaW5nKEEpLnNwbGl0KGUpKSx0fSxkcj0oKT0+e30sRXI9KEEsZSk9PihBPStBLE51bWJlci5pc0Zpbml0ZShBKT9BOmUpLE9BPSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIsa2U9IjAxMjM0NTY3ODkiLFdlPXtESUdJVDprZSxBTFBIQTpPQSxBTFBIQV9ESUdJVDpPQStPQS50b1VwcGVyQ2FzZSgpK2tlfSxRcj0oQT0xNixlPVdlLkFMUEhBX0RJR0lUKT0+e2xldCB0PSIiLHtsZW5ndGg6cn09ZTtmb3IoO0EtLTspdCs9ZVtNYXRoLnJhbmRvbSgpKnJ8MF07cmV0dXJuIHR9O2Z1bmN0aW9uIGhyKEEpe3JldHVybiEhKEEmJk0oQS5hcHBlbmQpJiZBW1N5bWJvbC50b1N0cmluZ1RhZ109PT0iRm9ybURhdGEiJiZBW1N5bWJvbC5pdGVyYXRvcl0pfXZhciB5cj1BPT57bGV0IGU9bmV3IEFycmF5KDEwKSx0PShyLG4pPT57aWYoY0Eocikpe2lmKGUuaW5kZXhPZihyKT49MClyZXR1cm47aWYoISgidG9KU09OImluIHIpKXtlW25dPXI7bGV0IG89SyhyKT9bXTp7fTtyZXR1cm4gaUEociwoaSxsKT0+e2xldCBjPXQoaSxuKzEpOyFyQShjKSYmKG9bbF09Yyl9KSxlW25dPXZvaWQgMCxvfX1yZXR1cm4gcn07cmV0dXJuIHQoQSwwKX0sd3I9UCgiQXN5bmNGdW5jdGlvbiIpLERyPUE9PkEmJihjQShBKXx8TShBKSkmJk0oQS50aGVuKSYmTShBLmNhdGNoKSxwPXtpc0FycmF5OkssaXNBcnJheUJ1ZmZlcjpPZSxpc0J1ZmZlcjpqdCxpc0Zvcm1EYXRhOnRyLGlzQXJyYXlCdWZmZXJWaWV3Ol90LGlzU3RyaW5nOnp0LGlzTnVtYmVyOlVlLGlzQm9vbGVhbjpWdCxpc09iamVjdDpjQSxpc1BsYWluT2JqZWN0OnVBLGlzVW5kZWZpbmVkOnJBLGlzRGF0ZTpadCxpc0ZpbGU6WHQsaXNCbG9iOiR0LGlzUmVnRXhwOkJyLGlzRnVuY3Rpb246TSxpc1N0cmVhbTplcixpc1VSTFNlYXJjaFBhcmFtczpycixpc1R5cGVkQXJyYXk6Z3IsaXNGaWxlTGlzdDpBcixmb3JFYWNoOmlBLG1lcmdlOlVBLGV4dGVuZDpucix0cmltOmlyLHN0cmlwQk9NOm9yLGluaGVyaXRzOmFyLHRvRmxhdE9iamVjdDpzcixraW5kT2Y6ZkEsa2luZE9mVGVzdDpQLGVuZHNXaXRoOklyLHRvQXJyYXk6bHIsZm9yRWFjaEVudHJ5OnVyLG1hdGNoQWxsOmZyLGlzSFRNTEZvcm06cHIsaGFzT3duUHJvcGVydHk6U2UsaGFzT3duUHJvcDpTZSxyZWR1Y2VEZXNjcmlwdG9yczp4ZSxmcmVlemVNZXRob2RzOkNyLHRvT2JqZWN0U2V0Om1yLHRvQ2FtZWxDYXNlOmNyLG5vb3A6ZHIsdG9GaW5pdGVOdW1iZXI6RXIsZmluZEtleTpOZSxnbG9iYWw6TWUsaXNDb250ZXh0RGVmaW5lZDpQZSxBTFBIQUJFVDpXZSxnZW5lcmF0ZVN0cmluZzpRcixpc1NwZWNDb21wbGlhbnRGb3JtOmhyLHRvSlNPTk9iamVjdDp5cixpc0FzeW5jRm46d3IsaXNUaGVuYWJsZTpEcn07ZnVuY3Rpb24gdihBLGUsdCxyLG4pe0Vycm9yLmNhbGwodGhpcyksRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2U/RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcyx0aGlzLmNvbnN0cnVjdG9yKTp0aGlzLnN0YWNrPW5ldyBFcnJvcigpLnN0YWNrLHRoaXMubWVzc2FnZT1BLHRoaXMubmFtZT0iQXhpb3NFcnJvciIsZSYmKHRoaXMuY29kZT1lKSx0JiYodGhpcy5jb25maWc9dCksciYmKHRoaXMucmVxdWVzdD1yKSxuJiYodGhpcy5yZXNwb25zZT1uKX1wLmluaGVyaXRzKHYsRXJyb3Ise3RvSlNPTjpmdW5jdGlvbigpe3JldHVybnttZXNzYWdlOnRoaXMubWVzc2FnZSxuYW1lOnRoaXMubmFtZSxkZXNjcmlwdGlvbjp0aGlzLmRlc2NyaXB0aW9uLG51bWJlcjp0aGlzLm51bWJlcixmaWxlTmFtZTp0aGlzLmZpbGVOYW1lLGxpbmVOdW1iZXI6dGhpcy5saW5lTnVtYmVyLGNvbHVtbk51bWJlcjp0aGlzLmNvbHVtbk51bWJlcixzdGFjazp0aGlzLnN0YWNrLGNvbmZpZzpwLnRvSlNPTk9iamVjdCh0aGlzLmNvbmZpZyksY29kZTp0aGlzLmNvZGUsc3RhdHVzOnRoaXMucmVzcG9uc2UmJnRoaXMucmVzcG9uc2Uuc3RhdHVzP3RoaXMucmVzcG9uc2Uuc3RhdHVzOm51bGx9fX0pO3ZhciBHZT12LnByb3RvdHlwZSxUZT17fTtbIkVSUl9CQURfT1BUSU9OX1ZBTFVFIiwiRVJSX0JBRF9PUFRJT04iLCJFQ09OTkFCT1JURUQiLCJFVElNRURPVVQiLCJFUlJfTkVUV09SSyIsIkVSUl9GUl9UT09fTUFOWV9SRURJUkVDVFMiLCJFUlJfREVQUkVDQVRFRCIsIkVSUl9CQURfUkVTUE9OU0UiLCJFUlJfQkFEX1JFUVVFU1QiLCJFUlJfQ0FOQ0VMRUQiLCJFUlJfTk9UX1NVUFBPUlQiLCJFUlJfSU5WQUxJRF9VUkwiXS5mb3JFYWNoKEE9PntUZVtBXT17dmFsdWU6QX19KTtPYmplY3QuZGVmaW5lUHJvcGVydGllcyh2LFRlKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoR2UsImlzQXhpb3NFcnJvciIse3ZhbHVlOiEwfSk7di5mcm9tPShBLGUsdCxyLG4sbyk9PntsZXQgaT1PYmplY3QuY3JlYXRlKEdlKTtyZXR1cm4gcC50b0ZsYXRPYmplY3QoQSxpLGZ1bmN0aW9uKGMpe3JldHVybiBjIT09RXJyb3IucHJvdG90eXBlfSxsPT5sIT09ImlzQXhpb3NFcnJvciIpLHYuY2FsbChpLEEubWVzc2FnZSxlLHQscixuKSxpLmNhdXNlPUEsaS5uYW1lPUEubmFtZSxvJiZPYmplY3QuYXNzaWduKGksbyksaX07dmFyIGg9djt2YXIgQkE9bnVsbDtmdW5jdGlvbiBNQShBKXtyZXR1cm4gcC5pc1BsYWluT2JqZWN0KEEpfHxwLmlzQXJyYXkoQSl9ZnVuY3Rpb24gSmUoQSl7cmV0dXJuIHAuZW5kc1dpdGgoQSwiW10iKT9BLnNsaWNlKDAsLTIpOkF9ZnVuY3Rpb24gTGUoQSxlLHQpe3JldHVybiBBP0EuY29uY2F0KGUpLm1hcChmdW5jdGlvbihuLG8pe3JldHVybiBuPUplKG4pLCF0JiZvPyJbIituKyJdIjpufSkuam9pbih0PyIuIjoiIik6ZX1mdW5jdGlvbiBicihBKXtyZXR1cm4gcC5pc0FycmF5KEEpJiYhQS5zb21lKE1BKX12YXIgRnI9cC50b0ZsYXRPYmplY3QocCx7fSxudWxsLGZ1bmN0aW9uKGUpe3JldHVybi9eaXNbQS1aXS8udGVzdChlKX0pO2Z1bmN0aW9uIFJyKEEsZSx0KXtpZighcC5pc09iamVjdChBKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJ0YXJnZXQgbXVzdCBiZSBhbiBvYmplY3QiKTtlPWV8fG5ldyhCQXx8Rm9ybURhdGEpLHQ9cC50b0ZsYXRPYmplY3QodCx7bWV0YVRva2VuczohMCxkb3RzOiExLGluZGV4ZXM6ITF9LCExLGZ1bmN0aW9uKEMsbSl7cmV0dXJuIXAuaXNVbmRlZmluZWQobVtDXSl9KTtsZXQgcj10Lm1ldGFUb2tlbnMsbj10LnZpc2l0b3J8fGcsbz10LmRvdHMsaT10LmluZGV4ZXMsYz0odC5CbG9ifHx0eXBlb2YgQmxvYjwidSImJkJsb2IpJiZwLmlzU3BlY0NvbXBsaWFudEZvcm0oZSk7aWYoIXAuaXNGdW5jdGlvbihuKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJ2aXNpdG9yIG11c3QgYmUgYSBmdW5jdGlvbiIpO2Z1bmN0aW9uIEkocyl7aWYocz09PW51bGwpcmV0dXJuIiI7aWYocC5pc0RhdGUocykpcmV0dXJuIHMudG9JU09TdHJpbmcoKTtpZighYyYmcC5pc0Jsb2IocykpdGhyb3cgbmV3IGgoIkJsb2IgaXMgbm90IHN1cHBvcnRlZC4gVXNlIGEgQnVmZmVyIGluc3RlYWQuIik7cmV0dXJuIHAuaXNBcnJheUJ1ZmZlcihzKXx8cC5pc1R5cGVkQXJyYXkocyk/YyYmdHlwZW9mIEJsb2I9PSJmdW5jdGlvbiI/bmV3IEJsb2IoW3NdKTpCdWZmZXIuZnJvbShzKTpzfWZ1bmN0aW9uIGcocyxDLG0pe2xldCB3PXM7aWYocyYmIW0mJnR5cGVvZiBzPT0ib2JqZWN0Iil7aWYocC5lbmRzV2l0aChDLCJ7fSIpKUM9cj9DOkMuc2xpY2UoMCwtMikscz1KU09OLnN0cmluZ2lmeShzKTtlbHNlIGlmKHAuaXNBcnJheShzKSYmYnIocyl8fChwLmlzRmlsZUxpc3Qocyl8fHAuZW5kc1dpdGgoQywiW10iKSkmJih3PXAudG9BcnJheShzKSkpcmV0dXJuIEM9SmUoQyksdy5mb3JFYWNoKGZ1bmN0aW9uKEQsa0EpeyEocC5pc1VuZGVmaW5lZChEKXx8RD09PW51bGwpJiZlLmFwcGVuZChpPT09ITA/TGUoW0NdLGtBLG8pOmk9PT1udWxsP0M6QysiW10iLEkoRCkpfSksITF9cmV0dXJuIE1BKHMpPyEwOihlLmFwcGVuZChMZShtLEMsbyksSShzKSksITEpfWxldCB1PVtdLGY9T2JqZWN0LmFzc2lnbihGcix7ZGVmYXVsdFZpc2l0b3I6Zyxjb252ZXJ0VmFsdWU6SSxpc1Zpc2l0YWJsZTpNQX0pO2Z1bmN0aW9uIGEocyxDKXtpZighcC5pc1VuZGVmaW5lZChzKSl7aWYodS5pbmRleE9mKHMpIT09LTEpdGhyb3cgRXJyb3IoIkNpcmN1bGFyIHJlZmVyZW5jZSBkZXRlY3RlZCBpbiAiK0Muam9pbigiLiIpKTt1LnB1c2gocykscC5mb3JFYWNoKHMsZnVuY3Rpb24odyx5KXsoIShwLmlzVW5kZWZpbmVkKHcpfHx3PT09bnVsbCkmJm4uY2FsbChlLHcscC5pc1N0cmluZyh5KT95LnRyaW0oKTp5LEMsZikpPT09ITAmJmEodyxDP0MuY29uY2F0KHkpOlt5XSl9KSx1LnBvcCgpfX1pZighcC5pc09iamVjdChBKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJkYXRhIG11c3QgYmUgYW4gb2JqZWN0Iik7cmV0dXJuIGEoQSksZX12YXIgVz1ScjtmdW5jdGlvbiBIZShBKXtsZXQgZT17IiEiOiIlMjEiLCInIjoiJTI3IiwiKCI6IiUyOCIsIikiOiIlMjkiLCJ+IjoiJTdFIiwiJTIwIjoiKyIsIiUwMCI6IlwwIn07cmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChBKS5yZXBsYWNlKC9bIScoKX5dfCUyMHwlMDAvZyxmdW5jdGlvbihyKXtyZXR1cm4gZVtyXX0pfWZ1bmN0aW9uIFllKEEsZSl7dGhpcy5fcGFpcnM9W10sQSYmVyhBLHRoaXMsZSl9dmFyIHFlPVllLnByb3RvdHlwZTtxZS5hcHBlbmQ9ZnVuY3Rpb24oZSx0KXt0aGlzLl9wYWlycy5wdXNoKFtlLHRdKX07cWUudG9TdHJpbmc9ZnVuY3Rpb24oZSl7bGV0IHQ9ZT9mdW5jdGlvbihyKXtyZXR1cm4gZS5jYWxsKHRoaXMscixIZSl9OkhlO3JldHVybiB0aGlzLl9wYWlycy5tYXAoZnVuY3Rpb24obil7cmV0dXJuIHQoblswXSkrIj0iK3QoblsxXSl9LCIiKS5qb2luKCImIil9O3ZhciBDQT1ZZTtmdW5jdGlvbiBTcihBKXtyZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KEEpLnJlcGxhY2UoLyUzQS9naSwiOiIpLnJlcGxhY2UoLyUyNC9nLCIkIikucmVwbGFjZSgvJTJDL2dpLCIsIikucmVwbGFjZSgvJTIwL2csIisiKS5yZXBsYWNlKC8lNUIvZ2ksIlsiKS5yZXBsYWNlKC8lNUQvZ2ksIl0iKX1mdW5jdGlvbiBuQShBLGUsdCl7aWYoIWUpcmV0dXJuIEE7bGV0IHI9dCYmdC5lbmNvZGV8fFNyLG49dCYmdC5zZXJpYWxpemUsbztpZihuP289bihlLHQpOm89cC5pc1VSTFNlYXJjaFBhcmFtcyhlKT9lLnRvU3RyaW5nKCk6bmV3IENBKGUsdCkudG9TdHJpbmcociksbyl7bGV0IGk9QS5pbmRleE9mKCIjIik7aSE9PS0xJiYoQT1BLnNsaWNlKDAsaSkpLEErPShBLmluZGV4T2YoIj8iKT09PS0xPyI/IjoiJiIpK299cmV0dXJuIEF9dmFyIFBBPWNsYXNze2NvbnN0cnVjdG9yKCl7dGhpcy5oYW5kbGVycz1bXX11c2UoZSx0LHIpe3JldHVybiB0aGlzLmhhbmRsZXJzLnB1c2goe2Z1bGZpbGxlZDplLHJlamVjdGVkOnQsc3luY2hyb25vdXM6cj9yLnN5bmNocm9ub3VzOiExLHJ1bldoZW46cj9yLnJ1bldoZW46bnVsbH0pLHRoaXMuaGFuZGxlcnMubGVuZ3RoLTF9ZWplY3QoZSl7dGhpcy5oYW5kbGVyc1tlXSYmKHRoaXMuaGFuZGxlcnNbZV09bnVsbCl9Y2xlYXIoKXt0aGlzLmhhbmRsZXJzJiYodGhpcy5oYW5kbGVycz1bXSl9Zm9yRWFjaChlKXtwLmZvckVhY2godGhpcy5oYW5kbGVycyxmdW5jdGlvbihyKXtyIT09bnVsbCYmZShyKX0pfX0seEE9UEE7dmFyIG1BPXtzaWxlbnRKU09OUGFyc2luZzohMCxmb3JjZWRKU09OUGFyc2luZzohMCxjbGFyaWZ5VGltZW91dEVycm9yOiExfTt2YXIgS2U9dHlwZW9mIFVSTFNlYXJjaFBhcmFtczwidSI/VVJMU2VhcmNoUGFyYW1zOkNBO3ZhciB2ZT10eXBlb2YgRm9ybURhdGE8InUiP0Zvcm1EYXRhOm51bGw7dmFyIGplPXR5cGVvZiBCbG9iPCJ1Ij9CbG9iOm51bGw7dmFyIF9lPXtpc0Jyb3dzZXI6ITAsY2xhc3Nlczp7VVJMU2VhcmNoUGFyYW1zOktlLEZvcm1EYXRhOnZlLEJsb2I6amV9LHByb3RvY29sczpbImh0dHAiLCJodHRwcyIsImZpbGUiLCJibG9iIiwidXJsIiwiZGF0YSJdfTt2YXIgV0E9e307UHQoV0Ese2hhc0Jyb3dzZXJFbnY6KCk9PnplLGhhc1N0YW5kYXJkQnJvd3NlckVudjooKT0+a3IsaGFzU3RhbmRhcmRCcm93c2VyV2ViV29ya2VyRW52OigpPT5Pcn0pO3ZhciB6ZT10eXBlb2Ygd2luZG93PCJ1IiYmdHlwZW9mIGRvY3VtZW50PCJ1Iixrcj0oQT0+emUmJlsiUmVhY3ROYXRpdmUiLCJOYXRpdmVTY3JpcHQiLCJOUyJdLmluZGV4T2YoQSk8MCkodHlwZW9mIG5hdmlnYXRvcjwidSImJm5hdmlnYXRvci5wcm9kdWN0KSxPcj10eXBlb2YgV29ya2VyR2xvYmFsU2NvcGU8InUiJiZzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGUmJnR5cGVvZiBzZWxmLmltcG9ydFNjcmlwdHM9PSJmdW5jdGlvbiI7dmFyIFM9ey4uLldBLC4uLl9lfTtmdW5jdGlvbiBHQShBLGUpe3JldHVybiBXKEEsbmV3IFMuY2xhc3Nlcy5VUkxTZWFyY2hQYXJhbXMsT2JqZWN0LmFzc2lnbih7dmlzaXRvcjpmdW5jdGlvbih0LHIsbixvKXtyZXR1cm4gUy5pc05vZGUmJnAuaXNCdWZmZXIodCk/KHRoaXMuYXBwZW5kKHIsdC50b1N0cmluZygiYmFzZTY0IikpLCExKTpvLmRlZmF1bHRWaXNpdG9yLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19LGUpKX1mdW5jdGlvbiBVcihBKXtyZXR1cm4gcC5tYXRjaEFsbCgvXHcrfFxbKFx3KildL2csQSkubWFwKGU9PmVbMF09PT0iW10iPyIiOmVbMV18fGVbMF0pfWZ1bmN0aW9uIE5yKEEpe2xldCBlPXt9LHQ9T2JqZWN0LmtleXMoQSkscixuPXQubGVuZ3RoLG87Zm9yKHI9MDtyPG47cisrKW89dFtyXSxlW29dPUFbb107cmV0dXJuIGV9ZnVuY3Rpb24gTXIoQSl7ZnVuY3Rpb24gZSh0LHIsbixvKXtsZXQgaT10W28rK10sbD1OdW1iZXIuaXNGaW5pdGUoK2kpLGM9bz49dC5sZW5ndGg7cmV0dXJuIGk9IWkmJnAuaXNBcnJheShuKT9uLmxlbmd0aDppLGM/KHAuaGFzT3duUHJvcChuLGkpP25baV09W25baV0scl06bltpXT1yLCFsKTooKCFuW2ldfHwhcC5pc09iamVjdChuW2ldKSkmJihuW2ldPVtdKSxlKHQscixuW2ldLG8pJiZwLmlzQXJyYXkobltpXSkmJihuW2ldPU5yKG5baV0pKSwhbCl9aWYocC5pc0Zvcm1EYXRhKEEpJiZwLmlzRnVuY3Rpb24oQS5lbnRyaWVzKSl7bGV0IHQ9e307cmV0dXJuIHAuZm9yRWFjaEVudHJ5KEEsKHIsbik9PntlKFVyKHIpLG4sdCwwKX0pLHR9cmV0dXJuIG51bGx9dmFyIGRBPU1yO2Z1bmN0aW9uIFByKEEsZSx0KXtpZihwLmlzU3RyaW5nKEEpKXRyeXtyZXR1cm4oZXx8SlNPTi5wYXJzZSkoQSkscC50cmltKEEpfWNhdGNoKHIpe2lmKHIubmFtZSE9PSJTeW50YXhFcnJvciIpdGhyb3cgcn1yZXR1cm4odHx8SlNPTi5zdHJpbmdpZnkpKEEpfXZhciBUQT17dHJhbnNpdGlvbmFsOm1BLGFkYXB0ZXI6WyJ4aHIiLCJodHRwIl0sdHJhbnNmb3JtUmVxdWVzdDpbZnVuY3Rpb24oZSx0KXtsZXQgcj10LmdldENvbnRlbnRUeXBlKCl8fCIiLG49ci5pbmRleE9mKCJhcHBsaWNhdGlvbi9qc29uIik+LTEsbz1wLmlzT2JqZWN0KGUpO2lmKG8mJnAuaXNIVE1MRm9ybShlKSYmKGU9bmV3IEZvcm1EYXRhKGUpKSxwLmlzRm9ybURhdGEoZSkpcmV0dXJuIG4mJm4/SlNPTi5zdHJpbmdpZnkoZEEoZSkpOmU7aWYocC5pc0FycmF5QnVmZmVyKGUpfHxwLmlzQnVmZmVyKGUpfHxwLmlzU3RyZWFtKGUpfHxwLmlzRmlsZShlKXx8cC5pc0Jsb2IoZSkpcmV0dXJuIGU7aWYocC5pc0FycmF5QnVmZmVyVmlldyhlKSlyZXR1cm4gZS5idWZmZXI7aWYocC5pc1VSTFNlYXJjaFBhcmFtcyhlKSlyZXR1cm4gdC5zZXRDb250ZW50VHlwZSgiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9dXRmLTgiLCExKSxlLnRvU3RyaW5nKCk7bGV0IGw7aWYobyl7aWYoci5pbmRleE9mKCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKT4tMSlyZXR1cm4gR0EoZSx0aGlzLmZvcm1TZXJpYWxpemVyKS50b1N0cmluZygpO2lmKChsPXAuaXNGaWxlTGlzdChlKSl8fHIuaW5kZXhPZigibXVsdGlwYXJ0L2Zvcm0tZGF0YSIpPi0xKXtsZXQgYz10aGlzLmVudiYmdGhpcy5lbnYuRm9ybURhdGE7cmV0dXJuIFcobD97ImZpbGVzW10iOmV9OmUsYyYmbmV3IGMsdGhpcy5mb3JtU2VyaWFsaXplcil9fXJldHVybiBvfHxuPyh0LnNldENvbnRlbnRUeXBlKCJhcHBsaWNhdGlvbi9qc29uIiwhMSksUHIoZSkpOmV9XSx0cmFuc2Zvcm1SZXNwb25zZTpbZnVuY3Rpb24oZSl7bGV0IHQ9dGhpcy50cmFuc2l0aW9uYWx8fFRBLnRyYW5zaXRpb25hbCxyPXQmJnQuZm9yY2VkSlNPTlBhcnNpbmcsbj10aGlzLnJlc3BvbnNlVHlwZT09PSJqc29uIjtpZihlJiZwLmlzU3RyaW5nKGUpJiYociYmIXRoaXMucmVzcG9uc2VUeXBlfHxuKSl7bGV0IGk9ISh0JiZ0LnNpbGVudEpTT05QYXJzaW5nKSYmbjt0cnl7cmV0dXJuIEpTT04ucGFyc2UoZSl9Y2F0Y2gobCl7aWYoaSl0aHJvdyBsLm5hbWU9PT0iU3ludGF4RXJyb3IiP2guZnJvbShsLGguRVJSX0JBRF9SRVNQT05TRSx0aGlzLG51bGwsdGhpcy5yZXNwb25zZSk6bH19cmV0dXJuIGV9XSx0aW1lb3V0OjAseHNyZkNvb2tpZU5hbWU6IlhTUkYtVE9LRU4iLHhzcmZIZWFkZXJOYW1lOiJYLVhTUkYtVE9LRU4iLG1heENvbnRlbnRMZW5ndGg6LTEsbWF4Qm9keUxlbmd0aDotMSxlbnY6e0Zvcm1EYXRhOlMuY2xhc3Nlcy5Gb3JtRGF0YSxCbG9iOlMuY2xhc3Nlcy5CbG9ifSx2YWxpZGF0ZVN0YXR1czpmdW5jdGlvbihlKXtyZXR1cm4gZT49MjAwJiZlPDMwMH0saGVhZGVyczp7Y29tbW9uOntBY2NlcHQ6ImFwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKiIsIkNvbnRlbnQtVHlwZSI6dm9pZCAwfX19O3AuZm9yRWFjaChbImRlbGV0ZSIsImdldCIsImhlYWQiLCJwb3N0IiwicHV0IiwicGF0Y2giXSxBPT57VEEuaGVhZGVyc1tBXT17fX0pO3ZhciBqPVRBO3ZhciB4cj1wLnRvT2JqZWN0U2V0KFsiYWdlIiwiYXV0aG9yaXphdGlvbiIsImNvbnRlbnQtbGVuZ3RoIiwiY29udGVudC10eXBlIiwiZXRhZyIsImV4cGlyZXMiLCJmcm9tIiwiaG9zdCIsImlmLW1vZGlmaWVkLXNpbmNlIiwiaWYtdW5tb2RpZmllZC1zaW5jZSIsImxhc3QtbW9kaWZpZWQiLCJsb2NhdGlvbiIsIm1heC1mb3J3YXJkcyIsInByb3h5LWF1dGhvcml6YXRpb24iLCJyZWZlcmVyIiwicmV0cnktYWZ0ZXIiLCJ1c2VyLWFnZW50Il0pLFZlPUE9PntsZXQgZT17fSx0LHIsbjtyZXR1cm4gQSYmQS5zcGxpdChgCmApLmZvckVhY2goZnVuY3Rpb24oaSl7bj1pLmluZGV4T2YoIjoiKSx0PWkuc3Vic3RyaW5nKDAsbikudHJpbSgpLnRvTG93ZXJDYXNlKCkscj1pLnN1YnN0cmluZyhuKzEpLnRyaW0oKSwhKCF0fHxlW3RdJiZ4clt0XSkmJih0PT09InNldC1jb29raWUiP2VbdF0/ZVt0XS5wdXNoKHIpOmVbdF09W3JdOmVbdF09ZVt0XT9lW3RdKyIsICIrcjpyKX0pLGV9O3ZhciBaZT1TeW1ib2woImludGVybmFscyIpO2Z1bmN0aW9uIG9BKEEpe3JldHVybiBBJiZTdHJpbmcoQSkudHJpbSgpLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gRUEoQSl7cmV0dXJuIEE9PT0hMXx8QT09bnVsbD9BOnAuaXNBcnJheShBKT9BLm1hcChFQSk6U3RyaW5nKEEpfWZ1bmN0aW9uIFdyKEEpe2xldCBlPU9iamVjdC5jcmVhdGUobnVsbCksdD0vKFteXHMsOz1dKylccyooPzo9XHMqKFteLDtdKykpPy9nLHI7Zm9yKDtyPXQuZXhlYyhBKTspZVtyWzFdXT1yWzJdO3JldHVybiBlfXZhciBHcj1BPT4vXlstX2EtekEtWjAtOV5gfH4sISMkJSYnKisuXSskLy50ZXN0KEEudHJpbSgpKTtmdW5jdGlvbiBMQShBLGUsdCxyLG4pe2lmKHAuaXNGdW5jdGlvbihyKSlyZXR1cm4gci5jYWxsKHRoaXMsZSx0KTtpZihuJiYoZT10KSwhIXAuaXNTdHJpbmcoZSkpe2lmKHAuaXNTdHJpbmcocikpcmV0dXJuIGUuaW5kZXhPZihyKSE9PS0xO2lmKHAuaXNSZWdFeHAocikpcmV0dXJuIHIudGVzdChlKX19ZnVuY3Rpb24gVHIoQSl7cmV0dXJuIEEudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvKFthLXpcZF0pKFx3KikvZywoZSx0LHIpPT50LnRvVXBwZXJDYXNlKCkrcil9ZnVuY3Rpb24gTHIoQSxlKXtsZXQgdD1wLnRvQ2FtZWxDYXNlKCIgIitlKTtbImdldCIsInNldCIsImhhcyJdLmZvckVhY2gocj0+e09iamVjdC5kZWZpbmVQcm9wZXJ0eShBLHIrdCx7dmFsdWU6ZnVuY3Rpb24obixvLGkpe3JldHVybiB0aGlzW3JdLmNhbGwodGhpcyxlLG4sbyxpKX0sY29uZmlndXJhYmxlOiEwfSl9KX12YXIgXz1jbGFzc3tjb25zdHJ1Y3RvcihlKXtlJiZ0aGlzLnNldChlKX1zZXQoZSx0LHIpe2xldCBuPXRoaXM7ZnVuY3Rpb24gbyhsLGMsSSl7bGV0IGc9b0EoYyk7aWYoIWcpdGhyb3cgbmV3IEVycm9yKCJoZWFkZXIgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZyIpO2xldCB1PXAuZmluZEtleShuLGcpOyghdXx8blt1XT09PXZvaWQgMHx8ST09PSEwfHxJPT09dm9pZCAwJiZuW3VdIT09ITEpJiYoblt1fHxjXT1FQShsKSl9bGV0IGk9KGwsYyk9PnAuZm9yRWFjaChsLChJLGcpPT5vKEksZyxjKSk7cmV0dXJuIHAuaXNQbGFpbk9iamVjdChlKXx8ZSBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3I/aShlLHQpOnAuaXNTdHJpbmcoZSkmJihlPWUudHJpbSgpKSYmIUdyKGUpP2koVmUoZSksdCk6ZSE9bnVsbCYmbyh0LGUsciksdGhpc31nZXQoZSx0KXtpZihlPW9BKGUpLGUpe2xldCByPXAuZmluZEtleSh0aGlzLGUpO2lmKHIpe2xldCBuPXRoaXNbcl07aWYoIXQpcmV0dXJuIG47aWYodD09PSEwKXJldHVybiBXcihuKTtpZihwLmlzRnVuY3Rpb24odCkpcmV0dXJuIHQuY2FsbCh0aGlzLG4scik7aWYocC5pc1JlZ0V4cCh0KSlyZXR1cm4gdC5leGVjKG4pO3Rocm93IG5ldyBUeXBlRXJyb3IoInBhcnNlciBtdXN0IGJlIGJvb2xlYW58cmVnZXhwfGZ1bmN0aW9uIil9fX1oYXMoZSx0KXtpZihlPW9BKGUpLGUpe2xldCByPXAuZmluZEtleSh0aGlzLGUpO3JldHVybiEhKHImJnRoaXNbcl0hPT12b2lkIDAmJighdHx8TEEodGhpcyx0aGlzW3JdLHIsdCkpKX1yZXR1cm4hMX1kZWxldGUoZSx0KXtsZXQgcj10aGlzLG49ITE7ZnVuY3Rpb24gbyhpKXtpZihpPW9BKGkpLGkpe2xldCBsPXAuZmluZEtleShyLGkpO2wmJighdHx8TEEocixyW2xdLGwsdCkpJiYoZGVsZXRlIHJbbF0sbj0hMCl9fXJldHVybiBwLmlzQXJyYXkoZSk/ZS5mb3JFYWNoKG8pOm8oZSksbn1jbGVhcihlKXtsZXQgdD1PYmplY3Qua2V5cyh0aGlzKSxyPXQubGVuZ3RoLG49ITE7Zm9yKDtyLS07KXtsZXQgbz10W3JdOyghZXx8TEEodGhpcyx0aGlzW29dLG8sZSwhMCkpJiYoZGVsZXRlIHRoaXNbb10sbj0hMCl9cmV0dXJuIG59bm9ybWFsaXplKGUpe2xldCB0PXRoaXMscj17fTtyZXR1cm4gcC5mb3JFYWNoKHRoaXMsKG4sbyk9PntsZXQgaT1wLmZpbmRLZXkocixvKTtpZihpKXt0W2ldPUVBKG4pLGRlbGV0ZSB0W29dO3JldHVybn1sZXQgbD1lP1RyKG8pOlN0cmluZyhvKS50cmltKCk7bCE9PW8mJmRlbGV0ZSB0W29dLHRbbF09RUEobikscltsXT0hMH0pLHRoaXN9Y29uY2F0KC4uLmUpe3JldHVybiB0aGlzLmNvbnN0cnVjdG9yLmNvbmNhdCh0aGlzLC4uLmUpfXRvSlNPTihlKXtsZXQgdD1PYmplY3QuY3JlYXRlKG51bGwpO3JldHVybiBwLmZvckVhY2godGhpcywocixuKT0+e3IhPW51bGwmJnIhPT0hMSYmKHRbbl09ZSYmcC5pc0FycmF5KHIpP3Iuam9pbigiLCAiKTpyKX0pLHR9W1N5bWJvbC5pdGVyYXRvcl0oKXtyZXR1cm4gT2JqZWN0LmVudHJpZXModGhpcy50b0pTT04oKSlbU3ltYm9sLml0ZXJhdG9yXSgpfXRvU3RyaW5nKCl7cmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMudG9KU09OKCkpLm1hcCgoW2UsdF0pPT5lKyI6ICIrdCkuam9pbihgCmApfWdldFtTeW1ib2wudG9TdHJpbmdUYWddKCl7cmV0dXJuIkF4aW9zSGVhZGVycyJ9c3RhdGljIGZyb20oZSl7cmV0dXJuIGUgaW5zdGFuY2VvZiB0aGlzP2U6bmV3IHRoaXMoZSl9c3RhdGljIGNvbmNhdChlLC4uLnQpe2xldCByPW5ldyB0aGlzKGUpO3JldHVybiB0LmZvckVhY2gobj0+ci5zZXQobikpLHJ9c3RhdGljIGFjY2Vzc29yKGUpe2xldCByPSh0aGlzW1plXT10aGlzW1plXT17YWNjZXNzb3JzOnt9fSkuYWNjZXNzb3JzLG49dGhpcy5wcm90b3R5cGU7ZnVuY3Rpb24gbyhpKXtsZXQgbD1vQShpKTtyW2xdfHwoTHIobixpKSxyW2xdPSEwKX1yZXR1cm4gcC5pc0FycmF5KGUpP2UuZm9yRWFjaChvKTpvKGUpLHRoaXN9fTtfLmFjY2Vzc29yKFsiQ29udGVudC1UeXBlIiwiQ29udGVudC1MZW5ndGgiLCJBY2NlcHQiLCJBY2NlcHQtRW5jb2RpbmciLCJVc2VyLUFnZW50IiwiQXV0aG9yaXphdGlvbiJdKTtwLnJlZHVjZURlc2NyaXB0b3JzKF8ucHJvdG90eXBlLCh7dmFsdWU6QX0sZSk9PntsZXQgdD1lWzBdLnRvVXBwZXJDYXNlKCkrZS5zbGljZSgxKTtyZXR1cm57Z2V0OigpPT5BLHNldChyKXt0aGlzW3RdPXJ9fX0pO3AuZnJlZXplTWV0aG9kcyhfKTt2YXIgaz1fO2Z1bmN0aW9uIGFBKEEsZSl7bGV0IHQ9dGhpc3x8aixyPWV8fHQsbj1rLmZyb20oci5oZWFkZXJzKSxvPXIuZGF0YTtyZXR1cm4gcC5mb3JFYWNoKEEsZnVuY3Rpb24obCl7bz1sLmNhbGwodCxvLG4ubm9ybWFsaXplKCksZT9lLnN0YXR1czp2b2lkIDApfSksbi5ub3JtYWxpemUoKSxvfWZ1bmN0aW9uIHNBKEEpe3JldHVybiEhKEEmJkEuX19DQU5DRUxfXyl9ZnVuY3Rpb24gWGUoQSxlLHQpe2guY2FsbCh0aGlzLEE/PyJjYW5jZWxlZCIsaC5FUlJfQ0FOQ0VMRUQsZSx0KSx0aGlzLm5hbWU9IkNhbmNlbGVkRXJyb3IifXAuaW5oZXJpdHMoWGUsaCx7X19DQU5DRUxfXzohMH0pO3ZhciBHPVhlO2Z1bmN0aW9uIEpBKEEsZSx0KXtsZXQgcj10LmNvbmZpZy52YWxpZGF0ZVN0YXR1czshdC5zdGF0dXN8fCFyfHxyKHQuc3RhdHVzKT9BKHQpOmUobmV3IGgoIlJlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgIit0LnN0YXR1cyxbaC5FUlJfQkFEX1JFUVVFU1QsaC5FUlJfQkFEX1JFU1BPTlNFXVtNYXRoLmZsb29yKHQuc3RhdHVzLzEwMCktNF0sdC5jb25maWcsdC5yZXF1ZXN0LHQpKX12YXIgJGU9Uy5oYXNTdGFuZGFyZEJyb3dzZXJFbnY/e3dyaXRlKEEsZSx0LHIsbixvKXtsZXQgaT1bQSsiPSIrZW5jb2RlVVJJQ29tcG9uZW50KGUpXTtwLmlzTnVtYmVyKHQpJiZpLnB1c2goImV4cGlyZXM9IituZXcgRGF0ZSh0KS50b0dNVFN0cmluZygpKSxwLmlzU3RyaW5nKHIpJiZpLnB1c2goInBhdGg9IityKSxwLmlzU3RyaW5nKG4pJiZpLnB1c2goImRvbWFpbj0iK24pLG89PT0hMCYmaS5wdXNoKCJzZWN1cmUiKSxkb2N1bWVudC5jb29raWU9aS5qb2luKCI7ICIpfSxyZWFkKEEpe2xldCBlPWRvY3VtZW50LmNvb2tpZS5tYXRjaChuZXcgUmVnRXhwKCIoXnw7XFxzKikoIitBKyIpPShbXjtdKikiKSk7cmV0dXJuIGU/ZGVjb2RlVVJJQ29tcG9uZW50KGVbM10pOm51bGx9LHJlbW92ZShBKXt0aGlzLndyaXRlKEEsIiIsRGF0ZS5ub3coKS04NjRlNSl9fTp7d3JpdGUoKXt9LHJlYWQoKXtyZXR1cm4gbnVsbH0scmVtb3ZlKCl7fX07ZnVuY3Rpb24gSEEoQSl7cmV0dXJuL14oW2Etel1bYS16XGQrXC0uXSo6KT9cL1wvL2kudGVzdChBKX1mdW5jdGlvbiBZQShBLGUpe3JldHVybiBlP0EucmVwbGFjZSgvXC8rJC8sIiIpKyIvIitlLnJlcGxhY2UoL15cLysvLCIiKTpBfWZ1bmN0aW9uIElBKEEsZSl7cmV0dXJuIEEmJiFIQShlKT9ZQShBLGUpOmV9dmFyIEF0PVMuaGFzU3RhbmRhcmRCcm93c2VyRW52P2Z1bmN0aW9uKCl7bGV0IGU9Lyhtc2llfHRyaWRlbnQpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSx0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKSxyO2Z1bmN0aW9uIG4obyl7bGV0IGk9bztyZXR1cm4gZSYmKHQuc2V0QXR0cmlidXRlKCJocmVmIixpKSxpPXQuaHJlZiksdC5zZXRBdHRyaWJ1dGUoImhyZWYiLGkpLHtocmVmOnQuaHJlZixwcm90b2NvbDp0LnByb3RvY29sP3QucHJvdG9jb2wucmVwbGFjZSgvOiQvLCIiKToiIixob3N0OnQuaG9zdCxzZWFyY2g6dC5zZWFyY2g/dC5zZWFyY2gucmVwbGFjZSgvXlw/LywiIik6IiIsaGFzaDp0Lmhhc2g/dC5oYXNoLnJlcGxhY2UoL14jLywiIik6IiIsaG9zdG5hbWU6dC5ob3N0bmFtZSxwb3J0OnQucG9ydCxwYXRobmFtZTp0LnBhdGhuYW1lLmNoYXJBdCgwKT09PSIvIj90LnBhdGhuYW1lOiIvIit0LnBhdGhuYW1lfX1yZXR1cm4gcj1uKHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxmdW5jdGlvbihpKXtsZXQgbD1wLmlzU3RyaW5nKGkpP24oaSk6aTtyZXR1cm4gbC5wcm90b2NvbD09PXIucHJvdG9jb2wmJmwuaG9zdD09PXIuaG9zdH19KCk6ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4hMH19KCk7ZnVuY3Rpb24gcUEoQSl7bGV0IGU9L14oWy0rXHddezEsMjV9KSg6P1wvXC98OikvLmV4ZWMoQSk7cmV0dXJuIGUmJmVbMV18fCIifWZ1bmN0aW9uIEpyKEEsZSl7QT1BfHwxMDtsZXQgdD1uZXcgQXJyYXkoQSkscj1uZXcgQXJyYXkoQSksbj0wLG89MCxpO3JldHVybiBlPWUhPT12b2lkIDA/ZToxZTMsZnVuY3Rpb24oYyl7bGV0IEk9RGF0ZS5ub3coKSxnPXJbb107aXx8KGk9SSksdFtuXT1jLHJbbl09STtsZXQgdT1vLGY9MDtmb3IoO3UhPT1uOylmKz10W3UrK10sdT11JUE7aWYobj0obisxKSVBLG49PT1vJiYobz0obysxKSVBKSxJLWk8ZSlyZXR1cm47bGV0IGE9ZyYmSS1nO3JldHVybiBhP01hdGgucm91bmQoZioxZTMvYSk6dm9pZCAwfX12YXIgZXQ9SnI7ZnVuY3Rpb24gdHQoQSxlKXtsZXQgdD0wLHI9ZXQoNTAsMjUwKTtyZXR1cm4gbj0+e2xldCBvPW4ubG9hZGVkLGk9bi5sZW5ndGhDb21wdXRhYmxlP24udG90YWw6dm9pZCAwLGw9by10LGM9cihsKSxJPW88PWk7dD1vO2xldCBnPXtsb2FkZWQ6byx0b3RhbDppLHByb2dyZXNzOmk/by9pOnZvaWQgMCxieXRlczpsLHJhdGU6Y3x8dm9pZCAwLGVzdGltYXRlZDpjJiZpJiZJPyhpLW8pL2M6dm9pZCAwLGV2ZW50Om59O2dbZT8iZG93bmxvYWQiOiJ1cGxvYWQiXT0hMCxBKGcpfX12YXIgSHI9dHlwZW9mIFhNTEh0dHBSZXF1ZXN0PCJ1IixydD1IciYmZnVuY3Rpb24oQSl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHQscil7bGV0IG49QS5kYXRhLG89ay5mcm9tKEEuaGVhZGVycykubm9ybWFsaXplKCkse3Jlc3BvbnNlVHlwZTppLHdpdGhYU1JGVG9rZW46bH09QSxjO2Z1bmN0aW9uIEkoKXtBLmNhbmNlbFRva2VuJiZBLmNhbmNlbFRva2VuLnVuc3Vic2NyaWJlKGMpLEEuc2lnbmFsJiZBLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCJhYm9ydCIsYyl9bGV0IGc7aWYocC5pc0Zvcm1EYXRhKG4pKXtpZihTLmhhc1N0YW5kYXJkQnJvd3NlckVudnx8Uy5oYXNTdGFuZGFyZEJyb3dzZXJXZWJXb3JrZXJFbnYpby5zZXRDb250ZW50VHlwZSghMSk7ZWxzZSBpZigoZz1vLmdldENvbnRlbnRUeXBlKCkpIT09ITEpe2xldFtDLC4uLm1dPWc/Zy5zcGxpdCgiOyIpLm1hcCh3PT53LnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pOltdO28uc2V0Q29udGVudFR5cGUoW0N8fCJtdWx0aXBhcnQvZm9ybS1kYXRhIiwuLi5tXS5qb2luKCI7ICIpKX19bGV0IHU9bmV3IFhNTEh0dHBSZXF1ZXN0O2lmKEEuYXV0aCl7bGV0IEM9QS5hdXRoLnVzZXJuYW1lfHwiIixtPUEuYXV0aC5wYXNzd29yZD91bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoQS5hdXRoLnBhc3N3b3JkKSk6IiI7by5zZXQoIkF1dGhvcml6YXRpb24iLCJCYXNpYyAiK2J0b2EoQysiOiIrbSkpfWxldCBmPUlBKEEuYmFzZVVSTCxBLnVybCk7dS5vcGVuKEEubWV0aG9kLnRvVXBwZXJDYXNlKCksbkEoZixBLnBhcmFtcyxBLnBhcmFtc1NlcmlhbGl6ZXIpLCEwKSx1LnRpbWVvdXQ9QS50aW1lb3V0O2Z1bmN0aW9uIGEoKXtpZighdSlyZXR1cm47bGV0IEM9ay5mcm9tKCJnZXRBbGxSZXNwb25zZUhlYWRlcnMiaW4gdSYmdS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSksdz17ZGF0YTohaXx8aT09PSJ0ZXh0Inx8aT09PSJqc29uIj91LnJlc3BvbnNlVGV4dDp1LnJlc3BvbnNlLHN0YXR1czp1LnN0YXR1cyxzdGF0dXNUZXh0OnUuc3RhdHVzVGV4dCxoZWFkZXJzOkMsY29uZmlnOkEscmVxdWVzdDp1fTtKQShmdW5jdGlvbihEKXt0KEQpLEkoKX0sZnVuY3Rpb24oRCl7cihEKSxJKCl9LHcpLHU9bnVsbH1pZigib25sb2FkZW5kImluIHU/dS5vbmxvYWRlbmQ9YTp1Lm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpeyF1fHx1LnJlYWR5U3RhdGUhPT00fHx1LnN0YXR1cz09PTAmJiEodS5yZXNwb25zZVVSTCYmdS5yZXNwb25zZVVSTC5pbmRleE9mKCJmaWxlOiIpPT09MCl8fHNldFRpbWVvdXQoYSl9LHUub25hYm9ydD1mdW5jdGlvbigpe3UmJihyKG5ldyBoKCJSZXF1ZXN0IGFib3J0ZWQiLGguRUNPTk5BQk9SVEVELEEsdSkpLHU9bnVsbCl9LHUub25lcnJvcj1mdW5jdGlvbigpe3IobmV3IGgoIk5ldHdvcmsgRXJyb3IiLGguRVJSX05FVFdPUkssQSx1KSksdT1udWxsfSx1Lm9udGltZW91dD1mdW5jdGlvbigpe2xldCBtPUEudGltZW91dD8idGltZW91dCBvZiAiK0EudGltZW91dCsibXMgZXhjZWVkZWQiOiJ0aW1lb3V0IGV4Y2VlZGVkIix3PUEudHJhbnNpdGlvbmFsfHxtQTtBLnRpbWVvdXRFcnJvck1lc3NhZ2UmJihtPUEudGltZW91dEVycm9yTWVzc2FnZSkscihuZXcgaChtLHcuY2xhcmlmeVRpbWVvdXRFcnJvcj9oLkVUSU1FRE9VVDpoLkVDT05OQUJPUlRFRCxBLHUpKSx1PW51bGx9LFMuaGFzU3RhbmRhcmRCcm93c2VyRW52JiYobCYmcC5pc0Z1bmN0aW9uKGwpJiYobD1sKEEpKSxsfHxsIT09ITEmJkF0KGYpKSl7bGV0IEM9QS54c3JmSGVhZGVyTmFtZSYmQS54c3JmQ29va2llTmFtZSYmJGUucmVhZChBLnhzcmZDb29raWVOYW1lKTtDJiZvLnNldChBLnhzcmZIZWFkZXJOYW1lLEMpfW49PT12b2lkIDAmJm8uc2V0Q29udGVudFR5cGUobnVsbCksInNldFJlcXVlc3RIZWFkZXIiaW4gdSYmcC5mb3JFYWNoKG8udG9KU09OKCksZnVuY3Rpb24obSx3KXt1LnNldFJlcXVlc3RIZWFkZXIodyxtKX0pLHAuaXNVbmRlZmluZWQoQS53aXRoQ3JlZGVudGlhbHMpfHwodS53aXRoQ3JlZGVudGlhbHM9ISFBLndpdGhDcmVkZW50aWFscyksaSYmaSE9PSJqc29uIiYmKHUucmVzcG9uc2VUeXBlPUEucmVzcG9uc2VUeXBlKSx0eXBlb2YgQS5vbkRvd25sb2FkUHJvZ3Jlc3M9PSJmdW5jdGlvbiImJnUuYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLHR0KEEub25Eb3dubG9hZFByb2dyZXNzLCEwKSksdHlwZW9mIEEub25VcGxvYWRQcm9ncmVzcz09ImZ1bmN0aW9uIiYmdS51cGxvYWQmJnUudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoInByb2dyZXNzIix0dChBLm9uVXBsb2FkUHJvZ3Jlc3MpKSwoQS5jYW5jZWxUb2tlbnx8QS5zaWduYWwpJiYoYz1DPT57dSYmKHIoIUN8fEMudHlwZT9uZXcgRyhudWxsLEEsdSk6QyksdS5hYm9ydCgpLHU9bnVsbCl9LEEuY2FuY2VsVG9rZW4mJkEuY2FuY2VsVG9rZW4uc3Vic2NyaWJlKGMpLEEuc2lnbmFsJiYoQS5zaWduYWwuYWJvcnRlZD9jKCk6QS5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcigiYWJvcnQiLGMpKSk7bGV0IHM9cUEoZik7aWYocyYmUy5wcm90b2NvbHMuaW5kZXhPZihzKT09PS0xKXtyKG5ldyBoKCJVbnN1cHBvcnRlZCBwcm90b2NvbCAiK3MrIjoiLGguRVJSX0JBRF9SRVFVRVNULEEpKTtyZXR1cm59dS5zZW5kKG58fG51bGwpfSl9O3ZhciBLQT17aHR0cDpCQSx4aHI6cnR9O3AuZm9yRWFjaChLQSwoQSxlKT0+e2lmKEEpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkoQSwibmFtZSIse3ZhbHVlOmV9KX1jYXRjaHt9T2JqZWN0LmRlZmluZVByb3BlcnR5KEEsImFkYXB0ZXJOYW1lIix7dmFsdWU6ZX0pfX0pO3ZhciBpdD1BPT5gLSAke0F9YCxZcj1BPT5wLmlzRnVuY3Rpb24oQSl8fEE9PT1udWxsfHxBPT09ITEsUUE9e2dldEFkYXB0ZXI6QT0+e0E9cC5pc0FycmF5KEEpP0E6W0FdO2xldHtsZW5ndGg6ZX09QSx0LHIsbj17fTtmb3IobGV0IG89MDtvPGU7bysrKXt0PUFbb107bGV0IGk7aWYocj10LCFZcih0KSYmKHI9S0FbKGk9U3RyaW5nKHQpKS50b0xvd2VyQ2FzZSgpXSxyPT09dm9pZCAwKSl0aHJvdyBuZXcgaChgVW5rbm93biBhZGFwdGVyICcke2l9J2ApO2lmKHIpYnJlYWs7bltpfHwiIyIrb109cn1pZighcil7bGV0IG89T2JqZWN0LmVudHJpZXMobikubWFwKChbbCxjXSk9PmBhZGFwdGVyICR7bH0gYCsoYz09PSExPyJpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBlbnZpcm9ubWVudCI6ImlzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGJ1aWxkIikpLGk9ZT9vLmxlbmd0aD4xP2BzaW5jZSA6CmArby5tYXAoaXQpLmpvaW4oYApgKToiICIraXQob1swXSk6ImFzIG5vIGFkYXB0ZXIgc3BlY2lmaWVkIjt0aHJvdyBuZXcgaCgiVGhlcmUgaXMgbm8gc3VpdGFibGUgYWRhcHRlciB0byBkaXNwYXRjaCB0aGUgcmVxdWVzdCAiK2ksIkVSUl9OT1RfU1VQUE9SVCIpfXJldHVybiByfSxhZGFwdGVyczpLQX07ZnVuY3Rpb24gdkEoQSl7aWYoQS5jYW5jZWxUb2tlbiYmQS5jYW5jZWxUb2tlbi50aHJvd0lmUmVxdWVzdGVkKCksQS5zaWduYWwmJkEuc2lnbmFsLmFib3J0ZWQpdGhyb3cgbmV3IEcobnVsbCxBKX1mdW5jdGlvbiBoQShBKXtyZXR1cm4gdkEoQSksQS5oZWFkZXJzPWsuZnJvbShBLmhlYWRlcnMpLEEuZGF0YT1hQS5jYWxsKEEsQS50cmFuc2Zvcm1SZXF1ZXN0KSxbInBvc3QiLCJwdXQiLCJwYXRjaCJdLmluZGV4T2YoQS5tZXRob2QpIT09LTEmJkEuaGVhZGVycy5zZXRDb250ZW50VHlwZSgiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIiwhMSksUUEuZ2V0QWRhcHRlcihBLmFkYXB0ZXJ8fGouYWRhcHRlcikoQSkudGhlbihmdW5jdGlvbihyKXtyZXR1cm4gdkEoQSksci5kYXRhPWFBLmNhbGwoQSxBLnRyYW5zZm9ybVJlc3BvbnNlLHIpLHIuaGVhZGVycz1rLmZyb20oci5oZWFkZXJzKSxyfSxmdW5jdGlvbihyKXtyZXR1cm4gc0Eocil8fCh2QShBKSxyJiZyLnJlc3BvbnNlJiYoci5yZXNwb25zZS5kYXRhPWFBLmNhbGwoQSxBLnRyYW5zZm9ybVJlc3BvbnNlLHIucmVzcG9uc2UpLHIucmVzcG9uc2UuaGVhZGVycz1rLmZyb20oci5yZXNwb25zZS5oZWFkZXJzKSkpLFByb21pc2UucmVqZWN0KHIpfSl9dmFyIG50PUE9PkEgaW5zdGFuY2VvZiBrP0EudG9KU09OKCk6QTtmdW5jdGlvbiB4KEEsZSl7ZT1lfHx7fTtsZXQgdD17fTtmdW5jdGlvbiByKEksZyx1KXtyZXR1cm4gcC5pc1BsYWluT2JqZWN0KEkpJiZwLmlzUGxhaW5PYmplY3QoZyk/cC5tZXJnZS5jYWxsKHtjYXNlbGVzczp1fSxJLGcpOnAuaXNQbGFpbk9iamVjdChnKT9wLm1lcmdlKHt9LGcpOnAuaXNBcnJheShnKT9nLnNsaWNlKCk6Z31mdW5jdGlvbiBuKEksZyx1KXtpZihwLmlzVW5kZWZpbmVkKGcpKXtpZighcC5pc1VuZGVmaW5lZChJKSlyZXR1cm4gcih2b2lkIDAsSSx1KX1lbHNlIHJldHVybiByKEksZyx1KX1mdW5jdGlvbiBvKEksZyl7aWYoIXAuaXNVbmRlZmluZWQoZykpcmV0dXJuIHIodm9pZCAwLGcpfWZ1bmN0aW9uIGkoSSxnKXtpZihwLmlzVW5kZWZpbmVkKGcpKXtpZighcC5pc1VuZGVmaW5lZChJKSlyZXR1cm4gcih2b2lkIDAsSSl9ZWxzZSByZXR1cm4gcih2b2lkIDAsZyl9ZnVuY3Rpb24gbChJLGcsdSl7aWYodSBpbiBlKXJldHVybiByKEksZyk7aWYodSBpbiBBKXJldHVybiByKHZvaWQgMCxJKX1sZXQgYz17dXJsOm8sbWV0aG9kOm8sZGF0YTpvLGJhc2VVUkw6aSx0cmFuc2Zvcm1SZXF1ZXN0OmksdHJhbnNmb3JtUmVzcG9uc2U6aSxwYXJhbXNTZXJpYWxpemVyOmksdGltZW91dDppLHRpbWVvdXRNZXNzYWdlOmksd2l0aENyZWRlbnRpYWxzOmksd2l0aFhTUkZUb2tlbjppLGFkYXB0ZXI6aSxyZXNwb25zZVR5cGU6aSx4c3JmQ29va2llTmFtZTppLHhzcmZIZWFkZXJOYW1lOmksb25VcGxvYWRQcm9ncmVzczppLG9uRG93bmxvYWRQcm9ncmVzczppLGRlY29tcHJlc3M6aSxtYXhDb250ZW50TGVuZ3RoOmksbWF4Qm9keUxlbmd0aDppLGJlZm9yZVJlZGlyZWN0OmksdHJhbnNwb3J0OmksaHR0cEFnZW50OmksaHR0cHNBZ2VudDppLGNhbmNlbFRva2VuOmksc29ja2V0UGF0aDppLHJlc3BvbnNlRW5jb2Rpbmc6aSx2YWxpZGF0ZVN0YXR1czpsLGhlYWRlcnM6KEksZyk9Pm4obnQoSSksbnQoZyksITApfTtyZXR1cm4gcC5mb3JFYWNoKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sQSxlKSksZnVuY3Rpb24oZyl7bGV0IHU9Y1tnXXx8bixmPXUoQVtnXSxlW2ddLGcpO3AuaXNVbmRlZmluZWQoZikmJnUhPT1sfHwodFtnXT1mKX0pLHR9dmFyIHlBPSIxLjYuMiI7dmFyIGpBPXt9O1sib2JqZWN0IiwiYm9vbGVhbiIsIm51bWJlciIsImZ1bmN0aW9uIiwic3RyaW5nIiwic3ltYm9sIl0uZm9yRWFjaCgoQSxlKT0+e2pBW0FdPWZ1bmN0aW9uKHIpe3JldHVybiB0eXBlb2Ygcj09PUF8fCJhIisoZTwxPyJuICI6IiAiKStBfX0pO3ZhciBvdD17fTtqQS50cmFuc2l0aW9uYWw9ZnVuY3Rpb24oZSx0LHIpe2Z1bmN0aW9uIG4obyxpKXtyZXR1cm4iW0F4aW9zIHYiK3lBKyJdIFRyYW5zaXRpb25hbCBvcHRpb24gJyIrbysiJyIraSsocj8iLiAiK3I6IiIpfXJldHVybihvLGksbCk9PntpZihlPT09ITEpdGhyb3cgbmV3IGgobihpLCIgaGFzIGJlZW4gcmVtb3ZlZCIrKHQ/IiBpbiAiK3Q6IiIpKSxoLkVSUl9ERVBSRUNBVEVEKTtyZXR1cm4gdCYmIW90W2ldJiYob3RbaV09ITAsY29uc29sZS53YXJuKG4oaSwiIGhhcyBiZWVuIGRlcHJlY2F0ZWQgc2luY2UgdiIrdCsiIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5lYXIgZnV0dXJlIikpKSxlP2UobyxpLGwpOiEwfX07ZnVuY3Rpb24gcXIoQSxlLHQpe2lmKHR5cGVvZiBBIT0ib2JqZWN0Iil0aHJvdyBuZXcgaCgib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIsaC5FUlJfQkFEX09QVElPTl9WQUxVRSk7bGV0IHI9T2JqZWN0LmtleXMoQSksbj1yLmxlbmd0aDtmb3IoO24tLSA+MDspe2xldCBvPXJbbl0saT1lW29dO2lmKGkpe2xldCBsPUFbb10sYz1sPT09dm9pZCAwfHxpKGwsbyxBKTtpZihjIT09ITApdGhyb3cgbmV3IGgoIm9wdGlvbiAiK28rIiBtdXN0IGJlICIrYyxoLkVSUl9CQURfT1BUSU9OX1ZBTFVFKTtjb250aW51ZX1pZih0IT09ITApdGhyb3cgbmV3IGgoIlVua25vd24gb3B0aW9uICIrbyxoLkVSUl9CQURfT1BUSU9OKX19dmFyIHdBPXthc3NlcnRPcHRpb25zOnFyLHZhbGlkYXRvcnM6akF9O3ZhciBUPXdBLnZhbGlkYXRvcnMsej1jbGFzc3tjb25zdHJ1Y3RvcihlKXt0aGlzLmRlZmF1bHRzPWUsdGhpcy5pbnRlcmNlcHRvcnM9e3JlcXVlc3Q6bmV3IHhBLHJlc3BvbnNlOm5ldyB4QX19cmVxdWVzdChlLHQpe3R5cGVvZiBlPT0ic3RyaW5nIj8odD10fHx7fSx0LnVybD1lKTp0PWV8fHt9LHQ9eCh0aGlzLmRlZmF1bHRzLHQpO2xldHt0cmFuc2l0aW9uYWw6cixwYXJhbXNTZXJpYWxpemVyOm4saGVhZGVyczpvfT10O3IhPT12b2lkIDAmJndBLmFzc2VydE9wdGlvbnMocix7c2lsZW50SlNPTlBhcnNpbmc6VC50cmFuc2l0aW9uYWwoVC5ib29sZWFuKSxmb3JjZWRKU09OUGFyc2luZzpULnRyYW5zaXRpb25hbChULmJvb2xlYW4pLGNsYXJpZnlUaW1lb3V0RXJyb3I6VC50cmFuc2l0aW9uYWwoVC5ib29sZWFuKX0sITEpLG4hPW51bGwmJihwLmlzRnVuY3Rpb24obik/dC5wYXJhbXNTZXJpYWxpemVyPXtzZXJpYWxpemU6bn06d0EuYXNzZXJ0T3B0aW9ucyhuLHtlbmNvZGU6VC5mdW5jdGlvbixzZXJpYWxpemU6VC5mdW5jdGlvbn0sITApKSx0Lm1ldGhvZD0odC5tZXRob2R8fHRoaXMuZGVmYXVsdHMubWV0aG9kfHwiZ2V0IikudG9Mb3dlckNhc2UoKTtsZXQgaT1vJiZwLm1lcmdlKG8uY29tbW9uLG9bdC5tZXRob2RdKTtvJiZwLmZvckVhY2goWyJkZWxldGUiLCJnZXQiLCJoZWFkIiwicG9zdCIsInB1dCIsInBhdGNoIiwiY29tbW9uIl0scz0+e2RlbGV0ZSBvW3NdfSksdC5oZWFkZXJzPWsuY29uY2F0KGksbyk7bGV0IGw9W10sYz0hMDt0aGlzLmludGVyY2VwdG9ycy5yZXF1ZXN0LmZvckVhY2goZnVuY3Rpb24oQyl7dHlwZW9mIEMucnVuV2hlbj09ImZ1bmN0aW9uIiYmQy5ydW5XaGVuKHQpPT09ITF8fChjPWMmJkMuc3luY2hyb25vdXMsbC51bnNoaWZ0KEMuZnVsZmlsbGVkLEMucmVqZWN0ZWQpKX0pO2xldCBJPVtdO3RoaXMuaW50ZXJjZXB0b3JzLnJlc3BvbnNlLmZvckVhY2goZnVuY3Rpb24oQyl7SS5wdXNoKEMuZnVsZmlsbGVkLEMucmVqZWN0ZWQpfSk7bGV0IGcsdT0wLGY7aWYoIWMpe2xldCBzPVtoQS5iaW5kKHRoaXMpLHZvaWQgMF07Zm9yKHMudW5zaGlmdC5hcHBseShzLGwpLHMucHVzaC5hcHBseShzLEkpLGY9cy5sZW5ndGgsZz1Qcm9taXNlLnJlc29sdmUodCk7dTxmOylnPWcudGhlbihzW3UrK10sc1t1KytdKTtyZXR1cm4gZ31mPWwubGVuZ3RoO2xldCBhPXQ7Zm9yKHU9MDt1PGY7KXtsZXQgcz1sW3UrK10sQz1sW3UrK107dHJ5e2E9cyhhKX1jYXRjaChtKXtDLmNhbGwodGhpcyxtKTticmVha319dHJ5e2c9aEEuY2FsbCh0aGlzLGEpfWNhdGNoKHMpe3JldHVybiBQcm9taXNlLnJlamVjdChzKX1mb3IodT0wLGY9SS5sZW5ndGg7dTxmOylnPWcudGhlbihJW3UrK10sSVt1KytdKTtyZXR1cm4gZ31nZXRVcmkoZSl7ZT14KHRoaXMuZGVmYXVsdHMsZSk7bGV0IHQ9SUEoZS5iYXNlVVJMLGUudXJsKTtyZXR1cm4gbkEodCxlLnBhcmFtcyxlLnBhcmFtc1NlcmlhbGl6ZXIpfX07cC5mb3JFYWNoKFsiZGVsZXRlIiwiZ2V0IiwiaGVhZCIsIm9wdGlvbnMiXSxmdW5jdGlvbihlKXt6LnByb3RvdHlwZVtlXT1mdW5jdGlvbih0LHIpe3JldHVybiB0aGlzLnJlcXVlc3QoeChyfHx7fSx7bWV0aG9kOmUsdXJsOnQsZGF0YToocnx8e30pLmRhdGF9KSl9fSk7cC5mb3JFYWNoKFsicG9zdCIsInB1dCIsInBhdGNoIl0sZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChyKXtyZXR1cm4gZnVuY3Rpb24obyxpLGwpe3JldHVybiB0aGlzLnJlcXVlc3QoeChsfHx7fSx7bWV0aG9kOmUsaGVhZGVyczpyP3siQ29udGVudC1UeXBlIjoibXVsdGlwYXJ0L2Zvcm0tZGF0YSJ9Ont9LHVybDpvLGRhdGE6aX0pKX19ei5wcm90b3R5cGVbZV09dCgpLHoucHJvdG90eXBlW2UrIkZvcm0iXT10KCEwKX0pO3ZhciBsQT16O3ZhciBfQT1jbGFzcyBBe2NvbnN0cnVjdG9yKGUpe2lmKHR5cGVvZiBlIT0iZnVuY3Rpb24iKXRocm93IG5ldyBUeXBlRXJyb3IoImV4ZWN1dG9yIG11c3QgYmUgYSBmdW5jdGlvbi4iKTtsZXQgdDt0aGlzLnByb21pc2U9bmV3IFByb21pc2UoZnVuY3Rpb24obyl7dD1vfSk7bGV0IHI9dGhpczt0aGlzLnByb21pc2UudGhlbihuPT57aWYoIXIuX2xpc3RlbmVycylyZXR1cm47bGV0IG89ci5fbGlzdGVuZXJzLmxlbmd0aDtmb3IoO28tLSA+MDspci5fbGlzdGVuZXJzW29dKG4pO3IuX2xpc3RlbmVycz1udWxsfSksdGhpcy5wcm9taXNlLnRoZW49bj0+e2xldCBvLGk9bmV3IFByb21pc2UobD0+e3Iuc3Vic2NyaWJlKGwpLG89bH0pLnRoZW4obik7cmV0dXJuIGkuY2FuY2VsPWZ1bmN0aW9uKCl7ci51bnN1YnNjcmliZShvKX0saX0sZShmdW5jdGlvbihvLGksbCl7ci5yZWFzb258fChyLnJlYXNvbj1uZXcgRyhvLGksbCksdChyLnJlYXNvbikpfSl9dGhyb3dJZlJlcXVlc3RlZCgpe2lmKHRoaXMucmVhc29uKXRocm93IHRoaXMucmVhc29ufXN1YnNjcmliZShlKXtpZih0aGlzLnJlYXNvbil7ZSh0aGlzLnJlYXNvbik7cmV0dXJufXRoaXMuX2xpc3RlbmVycz90aGlzLl9saXN0ZW5lcnMucHVzaChlKTp0aGlzLl9saXN0ZW5lcnM9W2VdfXVuc3Vic2NyaWJlKGUpe2lmKCF0aGlzLl9saXN0ZW5lcnMpcmV0dXJuO2xldCB0PXRoaXMuX2xpc3RlbmVycy5pbmRleE9mKGUpO3QhPT0tMSYmdGhpcy5fbGlzdGVuZXJzLnNwbGljZSh0LDEpfXN0YXRpYyBzb3VyY2UoKXtsZXQgZTtyZXR1cm57dG9rZW46bmV3IEEoZnVuY3Rpb24obil7ZT1ufSksY2FuY2VsOmV9fX0sYXQ9X0E7ZnVuY3Rpb24gekEoQSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiBBLmFwcGx5KG51bGwsdCl9fWZ1bmN0aW9uIFZBKEEpe3JldHVybiBwLmlzT2JqZWN0KEEpJiZBLmlzQXhpb3NFcnJvcj09PSEwfXZhciBaQT17Q29udGludWU6MTAwLFN3aXRjaGluZ1Byb3RvY29sczoxMDEsUHJvY2Vzc2luZzoxMDIsRWFybHlIaW50czoxMDMsT2s6MjAwLENyZWF0ZWQ6MjAxLEFjY2VwdGVkOjIwMixOb25BdXRob3JpdGF0aXZlSW5mb3JtYXRpb246MjAzLE5vQ29udGVudDoyMDQsUmVzZXRDb250ZW50OjIwNSxQYXJ0aWFsQ29udGVudDoyMDYsTXVsdGlTdGF0dXM6MjA3LEFscmVhZHlSZXBvcnRlZDoyMDgsSW1Vc2VkOjIyNixNdWx0aXBsZUNob2ljZXM6MzAwLE1vdmVkUGVybWFuZW50bHk6MzAxLEZvdW5kOjMwMixTZWVPdGhlcjozMDMsTm90TW9kaWZpZWQ6MzA0LFVzZVByb3h5OjMwNSxVbnVzZWQ6MzA2LFRlbXBvcmFyeVJlZGlyZWN0OjMwNyxQZXJtYW5lbnRSZWRpcmVjdDozMDgsQmFkUmVxdWVzdDo0MDAsVW5hdXRob3JpemVkOjQwMSxQYXltZW50UmVxdWlyZWQ6NDAyLEZvcmJpZGRlbjo0MDMsTm90Rm91bmQ6NDA0LE1ldGhvZE5vdEFsbG93ZWQ6NDA1LE5vdEFjY2VwdGFibGU6NDA2LFByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZDo0MDcsUmVxdWVzdFRpbWVvdXQ6NDA4LENvbmZsaWN0OjQwOSxHb25lOjQxMCxMZW5ndGhSZXF1aXJlZDo0MTEsUHJlY29uZGl0aW9uRmFpbGVkOjQxMixQYXlsb2FkVG9vTGFyZ2U6NDEzLFVyaVRvb0xvbmc6NDE0LFVuc3VwcG9ydGVkTWVkaWFUeXBlOjQxNSxSYW5nZU5vdFNhdGlzZmlhYmxlOjQxNixFeHBlY3RhdGlvbkZhaWxlZDo0MTcsSW1BVGVhcG90OjQxOCxNaXNkaXJlY3RlZFJlcXVlc3Q6NDIxLFVucHJvY2Vzc2FibGVFbnRpdHk6NDIyLExvY2tlZDo0MjMsRmFpbGVkRGVwZW5kZW5jeTo0MjQsVG9vRWFybHk6NDI1LFVwZ3JhZGVSZXF1aXJlZDo0MjYsUHJlY29uZGl0aW9uUmVxdWlyZWQ6NDI4LFRvb01hbnlSZXF1ZXN0czo0MjksUmVxdWVzdEhlYWRlckZpZWxkc1Rvb0xhcmdlOjQzMSxVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29uczo0NTEsSW50ZXJuYWxTZXJ2ZXJFcnJvcjo1MDAsTm90SW1wbGVtZW50ZWQ6NTAxLEJhZEdhdGV3YXk6NTAyLFNlcnZpY2VVbmF2YWlsYWJsZTo1MDMsR2F0ZXdheVRpbWVvdXQ6NTA0LEh0dHBWZXJzaW9uTm90U3VwcG9ydGVkOjUwNSxWYXJpYW50QWxzb05lZ290aWF0ZXM6NTA2LEluc3VmZmljaWVudFN0b3JhZ2U6NTA3LExvb3BEZXRlY3RlZDo1MDgsTm90RXh0ZW5kZWQ6NTEwLE5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkOjUxMX07T2JqZWN0LmVudHJpZXMoWkEpLmZvckVhY2goKFtBLGVdKT0+e1pBW2VdPUF9KTt2YXIgc3Q9WkE7ZnVuY3Rpb24gSXQoQSl7bGV0IGU9bmV3IGxBKEEpLHQ9dEEobEEucHJvdG90eXBlLnJlcXVlc3QsZSk7cmV0dXJuIHAuZXh0ZW5kKHQsbEEucHJvdG90eXBlLGUse2FsbE93bktleXM6ITB9KSxwLmV4dGVuZCh0LGUsbnVsbCx7YWxsT3duS2V5czohMH0pLHQuY3JlYXRlPWZ1bmN0aW9uKG4pe3JldHVybiBJdCh4KEEsbikpfSx0fXZhciBiPUl0KGopO2IuQXhpb3M9bEE7Yi5DYW5jZWxlZEVycm9yPUc7Yi5DYW5jZWxUb2tlbj1hdDtiLmlzQ2FuY2VsPXNBO2IuVkVSU0lPTj15QTtiLnRvRm9ybURhdGE9VztiLkF4aW9zRXJyb3I9aDtiLkNhbmNlbD1iLkNhbmNlbGVkRXJyb3I7Yi5hbGw9ZnVuY3Rpb24oZSl7cmV0dXJuIFByb21pc2UuYWxsKGUpfTtiLnNwcmVhZD16QTtiLmlzQXhpb3NFcnJvcj1WQTtiLm1lcmdlQ29uZmlnPXg7Yi5BeGlvc0hlYWRlcnM9aztiLmZvcm1Ub0pTT049QT0+ZEEocC5pc0hUTUxGb3JtKEEpP25ldyBGb3JtRGF0YShBKTpBKTtiLmdldEFkYXB0ZXI9UUEuZ2V0QWRhcHRlcjtiLkh0dHBTdGF0dXNDb2RlPXN0O2IuZGVmYXVsdD1iO3ZhciBIPWI7dmFye0F4aW9zOlBhLEF4aW9zRXJyb3I6eGEsQ2FuY2VsZWRFcnJvcjpXYSxpc0NhbmNlbDpHYSxDYW5jZWxUb2tlbjpUYSxWRVJTSU9OOkxhLGFsbDpKYSxDYW5jZWw6SGEsaXNBeGlvc0Vycm9yOllhLHNwcmVhZDpxYSx0b0Zvcm1EYXRhOkthLEF4aW9zSGVhZGVyczp2YSxIdHRwU3RhdHVzQ29kZTpqYSxmb3JtVG9KU09OOl9hLGdldEFkYXB0ZXI6emEsbWVyZ2VDb25maWc6VmF9PUg7dmFyIGd0PVN5bWJvbCgiQ29tbGluay5wcm94eSIpLEtyPVN5bWJvbCgiQ29tbGluay5lbmRwb2ludCIpLEFlPVN5bWJvbCgiQ29tbGluay5yZWxlYXNlUHJveHkiKSxYQT1TeW1ib2woIkNvbWxpbmsuZmluYWxpemVyIiksYkE9U3ltYm9sKCJDb21saW5rLnRocm93biIpLHV0PUE9PnR5cGVvZiBBPT0ib2JqZWN0IiYmQSE9PW51bGx8fHR5cGVvZiBBPT0iZnVuY3Rpb24iLHZyPXtjYW5IYW5kbGU6QT0+dXQoQSkmJkFbZ3RdLHNlcmlhbGl6ZShBKXtsZXR7cG9ydDE6ZSxwb3J0Mjp0fT1uZXcgTWVzc2FnZUNoYW5uZWw7cmV0dXJuIHB0KEEsZSksW3QsW3RdXX0sZGVzZXJpYWxpemUoQSl7cmV0dXJuIEEuc3RhcnQoKSxlZShBKX19LGpyPXtjYW5IYW5kbGU6QT0+dXQoQSkmJmJBIGluIEEsc2VyaWFsaXplKHt2YWx1ZTpBfSl7bGV0IGU7cmV0dXJuIEEgaW5zdGFuY2VvZiBFcnJvcj9lPXtpc0Vycm9yOiEwLHZhbHVlOnttZXNzYWdlOkEubWVzc2FnZSxuYW1lOkEubmFtZSxzdGFjazpBLnN0YWNrfX06ZT17aXNFcnJvcjohMSx2YWx1ZTpBfSxbZSxbXV19LGRlc2VyaWFsaXplKEEpe3Rocm93IEEuaXNFcnJvcj9PYmplY3QuYXNzaWduKG5ldyBFcnJvcihBLnZhbHVlLm1lc3NhZ2UpLEEudmFsdWUpOkEudmFsdWV9fSxmdD1uZXcgTWFwKFtbInByb3h5Iix2cl0sWyJ0aHJvdyIsanJdXSk7ZnVuY3Rpb24gX3IoQSxlKXtmb3IobGV0IHQgb2YgQSlpZihlPT09dHx8dD09PSIqInx8dCBpbnN0YW5jZW9mIFJlZ0V4cCYmdC50ZXN0KGUpKXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIHB0KEEsZT1nbG9iYWxUaGlzLHQ9WyIqIl0pe2UuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZnVuY3Rpb24gcihuKXtpZighbnx8IW4uZGF0YSlyZXR1cm47aWYoIV9yKHQsbi5vcmlnaW4pKXtjb25zb2xlLndhcm4oYEludmFsaWQgb3JpZ2luICcke24ub3JpZ2lufScgZm9yIGNvbWxpbmsgcHJveHlgKTtyZXR1cm59bGV0e2lkOm8sdHlwZTppLHBhdGg6bH09T2JqZWN0LmFzc2lnbih7cGF0aDpbXX0sbi5kYXRhKSxjPShuLmRhdGEuYXJndW1lbnRMaXN0fHxbXSkubWFwKFkpLEk7dHJ5e2xldCBnPWwuc2xpY2UoMCwtMSkucmVkdWNlKChmLGEpPT5mW2FdLEEpLHU9bC5yZWR1Y2UoKGYsYSk9PmZbYV0sQSk7c3dpdGNoKGkpe2Nhc2UiR0VUIjpJPXU7YnJlYWs7Y2FzZSJTRVQiOmdbbC5zbGljZSgtMSlbMF1dPVkobi5kYXRhLnZhbHVlKSxJPSEwO2JyZWFrO2Nhc2UiQVBQTFkiOkk9dS5hcHBseShnLGMpO2JyZWFrO2Nhc2UiQ09OU1RSVUNUIjp7bGV0IGY9bmV3IHUoLi4uYyk7ST0kcihmKX1icmVhaztjYXNlIkVORFBPSU5UIjp7bGV0e3BvcnQxOmYscG9ydDI6YX09bmV3IE1lc3NhZ2VDaGFubmVsO3B0KEEsYSksST10ZShmLFtmXSl9YnJlYWs7Y2FzZSJSRUxFQVNFIjpJPXZvaWQgMDticmVhaztkZWZhdWx0OnJldHVybn19Y2F0Y2goZyl7ST17dmFsdWU6ZyxbYkFdOjB9fVByb21pc2UucmVzb2x2ZShJKS5jYXRjaChnPT4oe3ZhbHVlOmcsW2JBXTowfSkpLnRoZW4oZz0+e2xldFt1LGZdPVNBKGcpO2UucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LHUpLHtpZDpvfSksZiksaT09PSJSRUxFQVNFIiYmKGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsciksY3QoZSksWEEgaW4gQSYmdHlwZW9mIEFbWEFdPT0iZnVuY3Rpb24iJiZBW1hBXSgpKX0pLmNhdGNoKGc9PntsZXRbdSxmXT1TQSh7dmFsdWU6bmV3IFR5cGVFcnJvcigiVW5zZXJpYWxpemFibGUgcmV0dXJuIHZhbHVlIiksW2JBXTowfSk7ZS5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sdSkse2lkOm99KSxmKX0pfSksZS5zdGFydCYmZS5zdGFydCgpfWZ1bmN0aW9uIHpyKEEpe3JldHVybiBBLmNvbnN0cnVjdG9yLm5hbWU9PT0iTWVzc2FnZVBvcnQifWZ1bmN0aW9uIGN0KEEpe3pyKEEpJiZBLmNsb3NlKCl9ZnVuY3Rpb24gZWUoQSxlKXtyZXR1cm4gJEEoQSxbXSxlKX1mdW5jdGlvbiBEQShBKXtpZihBKXRocm93IG5ldyBFcnJvcigiUHJveHkgaGFzIGJlZW4gcmVsZWFzZWQgYW5kIGlzIG5vdCB1c2VhYmxlIil9ZnVuY3Rpb24gQnQoQSl7cmV0dXJuIFYoQSx7dHlwZToiUkVMRUFTRSJ9KS50aGVuKCgpPT57Y3QoQSl9KX12YXIgRkE9bmV3IFdlYWtNYXAsUkE9IkZpbmFsaXphdGlvblJlZ2lzdHJ5ImluIGdsb2JhbFRoaXMmJm5ldyBGaW5hbGl6YXRpb25SZWdpc3RyeShBPT57bGV0IGU9KEZBLmdldChBKXx8MCktMTtGQS5zZXQoQSxlKSxlPT09MCYmQnQoQSl9KTtmdW5jdGlvbiBWcihBLGUpe2xldCB0PShGQS5nZXQoZSl8fDApKzE7RkEuc2V0KGUsdCksUkEmJlJBLnJlZ2lzdGVyKEEsZSxBKX1mdW5jdGlvbiBacihBKXtSQSYmUkEudW5yZWdpc3RlcihBKX1mdW5jdGlvbiAkQShBLGU9W10sdD1mdW5jdGlvbigpe30pe2xldCByPSExLG49bmV3IFByb3h5KHQse2dldChvLGkpe2lmKERBKHIpLGk9PT1BZSlyZXR1cm4oKT0+e1pyKG4pLEJ0KEEpLHI9ITB9O2lmKGk9PT0idGhlbiIpe2lmKGUubGVuZ3RoPT09MClyZXR1cm57dGhlbjooKT0+bn07bGV0IGw9VihBLHt0eXBlOiJHRVQiLHBhdGg6ZS5tYXAoYz0+Yy50b1N0cmluZygpKX0pLnRoZW4oWSk7cmV0dXJuIGwudGhlbi5iaW5kKGwpfXJldHVybiAkQShBLFsuLi5lLGldKX0sc2V0KG8saSxsKXtEQShyKTtsZXRbYyxJXT1TQShsKTtyZXR1cm4gVihBLHt0eXBlOiJTRVQiLHBhdGg6Wy4uLmUsaV0ubWFwKGc9PmcudG9TdHJpbmcoKSksdmFsdWU6Y30sSSkudGhlbihZKX0sYXBwbHkobyxpLGwpe0RBKHIpO2xldCBjPWVbZS5sZW5ndGgtMV07aWYoYz09PUtyKXJldHVybiBWKEEse3R5cGU6IkVORFBPSU5UIn0pLnRoZW4oWSk7aWYoYz09PSJiaW5kIilyZXR1cm4gJEEoQSxlLnNsaWNlKDAsLTEpKTtsZXRbSSxnXT1sdChsKTtyZXR1cm4gVihBLHt0eXBlOiJBUFBMWSIscGF0aDplLm1hcCh1PT51LnRvU3RyaW5nKCkpLGFyZ3VtZW50TGlzdDpJfSxnKS50aGVuKFkpfSxjb25zdHJ1Y3QobyxpKXtEQShyKTtsZXRbbCxjXT1sdChpKTtyZXR1cm4gVihBLHt0eXBlOiJDT05TVFJVQ1QiLHBhdGg6ZS5tYXAoST0+SS50b1N0cmluZygpKSxhcmd1bWVudExpc3Q6bH0sYykudGhlbihZKX19KTtyZXR1cm4gVnIobixBKSxufWZ1bmN0aW9uIFhyKEEpe3JldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLEEpfWZ1bmN0aW9uIGx0KEEpe2xldCBlPUEubWFwKFNBKTtyZXR1cm5bZS5tYXAodD0+dFswXSksWHIoZS5tYXAodD0+dFsxXSkpXX12YXIgQ3Q9bmV3IFdlYWtNYXA7ZnVuY3Rpb24gdGUoQSxlKXtyZXR1cm4gQ3Quc2V0KEEsZSksQX1mdW5jdGlvbiAkcihBKXtyZXR1cm4gT2JqZWN0LmFzc2lnbihBLHtbZ3RdOiEwfSl9ZnVuY3Rpb24gU0EoQSl7Zm9yKGxldFtlLHRdb2YgZnQpaWYodC5jYW5IYW5kbGUoQSkpe2xldFtyLG5dPXQuc2VyaWFsaXplKEEpO3JldHVyblt7dHlwZToiSEFORExFUiIsbmFtZTplLHZhbHVlOnJ9LG5dfXJldHVyblt7dHlwZToiUkFXIix2YWx1ZTpBfSxDdC5nZXQoQSl8fFtdXX1mdW5jdGlvbiBZKEEpe3N3aXRjaChBLnR5cGUpe2Nhc2UiSEFORExFUiI6cmV0dXJuIGZ0LmdldChBLm5hbWUpLmRlc2VyaWFsaXplKEEudmFsdWUpO2Nhc2UiUkFXIjpyZXR1cm4gQS52YWx1ZX19ZnVuY3Rpb24gVihBLGUsdCl7cmV0dXJuIG5ldyBQcm9taXNlKHI9PntsZXQgbj1BaSgpO0EuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZnVuY3Rpb24gbyhpKXshaS5kYXRhfHwhaS5kYXRhLmlkfHxpLmRhdGEuaWQhPT1ufHwoQS5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIixvKSxyKGkuZGF0YSkpfSksQS5zdGFydCYmQS5zdGFydCgpLEEucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbih7aWQ6bn0sZSksdCl9KX1mdW5jdGlvbiBBaSgpe3JldHVybiBuZXcgQXJyYXkoNCkuZmlsbCgwKS5tYXAoKCk9Pk1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSpOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikudG9TdHJpbmcoMTYpKS5qb2luKCItIil9ZnVuY3Rpb24gZHQoQSl7bGV0IGU9ZWUoQSksdD1BO3JldHVybiB0LndvcmtlclByb3h5PWUsdC5vcmlnaW5hbFRlcm1pbmF0ZT10LnRlcm1pbmF0ZSx0LnRlcm1pbmF0ZT0oKT0+e3Qud29ya2VyUHJveHlbQWVdKCksdC5vcmlnaW5hbFRlcm1pbmF0ZSgpfSx7d29ya2VyUHJveHk6ZSx3b3JrZXI6dH19YXN5bmMgZnVuY3Rpb24gZWkoQSxlKXtsZXQgdDtpZihBIT1udWxsKXtsZXQgaT1BO3JldHVybiBpLndvcmtlclByb3h5IT09dm9pZCAwPyh0PWkud29ya2VyUHJveHkse3dvcmtlclByb3h5OnQsd29ya2VyOml9KTpkdChBKX1sZXQgcj10eXBlb2YgZT4idSI/cS5waXBlbGluZVdvcmtlclVybDplLG49bnVsbCxvPXEud2ViV29ya2Vyc1VybDtpZih0eXBlb2YgbzwidSIpe2NvbnNvbGUud2FybigiaXRrQ29uZmlnIHdlYldvcmtlcnNVcmwgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBwaXBlbGluZVdvcmtlclVybCB3aXRoIHRoZSBmdWxsIHBhdGggdG8gdGhlIHBpcGVsaW5lIHdvcmtlci4iKTtsZXQgaT0ibWluLiIsbD1vO2lmKGwuc3RhcnRzV2l0aCgiaHR0cCIpKXtsZXQgYz1hd2FpdCBILmdldChgJHtsfS9idW5kbGVzL3BpcGVsaW5lLiR7aX13b3JrZXIuanNgLHtyZXNwb25zZVR5cGU6ImJsb2IifSksST1VUkwuY3JlYXRlT2JqZWN0VVJMKGMuZGF0YSk7bj1uZXcgV29ya2VyKEkse3R5cGU6Im1vZHVsZSJ9KX1lbHNlIG49bmV3IFdvcmtlcihgJHtsfS9idW5kbGVzL3BpcGVsaW5lLiR7aX13b3JrZXIuanNgLHt0eXBlOiJtb2R1bGUifSl9ZWxzZSBpZihyPT09bnVsbCluPW5ldyBXb3JrZXIobmV3IFVSTCgiLi93ZWItd29ya2Vycy9pdGstd2FzbS1waXBlbGluZS53b3JrZXIuanMiLGltcG9ydC5tZXRhLnVybCkse3R5cGU6Im1vZHVsZSJ9KTtlbHNlIGlmKHIuc3RhcnRzV2l0aCgiaHR0cCIpKXtsZXQgaT1hd2FpdCBILmdldChyLHtyZXNwb25zZVR5cGU6ImJsb2IifSksbD1VUkwuY3JlYXRlT2JqZWN0VVJMKGkuZGF0YSk7bj1uZXcgV29ya2VyKGwse3R5cGU6Im1vZHVsZSJ9KX1lbHNlIG49bmV3IFdvcmtlcihyLHt0eXBlOiJtb2R1bGUifSk7cmV0dXJuIGR0KG4pfXZhciBFdD1laTt2YXIgdGk7ZnVuY3Rpb24gUXQoKXtyZXR1cm4gdGl9dmFyIHJpO2Z1bmN0aW9uIGh0KCl7cmV0dXJuIHJpfWZ1bmN0aW9uIGlpKEEpe2xldCBlPUEuc2xpY2UoKEEubGFzdEluZGV4T2YoIi4iKS0xPj4+MCkrMik7aWYoZS50b0xvd2VyQ2FzZSgpPT09Imd6Iil7bGV0IHQ9QS5zbGljZSgwLC0zKS5sYXN0SW5kZXhPZigiLiIpO2U9QS5zbGljZSgodC0xPj4+MCkrMil9ZWxzZSBpZihlLnRvTG93ZXJDYXNlKCk9PT0iY2JvciIpe2xldCB0PUEuc2xpY2UoMCwtNSkubGFzdEluZGV4T2YoIi4iKTtlPUEuc2xpY2UoKHQtMT4+PjApKzIpfWVsc2UgaWYoZS50b0xvd2VyQ2FzZSgpPT09InpzdCIpe2xldCB0PUEuc2xpY2UoMCwtMTApLmxhc3RJbmRleE9mKCIuIik7ZT1BLnNsaWNlKCh0LTE+Pj4wKSsyKX1lbHNlIGlmKGUudG9Mb3dlckNhc2UoKT09PSJ6aXAiKXtsZXQgdD1BLnNsaWNlKDAsLTQpLmxhc3RJbmRleE9mKCIuIik7ZT1BLnNsaWNlKCh0LTE+Pj4wKSsyKX1yZXR1cm4gZX12YXIgZ0E9aWk7ZnVuY3Rpb24gbmkoQSl7cmV0dXJuW0EuZGF0YSxBLmRpcmVjdGlvbl19dmFyIHJlPW5pO2Z1bmN0aW9uIG9pKEEpe3JldHVybltBLnBvaW50cyxBLnBvaW50RGF0YSxBLmNlbGxzLEEuY2VsbERhdGFdfXZhciB5dD1vaTthc3luYyBmdW5jdGlvbiBhaShBLGUpe2xldCB0PSJ1bmtub3duIjt0eXBlb2YgQSE9InN0cmluZyI/dD1BLmhyZWY6QS5zdGFydHNXaXRoKCJodHRwIik/dD1BOnQ9YCR7ZX0vJHtBfWAsdC5lbmRzV2l0aCgiLmpzIikmJih0PXQuc3Vic3RyaW5nKDAsdC5sZW5ndGgtMykpLHQuZW5kc1dpdGgoIi53YXNtIikmJih0PXQuc3Vic3RyaW5nKDAsdC5sZW5ndGgtNSkpO2xldCByPWAke3R9Lndhc21gLG89KGF3YWl0IEguZ2V0KHIse3Jlc3BvbnNlVHlwZToiYXJyYXlidWZmZXIifSkpLmRhdGE7cmV0dXJuKGF3YWl0IGltcG9ydChgJHt0fS5qc2ApKS5kZWZhdWx0KHt3YXNtQmluYXJ5Om99KX12YXIgd3Q9YWk7dmFyIER0PWFzeW5jKCk9PldlYkFzc2VtYmx5LnZhbGlkYXRlKG5ldyBVaW50OEFycmF5KFswLDk3LDExNSwxMDksMSwwLDAsMCwxLDUsMSw5NiwwLDEsMTIzLDMsMiwxLDAsMTAsMTAsMSw4LDAsNjUsMCwyNTMsMTUsMjUzLDk4LDExXSkpO3ZhciBSdD10eXBlb2YgZ2xvYmFsVGhpcy5TaGFyZWRBcnJheUJ1ZmZlcj09ImZ1bmN0aW9uIixidD1uZXcgVGV4dEVuY29kZXIsRnQ9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpO2Z1bmN0aW9uIEwoQSxlKXtsZXQgdD17ZmxhZ3M6InIiLGVuY29kaW5nOiJiaW5hcnkifSxyPUEuZnNfb3BlbihlLHQuZmxhZ3MpLG89QS5mc19zdGF0KGUpLnNpemUsaT1udWxsO1J0P2k9bmV3IFNoYXJlZEFycmF5QnVmZmVyKG8pOmk9bmV3IEFycmF5QnVmZmVyKG8pO2xldCBsPW5ldyBVaW50OEFycmF5KGkpO3JldHVybiBBLmZzX3JlYWQocixsLDAsbywwKSxBLmZzX2Nsb3NlKHIpLGx9ZnVuY3Rpb24gU3QoQSxlLHQpe2xldCByPW51bGw7UnQ/cj1uZXcgU2hhcmVkQXJyYXlCdWZmZXIodCk6cj1uZXcgQXJyYXlCdWZmZXIodCk7bGV0IG49bmV3IFVpbnQ4QXJyYXkociksbz1uZXcgVWludDhBcnJheShBLkhFQVBVOC5idWZmZXIsZSx0KTtyZXR1cm4gbi5zZXQobyksbn1mdW5jdGlvbiBSKEEsZSx0LHIpe2xldCBuPTA7cmV0dXJuIGUhPT1udWxsJiYobj1BLmNjYWxsKCJpdGtfd2FzbV9pbnB1dF9hcnJheV9hbGxvYyIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCx0LHIsZS5idWZmZXIuYnl0ZUxlbmd0aF0pLEEuSEVBUFU4LnNldChuZXcgVWludDhBcnJheShlLmJ1ZmZlciksbikpLG59ZnVuY3Rpb24gWihBLGUsdCl7bGV0IHI9SlNPTi5zdHJpbmdpZnkoZSksbj1BLmNjYWxsKCJpdGtfd2FzbV9pbnB1dF9qc29uX2FsbG9jIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLHQsci5sZW5ndGhdKTtBLndyaXRlQXNjaWlUb01lbW9yeShyLG4sITEpfWZ1bmN0aW9uIE4oQSxlLHQscil7bGV0IG49QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2FycmF5X2FkZHJlc3MiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsZSx0XSksbz1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfc2l6ZSIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxlLHRdKSxpPVN0KEEsbixvKTtyZXR1cm4gRihyLGkuYnVmZmVyKX1mdW5jdGlvbiBpZShBLGUpe2xldCB0PUEuY2NhbGwoIml0a193YXNtX291dHB1dF9qc29uX2FkZHJlc3MiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIl0sWzAsZV0pLHI9QS5Bc2NpaVRvU3RyaW5nKHQpO3JldHVybiBKU09OLnBhcnNlKHIpfWZ1bmN0aW9uIHNpKEEsZSx0LHIpe3IhPW51bGwmJnIubGVuZ3RoPjAmJnIuZm9yRWFjaChmdW5jdGlvbihJLGcpe3ZhciB1O3N3aXRjaChJLnR5cGUpe2Nhc2UgQi5UZXh0U3RyZWFtOntsZXQgZj1idC5lbmNvZGUoSS5kYXRhLmRhdGEpLGE9UihBLGYsZywwKSxzPXtzaXplOmYuYnVmZmVyLmJ5dGVMZW5ndGgsZGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke2F9YH07WihBLHMsZyk7YnJlYWt9Y2FzZSBCLkpzb25Db21wYXRpYmxlOntsZXQgZj1idC5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoSS5kYXRhKSksYT1SKEEsZixnLDApLHM9e3NpemU6Zi5idWZmZXIuYnl0ZUxlbmd0aCxkYXRhOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7YX1gfTtaKEEscyxnKTticmVha31jYXNlIEIuQmluYXJ5U3RyZWFtOntsZXQgZj1JLmRhdGEuZGF0YSxhPVIoQSxmLGcsMCkscz17c2l6ZTpmLmJ1ZmZlci5ieXRlTGVuZ3RoLGRhdGE6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHthfWB9O1ooQSxzLGcpO2JyZWFrfWNhc2UgQi5UZXh0RmlsZTp7QS5mc193cml0ZUZpbGUoSS5kYXRhLnBhdGgsSS5kYXRhLmRhdGEpO2JyZWFrfWNhc2UgQi5CaW5hcnlGaWxlOntBLmZzX3dyaXRlRmlsZShJLmRhdGEucGF0aCxJLmRhdGEuZGF0YSk7YnJlYWt9Y2FzZSBCLkltYWdlOntsZXQgZj1JLmRhdGEsYT1SKEEsZi5kYXRhLGcsMCkscz1SKEEsZi5kaXJlY3Rpb24sZywxKSxDPXR5cGVvZigodT1mLm1ldGFkYXRhKT09PW51bGx8fHU9PT12b2lkIDA/dm9pZCAwOnUuZW50cmllcyk8InUiP0pTT04uc3RyaW5naWZ5KEFycmF5LmZyb20oZi5tZXRhZGF0YS5lbnRyaWVzKCkpKToiW10iLG09e2ltYWdlVHlwZTpmLmltYWdlVHlwZSxuYW1lOmYubmFtZSxvcmlnaW46Zi5vcmlnaW4sc3BhY2luZzpmLnNwYWNpbmcsZGlyZWN0aW9uOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7c31gLHNpemU6Zi5zaXplLGRhdGE6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHthfWAsbWV0YWRhdGE6Q307WihBLG0sZyk7YnJlYWt9Y2FzZSBCLk1lc2g6e2xldCBmPUkuZGF0YSxhPVIoQSxmLnBvaW50cyxnLDApLHM9UihBLGYuY2VsbHMsZywxKSxDPVIoQSxmLnBvaW50RGF0YSxnLDIpLG09UihBLGYuY2VsbERhdGEsZywzKSx3PXttZXNoVHlwZTpmLm1lc2hUeXBlLG5hbWU6Zi5uYW1lLG51bWJlck9mUG9pbnRzOmYubnVtYmVyT2ZQb2ludHMscG9pbnRzOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7YX1gLG51bWJlck9mQ2VsbHM6Zi5udW1iZXJPZkNlbGxzLGNlbGxzOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7c31gLGNlbGxCdWZmZXJTaXplOmYuY2VsbEJ1ZmZlclNpemUsbnVtYmVyT2ZQb2ludFBpeGVsczpmLm51bWJlck9mUG9pbnRQaXhlbHMscG9pbnREYXRhOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7Q31gLG51bWJlck9mQ2VsbFBpeGVsczpmLm51bWJlck9mQ2VsbFBpeGVscyxjZWxsRGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke219YH07WihBLHcsZyk7YnJlYWt9Y2FzZSBCLlBvbHlEYXRhOntsZXQgZj1JLmRhdGEsYT1SKEEsZi5wb2ludHMsZywwKSxzPVIoQSxmLnZlcnRpY2VzLGcsMSksQz1SKEEsZi5saW5lcyxnLDIpLG09UihBLGYucG9seWdvbnMsZywzKSx3PVIoQSxmLnRyaWFuZ2xlU3RyaXBzLGcsNCkseT1SKEEsZi5wb2ludERhdGEsZyw1KSxEPVIoQSxmLnBvaW50RGF0YSxnLDYpLGtBPXtwb2x5RGF0YVR5cGU6Zi5wb2x5RGF0YVR5cGUsbmFtZTpmLm5hbWUsbnVtYmVyT2ZQb2ludHM6Zi5udW1iZXJPZlBvaW50cyxwb2ludHM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHthfWAsdmVydGljZXNCdWZmZXJTaXplOmYudmVydGljZXNCdWZmZXJTaXplLHZlcnRpY2VzOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7c31gLGxpbmVzQnVmZmVyU2l6ZTpmLmxpbmVzQnVmZmVyU2l6ZSxsaW5lczpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke0N9YCxwb2x5Z29uc0J1ZmZlclNpemU6Zi5wb2x5Z29uc0J1ZmZlclNpemUscG9seWdvbnM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHttfWAsdHJpYW5nbGVTdHJpcHNCdWZmZXJTaXplOmYudHJpYW5nbGVTdHJpcHNCdWZmZXJTaXplLHRyaWFuZ2xlU3RyaXBzOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7d31gLG51bWJlck9mUG9pbnRQaXhlbHM6Zi5udW1iZXJPZlBvaW50UGl4ZWxzLHBvaW50RGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke3l9YCxudW1iZXJPZkNlbGxQaXhlbHM6Zi5udW1iZXJPZkNlbGxQaXhlbHMsY2VsbERhdGE6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtEfWB9O1ooQSxrQSxnKTticmVha31jYXNlIFUuVGV4dDp7QS5mc193cml0ZUZpbGUoSS5wYXRoLEkuZGF0YSk7YnJlYWt9Y2FzZSBVLkJpbmFyeTp7QS5mc193cml0ZUZpbGUoSS5wYXRoLEkuZGF0YSk7YnJlYWt9Y2FzZSBVLkltYWdlOntsZXQgZj1JLmRhdGEsYT17aW1hZ2VUeXBlOmYuaW1hZ2VUeXBlLG5hbWU6Zi5uYW1lLG9yaWdpbjpmLm9yaWdpbixzcGFjaW5nOmYuc3BhY2luZyxkaXJlY3Rpb246ImRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5wYXRoLGRhdGEvZGlyZWN0aW9uLnJhdyIsc2l6ZTpmLnNpemUsZGF0YToiZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLnBhdGgsZGF0YS9kYXRhLnJhdyJ9O2lmKEEuZnNfbWtkaXJzKGAke0kucGF0aH0vZGF0YWApLEEuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vaW5kZXguanNvbmAsSlNPTi5zdHJpbmdpZnkoYSkpLGYuZGF0YT09PW51bGwpdGhyb3cgRXJyb3IoImltYWdlLmRhdGEgaXMgbnVsbCIpO0EuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vZGF0YS9kYXRhLnJhd2AsbmV3IFVpbnQ4QXJyYXkoZi5kYXRhLmJ1ZmZlcikpLEEuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vZGF0YS9kaXJlY3Rpb24ucmF3YCxuZXcgVWludDhBcnJheShmLmRpcmVjdGlvbi5idWZmZXIpKTticmVha31jYXNlIFUuTWVzaDp7bGV0IGY9SS5kYXRhLGE9e21lc2hUeXBlOmYubWVzaFR5cGUsbmFtZTpmLm5hbWUsbnVtYmVyT2ZQb2ludHM6Zi5udW1iZXJPZlBvaW50cyxwb2ludHM6ImRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5wYXRoLGRhdGEvcG9pbnRzLnJhdyIsbnVtYmVyT2ZQb2ludFBpeGVsczpmLm51bWJlck9mUG9pbnRQaXhlbHMscG9pbnREYXRhOiJkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsucGF0aCxkYXRhL3BvaW50RGF0YS5yYXciLG51bWJlck9mQ2VsbHM6Zi5udW1iZXJPZkNlbGxzLGNlbGxzOiJkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsucGF0aCxkYXRhL2NlbGxzLnJhdyIsbnVtYmVyT2ZDZWxsUGl4ZWxzOmYubnVtYmVyT2ZDZWxsUGl4ZWxzLGNlbGxEYXRhOiJkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsucGF0aCxkYXRhL2NlbGxEYXRhLnJhdyIsY2VsbEJ1ZmZlclNpemU6Zi5jZWxsQnVmZmVyU2l6ZX07aWYoQS5mc19ta2RpcnMoYCR7SS5wYXRofS9kYXRhYCksQS5mc193cml0ZUZpbGUoYCR7SS5wYXRofS9pbmRleC5qc29uYCxKU09OLnN0cmluZ2lmeShhKSksYS5udW1iZXJPZlBvaW50cz4wKXtpZihmLnBvaW50cz09PW51bGwpdGhyb3cgRXJyb3IoIm1lc2gucG9pbnRzIGlzIG51bGwiKTtBLmZzX3dyaXRlRmlsZShgJHtJLnBhdGh9L2RhdGEvcG9pbnRzLnJhd2AsbmV3IFVpbnQ4QXJyYXkoZi5wb2ludHMuYnVmZmVyKSl9aWYoYS5udW1iZXJPZlBvaW50UGl4ZWxzPjApe2lmKGYucG9pbnREYXRhPT09bnVsbCl0aHJvdyBFcnJvcigibWVzaC5wb2ludERhdGEgaXMgbnVsbCIpO0EuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vZGF0YS9wb2ludERhdGEucmF3YCxuZXcgVWludDhBcnJheShmLnBvaW50RGF0YS5idWZmZXIpKX1pZihhLm51bWJlck9mQ2VsbHM+MCl7aWYoZi5jZWxscz09PW51bGwpdGhyb3cgRXJyb3IoIm1lc2guY2VsbHMgaXMgbnVsbCIpO0EuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vZGF0YS9jZWxscy5yYXdgLG5ldyBVaW50OEFycmF5KGYuY2VsbHMuYnVmZmVyKSl9aWYoYS5udW1iZXJPZkNlbGxQaXhlbHM+MCl7aWYoZi5jZWxsRGF0YT09PW51bGwpdGhyb3cgRXJyb3IoIm1lc2guY2VsbERhdGEgaXMgbnVsbCIpO0EuZnNfd3JpdGVGaWxlKGAke0kucGF0aH0vZGF0YS9jZWxsRGF0YS5yYXdgLG5ldyBVaW50OEFycmF5KGYuY2VsbERhdGEuYnVmZmVyKSl9YnJlYWt9ZGVmYXVsdDp0aHJvdyBFcnJvcigiVW5zdXBwb3J0ZWQgaW5wdXQgSW50ZXJmYWNlVHlwZSIpfX0pLEEucmVzZXRNb2R1bGVTdGRvdXQoKSxBLnJlc2V0TW9kdWxlU3RkZXJyKCk7bGV0IG49QS5zdGFja1NhdmUoKSxvPTA7dHJ5e289QS5jYWxsTWFpbihlLnNsaWNlKCkpfWNhdGNoKEkpe3Rocm93IHR5cGVvZiBJPT0ibnVtYmVyIiYmKGNvbnNvbGUubG9nKCJFeGNlcHRpb24gd2hpbGUgcnVubmluZyBwaXBlbGluZToiKSxjb25zb2xlLmxvZygic3Rkb3V0OiIsQS5nZXRNb2R1bGVTdGRvdXQoKSksY29uc29sZS5lcnJvcigic3RkZXJyOiIsQS5nZXRNb2R1bGVTdGRlcnIoKSksdHlwZW9mIEEuZ2V0RXhjZXB0aW9uTWVzc2FnZTwidSI/Y29uc29sZS5lcnJvcigiZXhjZXB0aW9uOiIsQS5nZXRFeGNlcHRpb25NZXNzYWdlKEkpKTpjb25zb2xlLmVycm9yKCJCdWlsZCBtb2R1bGUgaW4gRGVidWcgbW9kZSBmb3IgZXhjZXB0aW9uIG1lc3NhZ2UgaW5mb3JtYXRpb24uIikpLEl9ZmluYWxseXtBLnN0YWNrUmVzdG9yZShuKX1sZXQgaT1BLmdldE1vZHVsZVN0ZG91dCgpLGw9QS5nZXRNb2R1bGVTdGRlcnIoKSxjPVtdO3JldHVybiB0IT1udWxsJiZ0Lmxlbmd0aD4wJiZvPT09MCYmdC5mb3JFYWNoKGZ1bmN0aW9uKEksZyl7bGV0IHU9bnVsbDtzd2l0Y2goSS50eXBlKXtjYXNlIEIuVGV4dFN0cmVhbTp7bGV0IGE9QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2FycmF5X2FkZHJlc3MiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsZywwXSkscz1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfc2l6ZSIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxnLDBdKSxDPW5ldyBVaW50OEFycmF5KEEuSEVBUFU4LmJ1ZmZlcixhLHMpO3U9e2RhdGE6RnQuZGVjb2RlKEMpfTticmVha31jYXNlIEIuSnNvbkNvbXBhdGlibGU6e2xldCBhPUEuY2NhbGwoIml0a193YXNtX291dHB1dF9hcnJheV9hZGRyZXNzIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLGcsMF0pLHM9QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2FycmF5X3NpemUiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsZywwXSksQz1uZXcgVWludDhBcnJheShBLkhFQVBVOC5idWZmZXIsYSxzKTt1PUpTT04ucGFyc2UoRnQuZGVjb2RlKEMpKTticmVha31jYXNlIEIuQmluYXJ5U3RyZWFtOntsZXQgYT1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfYWRkcmVzcyIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxnLDBdKSxzPUEuY2NhbGwoIml0a193YXNtX291dHB1dF9hcnJheV9zaXplIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLGcsMF0pO3U9e2RhdGE6U3QoQSxhLHMpfTticmVha31jYXNlIEIuVGV4dEZpbGU6e3U9e3BhdGg6SS5kYXRhLnBhdGgsZGF0YTpBLmZzX3JlYWRGaWxlKEkuZGF0YS5wYXRoLHtlbmNvZGluZzoidXRmOCJ9KX07YnJlYWt9Y2FzZSBCLkJpbmFyeUZpbGU6e3U9e3BhdGg6SS5kYXRhLnBhdGgsZGF0YTpMKEEsSS5kYXRhLnBhdGgpfTticmVha31jYXNlIEIuSW1hZ2U6e2xldCBhPWllKEEsZyk7YS5kYXRhPU4oQSxnLDAsYS5pbWFnZVR5cGUuY29tcG9uZW50VHlwZSksYS5kaXJlY3Rpb249TihBLGcsMSxKLkZsb2F0NjQpLGEubWV0YWRhdGE9bmV3IE1hcChhLm1ldGFkYXRhKSx1PWE7YnJlYWt9Y2FzZSBCLk1lc2g6e2xldCBhPWllKEEsZyk7YS5udW1iZXJPZlBvaW50cz4wP2EucG9pbnRzPU4oQSxnLDAsYS5tZXNoVHlwZS5wb2ludENvbXBvbmVudFR5cGUpOmEucG9pbnRzPUYoYS5tZXNoVHlwZS5wb2ludENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKSxhLm51bWJlck9mQ2VsbHM+MD9hLmNlbGxzPU4oQSxnLDEsYS5tZXNoVHlwZS5jZWxsQ29tcG9uZW50VHlwZSk6YS5jZWxscz1GKGEubWVzaFR5cGUuY2VsbENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKSxhLm51bWJlck9mUG9pbnRQaXhlbHM+MD9hLnBvaW50RGF0YT1OKEEsZywyLGEubWVzaFR5cGUucG9pbnRQaXhlbENvbXBvbmVudFR5cGUpOmEucG9pbnREYXRhPUYoYS5tZXNoVHlwZS5wb2ludFBpeGVsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpLGEubnVtYmVyT2ZDZWxsUGl4ZWxzPjA/YS5jZWxsRGF0YT1OKEEsZywzLGEubWVzaFR5cGUuY2VsbFBpeGVsQ29tcG9uZW50VHlwZSk6YS5jZWxsRGF0YT1GKGEubWVzaFR5cGUuY2VsbFBpeGVsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpLHU9YTticmVha31jYXNlIEIuUG9seURhdGE6e2xldCBhPWllKEEsZyk7YS5udW1iZXJPZlBvaW50cz4wP2EucG9pbnRzPU4oQSxnLDAsSi5GbG9hdDMyKTphLnBvaW50cz1uZXcgRmxvYXQzMkFycmF5LGEudmVydGljZXNCdWZmZXJTaXplPjA/YS52ZXJ0aWNlcz1OKEEsZywxLE8uVUludDMyKTphLnZlcnRpY2VzPW5ldyBVaW50MzJBcnJheSxhLmxpbmVzQnVmZmVyU2l6ZT4wP2EubGluZXM9TihBLGcsMixPLlVJbnQzMik6YS5saW5lcz1uZXcgVWludDMyQXJyYXksYS5wb2x5Z29uc0J1ZmZlclNpemU+MD9hLnBvbHlnb25zPU4oQSxnLDMsTy5VSW50MzIpOmEucG9seWdvbnM9bmV3IFVpbnQzMkFycmF5LGEudHJpYW5nbGVTdHJpcHNCdWZmZXJTaXplPjA/YS50cmlhbmdsZVN0cmlwcz1OKEEsZyw0LE8uVUludDMyKTphLnRyaWFuZ2xlU3RyaXBzPW5ldyBVaW50MzJBcnJheSxhLm51bWJlck9mUG9pbnRQaXhlbHM+MD9hLnBvaW50RGF0YT1OKEEsZyw1LGEucG9seURhdGFUeXBlLnBvaW50UGl4ZWxDb21wb25lbnRUeXBlKTphLnBvaW50RGF0YT1GKGEucG9seURhdGFUeXBlLnBvaW50UGl4ZWxDb21wb25lbnRUeXBlLG5ldyBBcnJheUJ1ZmZlcigwKSksYS5udW1iZXJPZkNlbGxQaXhlbHM+MD9hLmNlbGxEYXRhPU4oQSxnLDYsYS5wb2x5RGF0YVR5cGUuY2VsbFBpeGVsQ29tcG9uZW50VHlwZSk6YS5jZWxsRGF0YT1GKGEucG9seURhdGFUeXBlLmNlbGxQaXhlbENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKSx1PWE7YnJlYWt9Y2FzZSBVLlRleHQ6e2lmKHR5cGVvZiBJLnBhdGg+InUiKXRocm93IG5ldyBFcnJvcigib3V0cHV0LnBhdGggbm90IGRlZmluZWQiKTt1PUEuZnNfcmVhZEZpbGUoSS5wYXRoLHtlbmNvZGluZzoidXRmOCJ9KTticmVha31jYXNlIFUuQmluYXJ5OntpZih0eXBlb2YgSS5wYXRoPiJ1Iil0aHJvdyBuZXcgRXJyb3IoIm91dHB1dC5wYXRoIG5vdCBkZWZpbmVkIik7dT1MKEEsSS5wYXRoKTticmVha31jYXNlIFUuSW1hZ2U6e2lmKHR5cGVvZiBJLnBhdGg+InUiKXRocm93IG5ldyBFcnJvcigib3V0cHV0LnBhdGggbm90IGRlZmluZWQiKTtsZXQgYT1BLmZzX3JlYWRGaWxlKGAke0kucGF0aH0vaW5kZXguanNvbmAse2VuY29kaW5nOiJ1dGY4In0pLHM9SlNPTi5wYXJzZShhKSxDPUwoQSxgJHtJLnBhdGh9L2RhdGEvZGF0YS5yYXdgKTtzLmRhdGE9RihzLmltYWdlVHlwZS5jb21wb25lbnRUeXBlLEMuYnVmZmVyKTtsZXQgbT1MKEEsYCR7SS5wYXRofS9kYXRhL2RpcmVjdGlvbi5yYXdgKTtzLmRpcmVjdGlvbj1GKEouRmxvYXQ2NCxtLmJ1ZmZlciksdT1zO2JyZWFrfWNhc2UgVS5NZXNoOntpZih0eXBlb2YgSS5wYXRoPiJ1Iil0aHJvdyBuZXcgRXJyb3IoIm91dHB1dC5wYXRoIG5vdCBkZWZpbmVkIik7bGV0IGE9QS5mc19yZWFkRmlsZShgJHtJLnBhdGh9L2luZGV4Lmpzb25gLHtlbmNvZGluZzoidXRmOCJ9KSxzPUpTT04ucGFyc2UoYSk7aWYocy5udW1iZXJPZlBvaW50cz4wKXtsZXQgQz1MKEEsYCR7SS5wYXRofS9kYXRhL3BvaW50cy5yYXdgKTtzLnBvaW50cz1GKHMubWVzaFR5cGUucG9pbnRDb21wb25lbnRUeXBlLEMuYnVmZmVyKX1lbHNlIHMucG9pbnRzPUYocy5tZXNoVHlwZS5wb2ludENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKTtpZihzLm51bWJlck9mUG9pbnRQaXhlbHM+MCl7bGV0IEM9TChBLGAke0kucGF0aH0vZGF0YS9wb2ludERhdGEucmF3YCk7cy5wb2ludERhdGE9RihzLm1lc2hUeXBlLnBvaW50UGl4ZWxDb21wb25lbnRUeXBlLEMuYnVmZmVyKX1lbHNlIHMucG9pbnREYXRhPUYocy5tZXNoVHlwZS5wb2ludFBpeGVsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpO2lmKHMubnVtYmVyT2ZDZWxscz4wKXtsZXQgQz1MKEEsYCR7SS5wYXRofS9kYXRhL2NlbGxzLnJhd2ApO3MuY2VsbHM9RihzLm1lc2hUeXBlLmNlbGxDb21wb25lbnRUeXBlLEMuYnVmZmVyKX1lbHNlIHMuY2VsbHM9RihzLm1lc2hUeXBlLmNlbGxDb21wb25lbnRUeXBlLG5ldyBBcnJheUJ1ZmZlcigwKSk7aWYocy5udW1iZXJPZkNlbGxQaXhlbHM+MCl7bGV0IEM9TChBLGAke0kucGF0aH0vZGF0YS9jZWxsRGF0YS5yYXdgKTtzLmNlbGxEYXRhPUYocy5tZXNoVHlwZS5jZWxsUGl4ZWxDb21wb25lbnRUeXBlLEMuYnVmZmVyKX1lbHNlIHMuY2VsbERhdGE9RihzLm1lc2hUeXBlLmNlbGxQaXhlbENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKTt1PXM7YnJlYWt9ZGVmYXVsdDp0aHJvdyBFcnJvcigiVW5zdXBwb3J0ZWQgb3V0cHV0IEludGVyZmFjZVR5cGUiKX1sZXQgZj17dHlwZTpJLnR5cGUsZGF0YTp1fTtjLnB1c2goZil9KSx7cmV0dXJuVmFsdWU6byxzdGRvdXQ6aSxzdGRlcnI6bCxvdXRwdXRzOmN9fXZhciBrdD1zaTt2YXIgbmU9bmV3IE1hcDthc3luYyBmdW5jdGlvbiBJaShBKXtsZXQgZT1BLHQ9QTtpZih0eXBlb2YgQSE9InN0cmluZyImJihlPW5ldyBVUkwoQS5ocmVmKSx0PWUuaHJlZiksbmUuaGFzKHQpKXJldHVybiBuZS5nZXQodCk7e2xldCByPWF3YWl0IHd0KEEscS5waXBlbGluZXNVcmwpO3JldHVybiBuZS5zZXQodCxyKSxyfX1hc3luYyBmdW5jdGlvbiBsaShBLGUsdCxyLG4sbyl7dmFyIGksbDtpZighYXdhaXQgRHQoKSl7bGV0IHk9IldlYkFzc2VtYmx5IFNJTUQgc3VwcG9ydCBpcyByZXF1aXJlZCAtLSBwbGVhc2UgdXBkYXRlIHlvdXIgYnJvd3Nlci4iO3Rocm93IGFsZXJ0KHkpLG5ldyBFcnJvcih5KX1pZihBPT09ITEpe2xldCB5PWF3YWl0IElpKGUudG9TdHJpbmcoKSk7cmV0dXJuIGt0KHksdCxyLG4pfWxldCBjPUEsST0oaT1vPy5waXBlbGluZVdvcmtlclVybCkhPT1udWxsJiZpIT09dm9pZCAwP2k6bnVsbCxnPXR5cGVvZiBJIT0ic3RyaW5nIiYmdHlwZW9mIEk/LmhyZWY8InUiP0kuaHJlZjpJLHt3b3JrZXJQcm94eTp1LHdvcmtlcjpmfT1hd2FpdCBFdChjLGcpO2M9ZjtsZXQgYT1bXTtuIT1udWxsJiZuLmxlbmd0aD4wJiZuLmZvckVhY2goZnVuY3Rpb24oeSl7aWYoeS50eXBlPT09Qi5CaW5hcnlTdHJlYW0pe2xldCBEPXkuZGF0YS5kYXRhO2EucHVzaChEKX1lbHNlIGlmKHkudHlwZT09PUIuQmluYXJ5RmlsZSl7bGV0IEQ9eS5kYXRhLmRhdGE7YS5wdXNoKEQpfWVsc2UgaWYoeS50eXBlPT09Qi5JbWFnZSl7bGV0IEQ9eS5kYXRhO2lmKEQuZGF0YT09PW51bGwpdGhyb3cgRXJyb3IoImltYWdlIGRhdGEgY2Fubm90IGJlIG51bGwiKTthLnB1c2goLi4ucmUoRCkpfWVsc2UgaWYoeS50eXBlPT09VS5CaW5hcnkpYS5wdXNoKHkuZGF0YSk7ZWxzZSBpZih5LnR5cGU9PT1VLkltYWdlKXtsZXQgRD15LmRhdGE7aWYoRC5kYXRhPT09bnVsbCl0aHJvdyBFcnJvcigiaW1hZ2UgZGF0YSBjYW5ub3QgYmUgbnVsbCIpO2EucHVzaCguLi5yZShEKSl9ZWxzZSBpZih5LnR5cGU9PT1VLk1lc2gpe2xldCBEPXkuZGF0YTthLnB1c2goLi4ueXQoRCkpfX0pO2xldCBzPShsPW8/LnBpcGVsaW5lQmFzZVVybCkhPT1udWxsJiZsIT09dm9pZCAwP2w6InBpcGVsaW5lc1VybCIsQz10eXBlb2YgcyE9InN0cmluZyImJnR5cGVvZiBzPy5ocmVmPCJ1Ij9zLmhyZWY6cyxtPW4hPW51bGw/dGUobixSZShhKSk6bnVsbCx3PWF3YWl0IHUucnVuUGlwZWxpbmUocSxlLnRvU3RyaW5nKCksQyx0LHIsbSk7cmV0dXJue3JldHVyblZhbHVlOncucmV0dXJuVmFsdWUsc3Rkb3V0Oncuc3Rkb3V0LHN0ZGVycjp3LnN0ZGVycixvdXRwdXRzOncub3V0cHV0cyx3ZWJXb3JrZXI6Y319dmFyIGQ9bGk7dmFyIE90PXtuYW1lOiJAaXRrLXdhc20vbWVzaC1pbyIsdmVyc2lvbjoiMC4xLjAiLGRlc2NyaXB0aW9uOiJJbnB1dCBhbmQgb3V0cHV0IGZvciBzY2llbnRpZmljIGFuZCBtZWRpY2FsIGltYWdlIGZpbGUgZm9ybWF0cy4iLHR5cGU6Im1vZHVsZSIsbW9kdWxlOiIuL2Rpc3QvaW5kZXguanMiLHR5cGVzOiIuL2Rpc3QvaW5kZXguZC50cyIsZXhwb3J0czp7Ii4iOnt0eXBlczoiLi9kaXN0L2luZGV4LmQudHMiLGJyb3dzZXI6Ii4vZGlzdC9pbmRleC5qcyIsbm9kZToiLi9kaXN0L2luZGV4LW5vZGUuanMiLGRlZmF1bHQ6Ii4vZGlzdC9pbmRleC5qcyJ9fSxzY3JpcHRzOntzdGFydDoibnBtIHJ1biBjb3B5U2hvZWxhY2VBc3NldHMgJiYgdml0ZSIsdGVzdDoibnBtIHJ1biB0ZXN0Om5vZGUgJiYgbnBtIHJ1biB0ZXN0OmJyb3dzZXIiLCJ0ZXN0Om5vZGUiOiJhdmEiLCJ0ZXN0OmJyb3dzZXIiOiJucG0gcnVuIHRlc3Q6YnJvd3NlcjpjaHJvbWUgJiYgbnBtIHJ1biB0ZXN0OmJyb3dzZXI6ZmlyZWZveCIsInRlc3Q6YnJvd3NlcjpmaXJlZm94Ijoic3RhcnQtc2VydmVyLWFuZC10ZXN0IHN0YXJ0IGh0dHAtZ2V0Oi8vbG9jYWxob3N0OjUxNzMgY3lwcmVzczpydW5GaXJlZm94IiwidGVzdDpicm93c2VyOmNocm9tZSI6InN0YXJ0LXNlcnZlci1hbmQtdGVzdCBzdGFydCBodHRwLWdldDovL2xvY2FsaG9zdDo1MTczIGN5cHJlc3M6cnVuQ2hyb21lIiwidGVzdDpicm93c2VyOmRlYnVnIjoic3RhcnQtc2VydmVyLWFuZC10ZXN0IHN0YXJ0IGh0dHAtZ2V0Oi8vbG9jYWxob3N0OjUxNzMgY3lwcmVzczpvcGVuIiwiY3lwcmVzczpvcGVuIjoibnB4IGN5cHJlc3Mgb3BlbiIsImN5cHJlc3M6cnVuQ2hyb21lIjoibnB4IGN5cHJlc3MgcnVuIC0tYnJvd3NlciBjaHJvbWUiLCJjeXByZXNzOnJ1bkZpcmVmb3giOiJucHggY3lwcmVzcyBydW4gLS1icm93c2VyIGZpcmVmb3giLGJ1aWxkOiJucG0gcnVuIGJ1aWxkOnRzYyAmJiBucG0gcnVuIGJ1aWxkOmJyb3dzZXI6d29ya2VyRW1iZWRkZWQgJiYgbnBtIHJ1biBidWlsZDpicm93c2VyOndvcmtlckVtYmVkZGVkTWluICYmIG5wbSBydW4gYnVpbGQ6ZGVtbyIsImJ1aWxkOmJyb3dzZXI6d29ya2VyRW1iZWRkZWQiOiJlc2J1aWxkIC0tbG9hZGVyOi53b3JrZXIuanM9ZGF0YXVybCAtLWJ1bmRsZSAtLWZvcm1hdD1lc20gLS1vdXRmaWxlPS4vZGlzdC9idW5kbGUvaW5kZXgtd29ya2VyLWVtYmVkZGVkLmpzIC4vc3JjL2luZGV4LXdvcmtlci1lbWJlZGRlZC50cyIsImJ1aWxkOmJyb3dzZXI6d29ya2VyRW1iZWRkZWRNaW4iOiJlc2J1aWxkIC0tbWluaWZ5IC0tbG9hZGVyOi53b3JrZXIuanM9ZGF0YXVybCAtLWJ1bmRsZSAtLWZvcm1hdD1lc20gLS1vdXRmaWxlPS4vZGlzdC9idW5kbGUvaW5kZXgtd29ya2VyLWVtYmVkZGVkLm1pbi5qcyAuL3NyYy9pbmRleC13b3JrZXItZW1iZWRkZWQubWluLnRzIiwiYnVpbGQ6dHNjIjoidHNjIC0tcHJldHR5Iixjb3B5U2hvZWxhY2VBc3NldHM6InNoeCBta2RpciAtcCB0ZXN0L2Jyb3dzZXIvZGVtby1hcHAvcHVibGljICYmIHNoeCBjcCAtciBub2RlX21vZHVsZXMvQHNob2VsYWNlLXN0eWxlL3Nob2VsYWNlL2Rpc3QvYXNzZXRzIHRlc3QvYnJvd3Nlci9kZW1vLWFwcC9wdWJsaWMvIiwiYnVpbGQ6ZGVtbyI6Im5wbSBydW4gY29weVNob2VsYWNlQXNzZXRzICYmIHZpdGUgYnVpbGQifSxrZXl3b3JkczpbIml0ayIsIndhc20iLCJ3ZWJhc3NlbWJseSIsIndhc2kiXSxhdXRob3I6IiIsbGljZW5zZToiQXBhY2hlLTIuMCIsZGVwZW5kZW5jaWVzOnsiaXRrLXdhc20iOiJeMS4wLjAtYi4xNTQifSxkZXZEZXBlbmRlbmNpZXM6eyJAaXRrLXdhc20vaW1hZ2UtaW8iOiJeMC4yLjAiLCJAc2hvZWxhY2Utc3R5bGUvc2hvZWxhY2UiOiJeMi41LjIiLCJAdHlwZXMvbWltZS10eXBlcyI6Il4yLjEuNCIsIkB0eXBlcy9ub2RlIjoiXjIwLjIuNSIsYXZhOiJeNS4zLjEiLGN5cHJlc3M6Il4xMy42LjAiLGVzYnVpbGQ6Il4wLjE5LjUiLHNoeDoiXjAuMy40Iiwic3RhcnQtc2VydmVyLWFuZC10ZXN0IjoiXjIuMC4zIix0eXBlc2NyaXB0OiJeNS4wLjQiLHZpdGU6Il40LjUuMCIsInZpdGUtcGx1Z2luLXN0YXRpYy1jb3B5IjoiXjAuMTcuMCJ9LHJlcG9zaXRvcnk6e3R5cGU6ImdpdCIsdXJsOiJodHRwczovL2dpdGh1Yi5jb20vSW5zaWdodFNvZnR3YXJlQ29uc29ydGl1bS9pdGstd2FzbSJ9LGF2YTp7ZmlsZXM6WyJ0ZXN0L25vZGUvKiovKiIsIiF0ZXN0L25vZGUvY29tbW9uLmpzIl19fTt2YXIgb2UsdWk9YGh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQGl0ay13YXNtL21lc2gtaW9AJHtPdC52ZXJzaW9ufS9kaXN0L3BpcGVsaW5lc2A7ZnVuY3Rpb24gUHMoQSl7b2U9QX1mdW5jdGlvbiBFKCl7aWYodHlwZW9mIG9lPCJ1IilyZXR1cm4gb2U7bGV0IEE9aHQoKTtyZXR1cm4gdHlwZW9mIEE8InUiP0E6dWl9dmFyIGFlLGZpPW51bGw7ZnVuY3Rpb24gVXQoQSl7YWU9QX1mdW5jdGlvbiBRKCl7aWYodHlwZW9mIGFlPCJ1IilyZXR1cm4gYWU7bGV0IEE9UXQoKTtyZXR1cm4gdHlwZW9mIEE8InUiP0E6Zml9dmFyIHBpPW5ldyBNYXAoW10pLFg9cGk7dmFyIGNpPW5ldyBNYXAoW1sidnRrIiwidnRrIl0sWyJieXUiLCJieXUiXSxbImZzYSIsImZyZWUtc3VyZmVyLWFzY2lpIl0sWyJmc2IiLCJmcmVlLXN1cmZlci1iaW5hcnkiXSxbIm9iaiIsIm9iaiJdLFsib2ZmIiwib2ZmIl0sWyJzdGwiLCJzdGwiXSxbInN3YyIsInN3YyJdLFsiaXdtIiwid2FzbSJdLFsiaXdtLmNib3IiLCJ3YXNtIl0sWyJpd20uY2Jvci56c3QiLCJ3YXNtLXpzdGQiXV0pLCQ9Y2k7YXN5bmMgZnVuY3Rpb24gQmkoQSxlLHQ9e30pe2xldCByPVt7dHlwZTpCLkpzb25Db21wYXRpYmxlfSx7dHlwZTpCLk1lc2h9XSxuPWU7aWYoZSBpbnN0YW5jZW9mIEZpbGUpe2xldCBtPWF3YWl0IGUuYXJyYXlCdWZmZXIoKTtuPXtwYXRoOmUubmFtZSxkYXRhOm5ldyBVaW50OEFycmF5KG0pfX1sZXQgbz1be3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6bn1dLGk9W10sbD1uLnBhdGg7aS5wdXNoKGwpO2xldCBjPSIwIjtpLnB1c2goYyk7bGV0IEk9IjEiO2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHQuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmdC5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5Iik7bGV0IGc9InZ0ay1wb2x5LWRhdGEtcmVhZC1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGkscixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFJlYWQ6c1swXT8uZGF0YSxtZXNoOnNbMV0/LmRhdGF9fXZhciBzZT1CaTthc3luYyBmdW5jdGlvbiBDaShBLGUsdCxyPXt9KXtsZXQgbj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6e3BhdGg6dCxkYXRhOm5ldyBVaW50OEFycmF5fX1dLG89W3t0eXBlOkIuTWVzaCxkYXRhOmV9XSxpPVtdLGw9IjAiO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPXQ7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2Ygci5pbmZvcm1hdGlvbk9ubHk8InUiJiZyLmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKSx0eXBlb2Ygci51c2VDb21wcmVzc2lvbjwidSImJnIudXNlQ29tcHJlc3Npb24mJmkucHVzaCgiLS11c2UtY29tcHJlc3Npb24iKSx0eXBlb2Ygci5iaW5hcnlGaWxlVHlwZTwidSImJnIuYmluYXJ5RmlsZVR5cGUmJmkucHVzaCgiLS1iaW5hcnktZmlsZS10eXBlIik7bGV0IGc9InZ0ay1wb2x5LWRhdGEtd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBJZT1DaTthc3luYyBmdW5jdGlvbiBtaShBLGUsdD17fSl7bGV0IHI9W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuTWVzaH1dLG49ZTtpZihlIGluc3RhbmNlb2YgRmlsZSl7bGV0IG09YXdhaXQgZS5hcnJheUJ1ZmZlcigpO249e3BhdGg6ZS5uYW1lLGRhdGE6bmV3IFVpbnQ4QXJyYXkobSl9fWxldCBvPVt7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTpufV0saT1bXSxsPW4ucGF0aDtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST0iMSI7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2YgdC5pbmZvcm1hdGlvbk9ubHk8InUiJiZ0LmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKTtsZXQgZz0ib2JqLXJlYWQtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLHIsbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRSZWFkOnNbMF0/LmRhdGEsbWVzaDpzWzFdPy5kYXRhfX12YXIgbGU9bWk7YXN5bmMgZnVuY3Rpb24gZGkoQSxlLHQscj17fSl7bGV0IG49W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOntwYXRoOnQsZGF0YTpuZXcgVWludDhBcnJheX19XSxvPVt7dHlwZTpCLk1lc2gsZGF0YTplfV0saT1bXSxsPSIwIjtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST10O2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHIuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmci5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5IiksdHlwZW9mIHIudXNlQ29tcHJlc3Npb248InUiJiZyLnVzZUNvbXByZXNzaW9uJiZpLnB1c2goIi0tdXNlLWNvbXByZXNzaW9uIiksdHlwZW9mIHIuYmluYXJ5RmlsZVR5cGU8InUiJiZyLmJpbmFyeUZpbGVUeXBlJiZpLnB1c2goIi0tYmluYXJ5LWZpbGUtdHlwZSIpO2xldCBnPSJvYmotd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBnZT1kaTthc3luYyBmdW5jdGlvbiBFaShBLGUsdD17fSl7bGV0IHI9W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuTWVzaH1dLG49ZTtpZihlIGluc3RhbmNlb2YgRmlsZSl7bGV0IG09YXdhaXQgZS5hcnJheUJ1ZmZlcigpO249e3BhdGg6ZS5uYW1lLGRhdGE6bmV3IFVpbnQ4QXJyYXkobSl9fWxldCBvPVt7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTpufV0saT1bXSxsPW4ucGF0aDtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST0iMSI7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2YgdC5pbmZvcm1hdGlvbk9ubHk8InUiJiZ0LmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKTtsZXQgZz0ic3RsLXJlYWQtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLHIsbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRSZWFkOnNbMF0/LmRhdGEsbWVzaDpzWzFdPy5kYXRhfX12YXIgdWU9RWk7YXN5bmMgZnVuY3Rpb24gUWkoQSxlLHQscj17fSl7bGV0IG49W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOntwYXRoOnQsZGF0YTpuZXcgVWludDhBcnJheX19XSxvPVt7dHlwZTpCLk1lc2gsZGF0YTplfV0saT1bXSxsPSIwIjtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST10O2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHIuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmci5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5IiksdHlwZW9mIHIudXNlQ29tcHJlc3Npb248InUiJiZyLnVzZUNvbXByZXNzaW9uJiZpLnB1c2goIi0tdXNlLWNvbXByZXNzaW9uIiksdHlwZW9mIHIuYmluYXJ5RmlsZVR5cGU8InUiJiZyLmJpbmFyeUZpbGVUeXBlJiZpLnB1c2goIi0tYmluYXJ5LWZpbGUtdHlwZSIpO2xldCBnPSJzdGwtd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBmZT1RaTthc3luYyBmdW5jdGlvbiBoaShBLGUsdD17fSl7bGV0IHI9W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuTWVzaH1dLG49ZTtpZihlIGluc3RhbmNlb2YgRmlsZSl7bGV0IG09YXdhaXQgZS5hcnJheUJ1ZmZlcigpO249e3BhdGg6ZS5uYW1lLGRhdGE6bmV3IFVpbnQ4QXJyYXkobSl9fWxldCBvPVt7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTpufV0saT1bXSxsPW4ucGF0aDtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST0iMSI7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2YgdC5pbmZvcm1hdGlvbk9ubHk8InUiJiZ0LmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKTtsZXQgZz0ib2ZmLXJlYWQtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLHIsbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRSZWFkOnNbMF0/LmRhdGEsbWVzaDpzWzFdPy5kYXRhfX12YXIgcGU9aGk7YXN5bmMgZnVuY3Rpb24geWkoQSxlLHQscj17fSl7bGV0IG49W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOntwYXRoOnQsZGF0YTpuZXcgVWludDhBcnJheX19XSxvPVt7dHlwZTpCLk1lc2gsZGF0YTplfV0saT1bXSxsPSIwIjtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST10O2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHIuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmci5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5IiksdHlwZW9mIHIudXNlQ29tcHJlc3Npb248InUiJiZyLnVzZUNvbXByZXNzaW9uJiZpLnB1c2goIi0tdXNlLWNvbXByZXNzaW9uIiksdHlwZW9mIHIuYmluYXJ5RmlsZVR5cGU8InUiJiZyLmJpbmFyeUZpbGVUeXBlJiZpLnB1c2goIi0tYmluYXJ5LWZpbGUtdHlwZSIpO2xldCBnPSJvZmYtd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBjZT15aTthc3luYyBmdW5jdGlvbiB3aShBLGUsdD17fSl7bGV0IHI9W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuTWVzaH1dLG49ZTtpZihlIGluc3RhbmNlb2YgRmlsZSl7bGV0IG09YXdhaXQgZS5hcnJheUJ1ZmZlcigpO249e3BhdGg6ZS5uYW1lLGRhdGE6bmV3IFVpbnQ4QXJyYXkobSl9fWxldCBvPVt7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTpufV0saT1bXSxsPW4ucGF0aDtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST0iMSI7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2YgdC5pbmZvcm1hdGlvbk9ubHk8InUiJiZ0LmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKTtsZXQgZz0id2FzbS1yZWFkLW1lc2giLHt3ZWJXb3JrZXI6dSxyZXR1cm5WYWx1ZTpmLHN0ZGVycjphLG91dHB1dHM6c309YXdhaXQgZChBLGcsaSxyLG8se3BpcGVsaW5lQmFzZVVybDpFKCkscGlwZWxpbmVXb3JrZXJVcmw6USgpfSk7aWYoZiE9PTAmJmEhPT0iIil0aHJvdyBuZXcgRXJyb3IoYSk7cmV0dXJue3dlYldvcmtlcjp1LGNvdWxkUmVhZDpzWzBdPy5kYXRhLG1lc2g6c1sxXT8uZGF0YX19dmFyIEJlPXdpO2FzeW5jIGZ1bmN0aW9uIERpKEEsZSx0LHI9e30pe2xldCBuPVt7dHlwZTpCLkpzb25Db21wYXRpYmxlfSx7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTp7cGF0aDp0LGRhdGE6bmV3IFVpbnQ4QXJyYXl9fV0sbz1be3R5cGU6Qi5NZXNoLGRhdGE6ZX1dLGk9W10sbD0iMCI7aS5wdXNoKGwpO2xldCBjPSIwIjtpLnB1c2goYyk7bGV0IEk9dDtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiByLmluZm9ybWF0aW9uT25seTwidSImJnIuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpLHR5cGVvZiByLnVzZUNvbXByZXNzaW9uPCJ1IiYmci51c2VDb21wcmVzc2lvbiYmaS5wdXNoKCItLXVzZS1jb21wcmVzc2lvbiIpLHR5cGVvZiByLmJpbmFyeUZpbGVUeXBlPCJ1IiYmci5iaW5hcnlGaWxlVHlwZSYmaS5wdXNoKCItLWJpbmFyeS1maWxlLXR5cGUiKTtsZXQgZz0id2FzbS13cml0ZS1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGksbixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFdyaXRlOnNbMF0/LmRhdGEsc2VyaWFsaXplZE1lc2g6c1sxXT8uZGF0YX19dmFyIENlPURpO2FzeW5jIGZ1bmN0aW9uIGJpKEEsZSx0PXt9KXtsZXQgcj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5NZXNofV0sbj1lO2lmKGUgaW5zdGFuY2VvZiBGaWxlKXtsZXQgbT1hd2FpdCBlLmFycmF5QnVmZmVyKCk7bj17cGF0aDplLm5hbWUsZGF0YTpuZXcgVWludDhBcnJheShtKX19bGV0IG89W3t0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOm59XSxpPVtdLGw9bi5wYXRoO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPSIxIjtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiB0LmluZm9ybWF0aW9uT25seTwidSImJnQuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpO2xldCBnPSJ3YXNtLXpzdGQtcmVhZC1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGkscixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFJlYWQ6c1swXT8uZGF0YSxtZXNoOnNbMV0/LmRhdGF9fXZhciBtZT1iaTthc3luYyBmdW5jdGlvbiBGaShBLGUsdCxyPXt9KXtsZXQgbj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6e3BhdGg6dCxkYXRhOm5ldyBVaW50OEFycmF5fX1dLG89W3t0eXBlOkIuTWVzaCxkYXRhOmV9XSxpPVtdLGw9IjAiO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPXQ7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2Ygci5pbmZvcm1hdGlvbk9ubHk8InUiJiZyLmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKSx0eXBlb2Ygci51c2VDb21wcmVzc2lvbjwidSImJnIudXNlQ29tcHJlc3Npb24mJmkucHVzaCgiLS11c2UtY29tcHJlc3Npb24iKSx0eXBlb2Ygci5iaW5hcnlGaWxlVHlwZTwidSImJnIuYmluYXJ5RmlsZVR5cGUmJmkucHVzaCgiLS1iaW5hcnktZmlsZS10eXBlIik7bGV0IGc9Indhc20tenN0ZC13cml0ZS1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGksbixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFdyaXRlOnNbMF0/LmRhdGEsc2VyaWFsaXplZE1lc2g6c1sxXT8uZGF0YX19dmFyIGRlPUZpO2FzeW5jIGZ1bmN0aW9uIFJpKEEsZSx0PXt9KXtsZXQgcj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5NZXNofV0sbj1lO2lmKGUgaW5zdGFuY2VvZiBGaWxlKXtsZXQgbT1hd2FpdCBlLmFycmF5QnVmZmVyKCk7bj17cGF0aDplLm5hbWUsZGF0YTpuZXcgVWludDhBcnJheShtKX19bGV0IG89W3t0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOm59XSxpPVtdLGw9bi5wYXRoO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPSIxIjtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiB0LmluZm9ybWF0aW9uT25seTwidSImJnQuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpO2xldCBnPSJzd2MtcmVhZC1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGkscixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFJlYWQ6c1swXT8uZGF0YSxtZXNoOnNbMV0/LmRhdGF9fXZhciBFZT1SaTthc3luYyBmdW5jdGlvbiBTaShBLGUsdCxyPXt9KXtsZXQgbj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6e3BhdGg6dCxkYXRhOm5ldyBVaW50OEFycmF5fX1dLG89W3t0eXBlOkIuTWVzaCxkYXRhOmV9XSxpPVtdLGw9IjAiO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPXQ7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2Ygci5pbmZvcm1hdGlvbk9ubHk8InUiJiZyLmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKSx0eXBlb2Ygci51c2VDb21wcmVzc2lvbjwidSImJnIudXNlQ29tcHJlc3Npb24mJmkucHVzaCgiLS11c2UtY29tcHJlc3Npb24iKSx0eXBlb2Ygci5iaW5hcnlGaWxlVHlwZTwidSImJnIuYmluYXJ5RmlsZVR5cGUmJmkucHVzaCgiLS1iaW5hcnktZmlsZS10eXBlIik7bGV0IGc9InN3Yy13cml0ZS1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGksbixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFdyaXRlOnNbMF0/LmRhdGEsc2VyaWFsaXplZE1lc2g6c1sxXT8uZGF0YX19dmFyIFFlPVNpO2FzeW5jIGZ1bmN0aW9uIGtpKEEsZSx0PXt9KXtsZXQgcj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5NZXNofV0sbj1lO2lmKGUgaW5zdGFuY2VvZiBGaWxlKXtsZXQgbT1hd2FpdCBlLmFycmF5QnVmZmVyKCk7bj17cGF0aDplLm5hbWUsZGF0YTpuZXcgVWludDhBcnJheShtKX19bGV0IG89W3t0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOm59XSxpPVtdLGw9bi5wYXRoO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPSIxIjtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiB0LmluZm9ybWF0aW9uT25seTwidSImJnQuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpO2xldCBnPSJieXUtcmVhZC1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGkscixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFJlYWQ6c1swXT8uZGF0YSxtZXNoOnNbMV0/LmRhdGF9fXZhciBoZT1raTthc3luYyBmdW5jdGlvbiBPaShBLGUsdCxyPXt9KXtsZXQgbj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6e3BhdGg6dCxkYXRhOm5ldyBVaW50OEFycmF5fX1dLG89W3t0eXBlOkIuTWVzaCxkYXRhOmV9XSxpPVtdLGw9IjAiO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPXQ7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2Ygci5pbmZvcm1hdGlvbk9ubHk8InUiJiZyLmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKSx0eXBlb2Ygci51c2VDb21wcmVzc2lvbjwidSImJnIudXNlQ29tcHJlc3Npb24mJmkucHVzaCgiLS11c2UtY29tcHJlc3Npb24iKSx0eXBlb2Ygci5iaW5hcnlGaWxlVHlwZTwidSImJnIuYmluYXJ5RmlsZVR5cGUmJmkucHVzaCgiLS1iaW5hcnktZmlsZS10eXBlIik7bGV0IGc9ImJ5dS13cml0ZS1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGksbixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFdyaXRlOnNbMF0/LmRhdGEsc2VyaWFsaXplZE1lc2g6c1sxXT8uZGF0YX19dmFyIHllPU9pO2FzeW5jIGZ1bmN0aW9uIFVpKEEsZSx0PXt9KXtsZXQgcj1be3R5cGU6Qi5Kc29uQ29tcGF0aWJsZX0se3R5cGU6Qi5NZXNofV0sbj1lO2lmKGUgaW5zdGFuY2VvZiBGaWxlKXtsZXQgbT1hd2FpdCBlLmFycmF5QnVmZmVyKCk7bj17cGF0aDplLm5hbWUsZGF0YTpuZXcgVWludDhBcnJheShtKX19bGV0IG89W3t0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOm59XSxpPVtdLGw9bi5wYXRoO2kucHVzaChsKTtsZXQgYz0iMCI7aS5wdXNoKGMpO2xldCBJPSIxIjtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiB0LmluZm9ybWF0aW9uT25seTwidSImJnQuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpO2xldCBnPSJmcmVlLXN1cmZlci1hc2NpaS1yZWFkLW1lc2giLHt3ZWJXb3JrZXI6dSxyZXR1cm5WYWx1ZTpmLHN0ZGVycjphLG91dHB1dHM6c309YXdhaXQgZChBLGcsaSxyLG8se3BpcGVsaW5lQmFzZVVybDpFKCkscGlwZWxpbmVXb3JrZXJVcmw6USgpfSk7aWYoZiE9PTAmJmEhPT0iIil0aHJvdyBuZXcgRXJyb3IoYSk7cmV0dXJue3dlYldvcmtlcjp1LGNvdWxkUmVhZDpzWzBdPy5kYXRhLG1lc2g6c1sxXT8uZGF0YX19dmFyIHdlPVVpO2FzeW5jIGZ1bmN0aW9uIE5pKEEsZSx0LHI9e30pe2xldCBuPVt7dHlwZTpCLkpzb25Db21wYXRpYmxlfSx7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTp7cGF0aDp0LGRhdGE6bmV3IFVpbnQ4QXJyYXl9fV0sbz1be3R5cGU6Qi5NZXNoLGRhdGE6ZX1dLGk9W10sbD0iMCI7aS5wdXNoKGwpO2xldCBjPSIwIjtpLnB1c2goYyk7bGV0IEk9dDtpLnB1c2goSSksaS5wdXNoKCItLW1lbW9yeS1pbyIpLHR5cGVvZiByLmluZm9ybWF0aW9uT25seTwidSImJnIuaW5mb3JtYXRpb25Pbmx5JiZpLnB1c2goIi0taW5mb3JtYXRpb24tb25seSIpLHR5cGVvZiByLnVzZUNvbXByZXNzaW9uPCJ1IiYmci51c2VDb21wcmVzc2lvbiYmaS5wdXNoKCItLXVzZS1jb21wcmVzc2lvbiIpLHR5cGVvZiByLmJpbmFyeUZpbGVUeXBlPCJ1IiYmci5iaW5hcnlGaWxlVHlwZSYmaS5wdXNoKCItLWJpbmFyeS1maWxlLXR5cGUiKTtsZXQgZz0iZnJlZS1zdXJmZXItYXNjaWktd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBEZT1OaTthc3luYyBmdW5jdGlvbiBNaShBLGUsdD17fSl7bGV0IHI9W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuTWVzaH1dLG49ZTtpZihlIGluc3RhbmNlb2YgRmlsZSl7bGV0IG09YXdhaXQgZS5hcnJheUJ1ZmZlcigpO249e3BhdGg6ZS5uYW1lLGRhdGE6bmV3IFVpbnQ4QXJyYXkobSl9fWxldCBvPVt7dHlwZTpCLkJpbmFyeUZpbGUsZGF0YTpufV0saT1bXSxsPW4ucGF0aDtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST0iMSI7aS5wdXNoKEkpLGkucHVzaCgiLS1tZW1vcnktaW8iKSx0eXBlb2YgdC5pbmZvcm1hdGlvbk9ubHk8InUiJiZ0LmluZm9ybWF0aW9uT25seSYmaS5wdXNoKCItLWluZm9ybWF0aW9uLW9ubHkiKTtsZXQgZz0iZnJlZS1zdXJmZXItYmluYXJ5LXJlYWQtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLHIsbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRSZWFkOnNbMF0/LmRhdGEsbWVzaDpzWzFdPy5kYXRhfX12YXIgYmU9TWk7YXN5bmMgZnVuY3Rpb24gUGkoQSxlLHQscj17fSl7bGV0IG49W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOntwYXRoOnQsZGF0YTpuZXcgVWludDhBcnJheX19XSxvPVt7dHlwZTpCLk1lc2gsZGF0YTplfV0saT1bXSxsPSIwIjtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST10O2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHIuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmci5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5IiksdHlwZW9mIHIudXNlQ29tcHJlc3Npb248InUiJiZyLnVzZUNvbXByZXNzaW9uJiZpLnB1c2goIi0tdXNlLWNvbXByZXNzaW9uIiksdHlwZW9mIHIuYmluYXJ5RmlsZVR5cGU8InUiJiZyLmJpbmFyeUZpbGVUeXBlJiZpLnB1c2goIi0tYmluYXJ5LWZpbGUtdHlwZSIpO2xldCBnPSJmcmVlLXN1cmZlci1iaW5hcnktd3JpdGUtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLG4sbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRXcml0ZTpzWzBdPy5kYXRhLHNlcmlhbGl6ZWRNZXNoOnNbMV0/LmRhdGF9fXZhciBGZT1QaTt2YXIgeGk9bmV3IE1hcChbWyJ2dGsiLFtzZSxJZV1dLFsib2JqIixbbGUsZ2VdXSxbInN0bCIsW3VlLGZlXV0sWyJvZmYiLFtwZSxjZV1dLFsid2FzbSIsW0JlLENlXV0sWyJ3YXNtLXpzdCIsW21lLGRlXV0sWyJzd2MiLFtFZSxRZV1dLFsiYnl1IixbaGUseWVdXSxbImZyZWUtc3VyZmVyLWFzY2lpIixbd2UsRGVdXSxbImZyZWUtc3VyZmVyLWJpbmFyeSIsW2JlLEZlXV1dKSxBQT14aTthc3luYyBmdW5jdGlvbiBXaShBLGUsdD17fSl7bGV0IHI9ZS50eXBlPz8iIixuPWUubmFtZT8/ZS5wYXRoPz8iZmlsZU5hbWUiLG89Z0EobikudG9Mb3dlckNhc2UoKSxpPUEsbD1lO2lmKGUgaW5zdGFuY2VvZiBCbG9iKXtsZXQgcz1hd2FpdCBlLmFycmF5QnVmZmVyKCk7bD17cGF0aDplLm5hbWUsZGF0YTpuZXcgVWludDhBcnJheShzKX19bGV0IGM9bnVsbDtpZihyJiZYLmhhcyhyKSljPVguZ2V0KHIpO2Vsc2UgaWYoJC5oYXMobykpYz0kLmdldChvKTtlbHNlIGZvcihsZXQgcyBvZiBBQS52YWx1ZXMoKSlpZihzWzBdIT09bnVsbCl7bGV0e3dlYldvcmtlcjpDLGNvdWxkUmVhZDptLG1lc2g6d309YXdhaXQgc1swXShpLHtwYXRoOmwucGF0aCxkYXRhOmwuZGF0YS5zbGljZSgpfSx7aW5mb3JtYXRpb25Pbmx5OnQuaW5mb3JtYXRpb25Pbmx5fSk7aWYoaT1DLG0pcmV0dXJue3dlYldvcmtlcjppLG1lc2g6d319aWYoIWMpdGhyb3cgRXJyb3IoIkNvdWxkIG5vdCBmaW5kIElPIGZvcjogIituKTtsZXQgZz1BQS5nZXQoYylbMF0se3dlYldvcmtlcjp1LGNvdWxkUmVhZDpmLG1lc2g6YX09YXdhaXQgZyhpLGwse2luZm9ybWF0aW9uT25seTp0LmluZm9ybWF0aW9uT25seX0pO2lmKGk9dSwhZil0aHJvdyBFcnJvcigiQ291bGQgbm90IHJlYWQ6ICIrbik7cmV0dXJue3dlYldvcmtlcjppLG1lc2g6YX19dmFyIEdpPVdpO2FzeW5jIGZ1bmN0aW9uIFRpKEEsZSx0LHI9e30pe2xldCBuPWUsbz1yLm1pbWVUeXBlLGk9Z0EodCkudG9Mb3dlckNhc2UoKSxsPUEsYz1udWxsO2lmKHR5cGVvZiBvPCJ1IiYmWC5oYXMobykpYz1YLmdldChvKTtlbHNlIGlmKCQuaGFzKGkpKWM9JC5nZXQoaSk7ZWxzZSBmb3IobGV0IEMgb2YgQUEudmFsdWVzKCkpaWYoQ1sxXSE9PW51bGwpe2xldHt3ZWJXb3JrZXI6bSxjb3VsZFdyaXRlOncsc2VyaWFsaXplZE1lc2g6eX09YXdhaXQgQ1sxXShsLG4sdCxyKTtpZihsPW0sdylyZXR1cm57d2ViV29ya2VyOmwsc2VyaWFsaXplZE1lc2g6eX19aWYoIWMpdGhyb3cgRXJyb3IoIkNvdWxkIG5vdCBmaW5kIElPIGZvcjogIit0KTtsZXQgZz1BQS5nZXQoYylbMV0se3dlYldvcmtlcjp1LGNvdWxkV3JpdGU6ZixzZXJpYWxpemVkTWVzaDphfT1hd2FpdCBnKGwsbix0LHIpO2lmKGw9dSwhZil0aHJvdyBFcnJvcigiQ291bGQgbm90IHdyaXRlOiAiK3QpO3JldHVybnt3ZWJXb3JrZXI6bCxzZXJpYWxpemVkTWVzaDphfX12YXIgTGk9VGk7YXN5bmMgZnVuY3Rpb24gSmkoQSxlLHQ9e30pe2xldCByPVt7dHlwZTpCLkpzb25Db21wYXRpYmxlfSx7dHlwZTpCLk1lc2h9XSxuPWU7aWYoZSBpbnN0YW5jZW9mIEZpbGUpe2xldCBtPWF3YWl0IGUuYXJyYXlCdWZmZXIoKTtuPXtwYXRoOmUubmFtZSxkYXRhOm5ldyBVaW50OEFycmF5KG0pfX1sZXQgbz1be3R5cGU6Qi5CaW5hcnlGaWxlLGRhdGE6bn1dLGk9W10sbD1uLnBhdGg7aS5wdXNoKGwpO2xldCBjPSIwIjtpLnB1c2goYyk7bGV0IEk9IjEiO2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHQuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmdC5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5Iik7bGV0IGc9Indhc20tenRkLXJlYWQtbWVzaCIse3dlYldvcmtlcjp1LHJldHVyblZhbHVlOmYsc3RkZXJyOmEsb3V0cHV0czpzfT1hd2FpdCBkKEEsZyxpLHIsbyx7cGlwZWxpbmVCYXNlVXJsOkUoKSxwaXBlbGluZVdvcmtlclVybDpRKCl9KTtpZihmIT09MCYmYSE9PSIiKXRocm93IG5ldyBFcnJvcihhKTtyZXR1cm57d2ViV29ya2VyOnUsY291bGRSZWFkOnNbMF0/LmRhdGEsbWVzaDpzWzFdPy5kYXRhfX12YXIgSGk9Smk7YXN5bmMgZnVuY3Rpb24gWWkoQSxlLHQscj17fSl7bGV0IG49W3t0eXBlOkIuSnNvbkNvbXBhdGlibGV9LHt0eXBlOkIuQmluYXJ5RmlsZSxkYXRhOntwYXRoOnQsZGF0YTpuZXcgVWludDhBcnJheX19XSxvPVt7dHlwZTpCLk1lc2gsZGF0YTplfV0saT1bXSxsPSIwIjtpLnB1c2gobCk7bGV0IGM9IjAiO2kucHVzaChjKTtsZXQgST10O2kucHVzaChJKSxpLnB1c2goIi0tbWVtb3J5LWlvIiksdHlwZW9mIHIuaW5mb3JtYXRpb25Pbmx5PCJ1IiYmci5pbmZvcm1hdGlvbk9ubHkmJmkucHVzaCgiLS1pbmZvcm1hdGlvbi1vbmx5IiksdHlwZW9mIHIudXNlQ29tcHJlc3Npb248InUiJiZyLnVzZUNvbXByZXNzaW9uJiZpLnB1c2goIi0tdXNlLWNvbXByZXNzaW9uIiksdHlwZW9mIHIuYmluYXJ5RmlsZVR5cGU8InUiJiZyLmJpbmFyeUZpbGVUeXBlJiZpLnB1c2goIi0tYmluYXJ5LWZpbGUtdHlwZSIpO2xldCBnPSJ3YXNtLXp0ZC13cml0ZS1tZXNoIix7d2ViV29ya2VyOnUscmV0dXJuVmFsdWU6ZixzdGRlcnI6YSxvdXRwdXRzOnN9PWF3YWl0IGQoQSxnLGksbixvLHtwaXBlbGluZUJhc2VVcmw6RSgpLHBpcGVsaW5lV29ya2VyVXJsOlEoKX0pO2lmKGYhPT0wJiZhIT09IiIpdGhyb3cgbmV3IEVycm9yKGEpO3JldHVybnt3ZWJXb3JrZXI6dSxjb3VsZFdyaXRlOnNbMF0/LmRhdGEsc2VyaWFsaXplZE1lc2g6c1sxXT8uZGF0YX19dmFyIHFpPVlpO3ZhciBOdD0nZGF0YTp0ZXh0L2phdmFzY3JpcHQ7Y2hhcnNldD11dGYtOCx2YXIgZmU9U3ltYm9sKCJDb21saW5rLnByb3h5IiksQnQ9U3ltYm9sKCJDb21saW5rLmVuZHBvaW50IiksUXQ9U3ltYm9sKCJDb21saW5rLnJlbGVhc2VQcm94eSIpLEpBPVN5bWJvbCgiQ29tbGluay5maW5hbGl6ZXIiKSxzQT1TeW1ib2woIkNvbWxpbmsudGhyb3duIiksbGU9QT0+dHlwZW9mIEE9PSJvYmplY3QiJiZBIT09bnVsbHx8dHlwZW9mIEE9PSJmdW5jdGlvbiIsRXQ9e2NhbkhhbmRsZTpBPT5sZShBKSYmQVtmZV0sc2VyaWFsaXplKEEpe2xldHtwb3J0MTplLHBvcnQyOnR9PW5ldyBNZXNzYWdlQ2hhbm5lbDtyZXR1cm4gRUEoQSxlKSxbdCxbdF1dfSxkZXNlcmlhbGl6ZShBKXtyZXR1cm4gQS5zdGFydCgpLHV0KEEpfX0sY3Q9e2NhbkhhbmRsZTpBPT5sZShBKSYmc0EgaW4gQSxzZXJpYWxpemUoe3ZhbHVlOkF9KXtsZXQgZTtyZXR1cm4gQSBpbnN0YW5jZW9mIEVycm9yP2U9e2lzRXJyb3I6ITAsdmFsdWU6e21lc3NhZ2U6QS5tZXNzYWdlLG5hbWU6QS5uYW1lLHN0YWNrOkEuc3RhY2t9fTplPXtpc0Vycm9yOiExLHZhbHVlOkF9LFtlLFtdXX0sZGVzZXJpYWxpemUoQSl7dGhyb3cgQS5pc0Vycm9yP09iamVjdC5hc3NpZ24obmV3IEVycm9yKEEudmFsdWUubWVzc2FnZSksQS52YWx1ZSk6QS52YWx1ZX19LHVlPW5ldyBNYXAoW1sicHJveHkiLEV0XSxbInRocm93IixjdF1dKTtmdW5jdGlvbiBmdChBLGUpe2ZvcihsZXQgdCBvZiBBKWlmKGU9PT10fHx0PT09IioifHx0IGluc3RhbmNlb2YgUmVnRXhwJiZ0LnRlc3QoZSkpcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24gRUEoQSxlPWdsb2JhbFRoaXMsdD1bIioiXSl7ZS5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIixmdW5jdGlvbiBJKHIpe2lmKCFyfHwhci5kYXRhKXJldHVybjtpZighZnQodCxyLm9yaWdpbikpe2NvbnNvbGUud2FybihgSW52YWxpZCBvcmlnaW4gXCcke3Iub3JpZ2lufVwnIGZvciBjb21saW5rIHByb3h5YCk7cmV0dXJufWxldHtpZDppLHR5cGU6ZyxwYXRoOm59PU9iamVjdC5hc3NpZ24oe3BhdGg6W119LHIuZGF0YSksRT0oci5kYXRhLmFyZ3VtZW50TGlzdHx8W10pLm1hcChxKSxDO3RyeXtsZXQgbz1uLnNsaWNlKDAsLTEpLnJlZHVjZSgoYSxCKT0+YVtCXSxBKSxjPW4ucmVkdWNlKChhLEIpPT5hW0JdLEEpO3N3aXRjaChnKXtjYXNlIkdFVCI6Qz1jO2JyZWFrO2Nhc2UiU0VUIjpvW24uc2xpY2UoLTEpWzBdXT1xKHIuZGF0YS52YWx1ZSksQz0hMDticmVhaztjYXNlIkFQUExZIjpDPWMuYXBwbHkobyxFKTticmVhaztjYXNlIkNPTlNUUlVDVCI6e2xldCBhPW5ldyBjKC4uLkUpO0M9RHQoYSl9YnJlYWs7Y2FzZSJFTkRQT0lOVCI6e2xldHtwb3J0MTphLHBvcnQyOkJ9PW5ldyBNZXNzYWdlQ2hhbm5lbDtFQShBLEIpLEM9YkEoYSxbYV0pfWJyZWFrO2Nhc2UiUkVMRUFTRSI6Qz12b2lkIDA7YnJlYWs7ZGVmYXVsdDpyZXR1cm59fWNhdGNoKG8pe0M9e3ZhbHVlOm8sW3NBXTowfX1Qcm9taXNlLnJlc29sdmUoQykuY2F0Y2gobz0+KHt2YWx1ZTpvLFtzQV06MH0pKS50aGVuKG89PntsZXRbYyxhXT1RQShvKTtlLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSx7aWQ6aX0pLGEpLGc9PT0iUkVMRUFTRSImJihlLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLEkpLGRlKGUpLEpBIGluIEEmJnR5cGVvZiBBW0pBXT09ImZ1bmN0aW9uIiYmQVtKQV0oKSl9KS5jYXRjaChvPT57bGV0W2MsYV09UUEoe3ZhbHVlOm5ldyBUeXBlRXJyb3IoIlVuc2VyaWFsaXphYmxlIHJldHVybiB2YWx1ZSIpLFtzQV06MH0pO2UucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LGMpLHtpZDppfSksYSl9KX0pLGUuc3RhcnQmJmUuc3RhcnQoKX1mdW5jdGlvbiBsdChBKXtyZXR1cm4gQS5jb25zdHJ1Y3Rvci5uYW1lPT09Ik1lc3NhZ2VQb3J0In1mdW5jdGlvbiBkZShBKXtsdChBKSYmQS5jbG9zZSgpfWZ1bmN0aW9uIHV0KEEsZSl7cmV0dXJuIE1BKEEsW10sZSl9ZnVuY3Rpb24gYUEoQSl7aWYoQSl0aHJvdyBuZXcgRXJyb3IoIlByb3h5IGhhcyBiZWVuIHJlbGVhc2VkIGFuZCBpcyBub3QgdXNlYWJsZSIpfWZ1bmN0aW9uIGhlKEEpe3JldHVybiB4KEEse3R5cGU6IlJFTEVBU0UifSkudGhlbigoKT0+e2RlKEEpfSl9dmFyIENBPW5ldyBXZWFrTWFwLEJBPSJGaW5hbGl6YXRpb25SZWdpc3RyeSJpbiBnbG9iYWxUaGlzJiZuZXcgRmluYWxpemF0aW9uUmVnaXN0cnkoQT0+e2xldCBlPShDQS5nZXQoQSl8fDApLTE7Q0Euc2V0KEEsZSksZT09PTAmJmhlKEEpfSk7ZnVuY3Rpb24gZHQoQSxlKXtsZXQgdD0oQ0EuZ2V0KGUpfHwwKSsxO0NBLnNldChlLHQpLEJBJiZCQS5yZWdpc3RlcihBLGUsQSl9ZnVuY3Rpb24gaHQoQSl7QkEmJkJBLnVucmVnaXN0ZXIoQSl9ZnVuY3Rpb24gTUEoQSxlPVtdLHQ9ZnVuY3Rpb24oKXt9KXtsZXQgST0hMSxyPW5ldyBQcm94eSh0LHtnZXQoaSxnKXtpZihhQShJKSxnPT09UXQpcmV0dXJuKCk9PntodChyKSxoZShBKSxJPSEwfTtpZihnPT09InRoZW4iKXtpZihlLmxlbmd0aD09PTApcmV0dXJue3RoZW46KCk9PnJ9O2xldCBuPXgoQSx7dHlwZToiR0VUIixwYXRoOmUubWFwKEU9PkUudG9TdHJpbmcoKSl9KS50aGVuKHEpO3JldHVybiBuLnRoZW4uYmluZChuKX1yZXR1cm4gTUEoQSxbLi4uZSxnXSl9LHNldChpLGcsbil7YUEoSSk7bGV0W0UsQ109UUEobik7cmV0dXJuIHgoQSx7dHlwZToiU0VUIixwYXRoOlsuLi5lLGddLm1hcChvPT5vLnRvU3RyaW5nKCkpLHZhbHVlOkV9LEMpLnRoZW4ocSl9LGFwcGx5KGksZyxuKXthQShJKTtsZXQgRT1lW2UubGVuZ3RoLTFdO2lmKEU9PT1CdClyZXR1cm4geChBLHt0eXBlOiJFTkRQT0lOVCJ9KS50aGVuKHEpO2lmKEU9PT0iYmluZCIpcmV0dXJuIE1BKEEsZS5zbGljZSgwLC0xKSk7bGV0W0Msb109Y2Uobik7cmV0dXJuIHgoQSx7dHlwZToiQVBQTFkiLHBhdGg6ZS5tYXAoYz0+Yy50b1N0cmluZygpKSxhcmd1bWVudExpc3Q6Q30sbykudGhlbihxKX0sY29uc3RydWN0KGksZyl7YUEoSSk7bGV0W24sRV09Y2UoZyk7cmV0dXJuIHgoQSx7dHlwZToiQ09OU1RSVUNUIixwYXRoOmUubWFwKEM9PkMudG9TdHJpbmcoKSksYXJndW1lbnRMaXN0Om59LEUpLnRoZW4ocSl9fSk7cmV0dXJuIGR0KHIsQSkscn1mdW5jdGlvbiBtdChBKXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSxBKX1mdW5jdGlvbiBjZShBKXtsZXQgZT1BLm1hcChRQSk7cmV0dXJuW2UubWFwKHQ9PnRbMF0pLG10KGUubWFwKHQ9PnRbMV0pKV19dmFyIG1lPW5ldyBXZWFrTWFwO2Z1bmN0aW9uIGJBKEEsZSl7cmV0dXJuIG1lLnNldChBLGUpLEF9ZnVuY3Rpb24gRHQoQSl7cmV0dXJuIE9iamVjdC5hc3NpZ24oQSx7W2ZlXTohMH0pfWZ1bmN0aW9uIFFBKEEpe2ZvcihsZXRbZSx0XW9mIHVlKWlmKHQuY2FuSGFuZGxlKEEpKXtsZXRbSSxyXT10LnNlcmlhbGl6ZShBKTtyZXR1cm5be3R5cGU6IkhBTkRMRVIiLG5hbWU6ZSx2YWx1ZTpJfSxyXX1yZXR1cm5be3R5cGU6IlJBVyIsdmFsdWU6QX0sbWUuZ2V0KEEpfHxbXV19ZnVuY3Rpb24gcShBKXtzd2l0Y2goQS50eXBlKXtjYXNlIkhBTkRMRVIiOnJldHVybiB1ZS5nZXQoQS5uYW1lKS5kZXNlcmlhbGl6ZShBLnZhbHVlKTtjYXNlIlJBVyI6cmV0dXJuIEEudmFsdWV9fWZ1bmN0aW9uIHgoQSxlLHQpe3JldHVybiBuZXcgUHJvbWlzZShJPT57bGV0IHI9eXQoKTtBLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGZ1bmN0aW9uIGkoZyl7IWcuZGF0YXx8IWcuZGF0YS5pZHx8Zy5kYXRhLmlkIT09cnx8KEEucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsaSksSShnLmRhdGEpKX0pLEEuc3RhcnQmJkEuc3RhcnQoKSxBLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oe2lkOnJ9LGUpLHQpfSl9ZnVuY3Rpb24geXQoKXtyZXR1cm4gbmV3IEFycmF5KDQpLmZpbGwoMCkubWFwKCgpPT5NYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLnRvU3RyaW5nKDE2KSkuam9pbigiLSIpfWZ1bmN0aW9uIFgoQSxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gQS5hcHBseShlLGFyZ3VtZW50cyl9fXZhcnt0b1N0cmluZzp3dH09T2JqZWN0LnByb3RvdHlwZSx7Z2V0UHJvdG90eXBlT2Y6cUF9PU9iamVjdCxmQT0oQT0+ZT0+e2xldCB0PXd0LmNhbGwoZSk7cmV0dXJuIEFbdF18fChBW3RdPXQuc2xpY2UoOCwtMSkudG9Mb3dlckNhc2UoKSl9KShPYmplY3QuY3JlYXRlKG51bGwpKSxrPUE9PihBPUEudG9Mb3dlckNhc2UoKSxlPT5mQShlKT09PUEpLGxBPUE9PmU9PnR5cGVvZiBlPT09QSx7aXNBcnJheTpQfT1BcnJheSx2PWxBKCJ1bmRlZmluZWQiKTtmdW5jdGlvbiBwdChBKXtyZXR1cm4gQSE9PW51bGwmJiF2KEEpJiZBLmNvbnN0cnVjdG9yIT09bnVsbCYmIXYoQS5jb25zdHJ1Y3RvcikmJkcoQS5jb25zdHJ1Y3Rvci5pc0J1ZmZlcikmJkEuY29uc3RydWN0b3IuaXNCdWZmZXIoQSl9dmFyIHBlPWsoIkFycmF5QnVmZmVyIik7ZnVuY3Rpb24gRnQoQSl7bGV0IGU7cmV0dXJuIHR5cGVvZiBBcnJheUJ1ZmZlcjwidSImJkFycmF5QnVmZmVyLmlzVmlldz9lPUFycmF5QnVmZmVyLmlzVmlldyhBKTplPUEmJkEuYnVmZmVyJiZwZShBLmJ1ZmZlciksZX12YXIgU3Q9bEEoInN0cmluZyIpLEc9bEEoImZ1bmN0aW9uIiksRmU9bEEoIm51bWJlciIpLHVBPUE9PkEhPT1udWxsJiZ0eXBlb2YgQT09Im9iamVjdCIsTnQ9QT0+QT09PSEwfHxBPT09ITEsY0E9QT0+e2lmKGZBKEEpIT09Im9iamVjdCIpcmV0dXJuITE7bGV0IGU9cUEoQSk7cmV0dXJuKGU9PT1udWxsfHxlPT09T2JqZWN0LnByb3RvdHlwZXx8T2JqZWN0LmdldFByb3RvdHlwZU9mKGUpPT09bnVsbCkmJiEoU3ltYm9sLnRvU3RyaW5nVGFnIGluIEEpJiYhKFN5bWJvbC5pdGVyYXRvciBpbiBBKX0sUnQ9aygiRGF0ZSIpLEd0PWsoIkZpbGUiKSxVdD1rKCJCbG9iIiksa3Q9aygiRmlsZUxpc3QiKSxMdD1BPT51QShBKSYmRyhBLnBpcGUpLE90PUE9PntsZXQgZTtyZXR1cm4gQSYmKHR5cGVvZiBGb3JtRGF0YT09ImZ1bmN0aW9uIiYmQSBpbnN0YW5jZW9mIEZvcm1EYXRhfHxHKEEuYXBwZW5kKSYmKChlPWZBKEEpKT09PSJmb3JtZGF0YSJ8fGU9PT0ib2JqZWN0IiYmRyhBLnRvU3RyaW5nKSYmQS50b1N0cmluZygpPT09IltvYmplY3QgRm9ybURhdGFdIikpfSxKdD1rKCJVUkxTZWFyY2hQYXJhbXMiKSxNdD1BPT5BLnRyaW0/QS50cmltKCk6QS5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywiIik7ZnVuY3Rpb24gJChBLGUse2FsbE93bktleXM6dD0hMX09e30pe2lmKEE9PT1udWxsfHx0eXBlb2YgQT4idSIpcmV0dXJuO2xldCBJLHI7aWYodHlwZW9mIEEhPSJvYmplY3QiJiYoQT1bQV0pLFAoQSkpZm9yKEk9MCxyPUEubGVuZ3RoO0k8cjtJKyspZS5jYWxsKG51bGwsQVtJXSxJLEEpO2Vsc2V7bGV0IGk9dD9PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhBKTpPYmplY3Qua2V5cyhBKSxnPWkubGVuZ3RoLG47Zm9yKEk9MDtJPGc7SSsrKW49aVtJXSxlLmNhbGwobnVsbCxBW25dLG4sQSl9fWZ1bmN0aW9uIFNlKEEsZSl7ZT1lLnRvTG93ZXJDYXNlKCk7bGV0IHQ9T2JqZWN0LmtleXMoQSksST10Lmxlbmd0aCxyO2Zvcig7SS0tID4wOylpZihyPXRbSV0sZT09PXIudG9Mb3dlckNhc2UoKSlyZXR1cm4gcjtyZXR1cm4gbnVsbH12YXIgTmU9KCgpPT50eXBlb2YgZ2xvYmFsVGhpczwidSI/Z2xvYmFsVGhpczp0eXBlb2Ygc2VsZjwidSI/c2VsZjp0eXBlb2Ygd2luZG93PCJ1Ij93aW5kb3c6Z2xvYmFsKSgpLFJlPUE9PiF2KEEpJiZBIT09TmU7ZnVuY3Rpb24gWUEoKXtsZXR7Y2FzZWxlc3M6QX09UmUodGhpcykmJnRoaXN8fHt9LGU9e30sdD0oSSxyKT0+e2xldCBpPUEmJlNlKGUscil8fHI7Y0EoZVtpXSkmJmNBKEkpP2VbaV09WUEoZVtpXSxJKTpjQShJKT9lW2ldPVlBKHt9LEkpOlAoSSk/ZVtpXT1JLnNsaWNlKCk6ZVtpXT1JfTtmb3IobGV0IEk9MCxyPWFyZ3VtZW50cy5sZW5ndGg7STxyO0krKylhcmd1bWVudHNbSV0mJiQoYXJndW1lbnRzW0ldLHQpO3JldHVybiBlfXZhciBidD0oQSxlLHQse2FsbE93bktleXM6SX09e30pPT4oJChlLChyLGkpPT57dCYmRyhyKT9BW2ldPVgocix0KTpBW2ldPXJ9LHthbGxPd25LZXlzOkl9KSxBKSxIdD1BPT4oQS5jaGFyQ29kZUF0KDApPT09NjUyNzkmJihBPUEuc2xpY2UoMSkpLEEpLFl0PShBLGUsdCxJKT0+e0EucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoZS5wcm90b3R5cGUsSSksQS5wcm90b3R5cGUuY29uc3RydWN0b3I9QSxPYmplY3QuZGVmaW5lUHJvcGVydHkoQSwic3VwZXIiLHt2YWx1ZTplLnByb3RvdHlwZX0pLHQmJk9iamVjdC5hc3NpZ24oQS5wcm90b3R5cGUsdCl9LHF0PShBLGUsdCxJKT0+e2xldCByLGksZyxuPXt9O2lmKGU9ZXx8e30sQT09bnVsbClyZXR1cm4gZTtkb3tmb3Iocj1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhBKSxpPXIubGVuZ3RoO2ktLSA+MDspZz1yW2ldLCghSXx8SShnLEEsZSkpJiYhbltnXSYmKGVbZ109QVtnXSxuW2ddPSEwKTtBPXQhPT0hMSYmcUEoQSl9d2hpbGUoQSYmKCF0fHx0KEEsZSkpJiZBIT09T2JqZWN0LnByb3RvdHlwZSk7cmV0dXJuIGV9LFR0PShBLGUsdCk9PntBPVN0cmluZyhBKSwodD09PXZvaWQgMHx8dD5BLmxlbmd0aCkmJih0PUEubGVuZ3RoKSx0LT1lLmxlbmd0aDtsZXQgST1BLmluZGV4T2YoZSx0KTtyZXR1cm4gSSE9PS0xJiZJPT09dH0sS3Q9QT0+e2lmKCFBKXJldHVybiBudWxsO2lmKFAoQSkpcmV0dXJuIEE7bGV0IGU9QS5sZW5ndGg7aWYoIUZlKGUpKXJldHVybiBudWxsO2xldCB0PW5ldyBBcnJheShlKTtmb3IoO2UtLSA+MDspdFtlXT1BW2VdO3JldHVybiB0fSx4dD0oQT0+ZT0+QSYmZSBpbnN0YW5jZW9mIEEpKHR5cGVvZiBVaW50OEFycmF5PCJ1IiYmcUEoVWludDhBcnJheSkpLFB0PShBLGUpPT57bGV0IEk9KEEmJkFbU3ltYm9sLml0ZXJhdG9yXSkuY2FsbChBKSxyO2Zvcig7KHI9SS5uZXh0KCkpJiYhci5kb25lOyl7bGV0IGk9ci52YWx1ZTtlLmNhbGwoQSxpWzBdLGlbMV0pfX0sV3Q9KEEsZSk9PntsZXQgdCxJPVtdO2Zvcig7KHQ9QS5leGVjKGUpKSE9PW51bGw7KUkucHVzaCh0KTtyZXR1cm4gSX0sanQ9aygiSFRNTEZvcm1FbGVtZW50IiksWnQ9QT0+QS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX1xcc10oW2EtelxcZF0pKFxcdyopL2csZnVuY3Rpb24odCxJLHIpe3JldHVybiBJLnRvVXBwZXJDYXNlKCkrcn0pLHllPSgoe2hhc093blByb3BlcnR5OkF9KT0+KGUsdCk9PkEuY2FsbChlLHQpKShPYmplY3QucHJvdG90eXBlKSxfdD1rKCJSZWdFeHAiKSxHZT0oQSxlKT0+e2xldCB0PU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKEEpLEk9e307JCh0LChyLGkpPT57bGV0IGc7KGc9ZShyLGksQSkpIT09ITEmJihJW2ldPWd8fHIpfSksT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQSxJKX0sVnQ9QT0+e0dlKEEsKGUsdCk9PntpZihHKEEpJiZbImFyZ3VtZW50cyIsImNhbGxlciIsImNhbGxlZSJdLmluZGV4T2YodCkhPT0tMSlyZXR1cm4hMTtsZXQgST1BW3RdO2lmKEcoSSkpe2lmKGUuZW51bWVyYWJsZT0hMSwid3JpdGFibGUiaW4gZSl7ZS53cml0YWJsZT0hMTtyZXR1cm59ZS5zZXR8fChlLnNldD0oKT0+e3Rocm93IEVycm9yKCJDYW4gbm90IHJld3JpdGUgcmVhZC1vbmx5IG1ldGhvZCBcJyIrdCsiXCciKX0pfX0pfSx6dD0oQSxlKT0+e2xldCB0PXt9LEk9cj0+e3IuZm9yRWFjaChpPT57dFtpXT0hMH0pfTtyZXR1cm4gUChBKT9JKEEpOkkoU3RyaW5nKEEpLnNwbGl0KGUpKSx0fSxYdD0oKT0+e30sdnQ9KEEsZSk9PihBPStBLE51bWJlci5pc0Zpbml0ZShBKT9BOmUpLEhBPSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIsd2U9IjAxMjM0NTY3ODkiLFVlPXtESUdJVDp3ZSxBTFBIQTpIQSxBTFBIQV9ESUdJVDpIQStIQS50b1VwcGVyQ2FzZSgpK3dlfSwkdD0oQT0xNixlPVVlLkFMUEhBX0RJR0lUKT0+e2xldCB0PSIiLHtsZW5ndGg6SX09ZTtmb3IoO0EtLTspdCs9ZVtNYXRoLnJhbmRvbSgpKkl8MF07cmV0dXJuIHR9O2Z1bmN0aW9uIEFJKEEpe3JldHVybiEhKEEmJkcoQS5hcHBlbmQpJiZBW1N5bWJvbC50b1N0cmluZ1RhZ109PT0iRm9ybURhdGEiJiZBW1N5bWJvbC5pdGVyYXRvcl0pfXZhciBlST1BPT57bGV0IGU9bmV3IEFycmF5KDEwKSx0PShJLHIpPT57aWYodUEoSSkpe2lmKGUuaW5kZXhPZihJKT49MClyZXR1cm47aWYoISgidG9KU09OImluIEkpKXtlW3JdPUk7bGV0IGk9UChJKT9bXTp7fTtyZXR1cm4gJChJLChnLG4pPT57bGV0IEU9dChnLHIrMSk7IXYoRSkmJihpW25dPUUpfSksZVtyXT12b2lkIDAsaX19cmV0dXJuIEl9O3JldHVybiB0KEEsMCl9LHRJPWsoIkFzeW5jRnVuY3Rpb24iKSxJST1BPT5BJiYodUEoQSl8fEcoQSkpJiZHKEEudGhlbikmJkcoQS5jYXRjaCkscz17aXNBcnJheTpQLGlzQXJyYXlCdWZmZXI6cGUsaXNCdWZmZXI6cHQsaXNGb3JtRGF0YTpPdCxpc0FycmF5QnVmZmVyVmlldzpGdCxpc1N0cmluZzpTdCxpc051bWJlcjpGZSxpc0Jvb2xlYW46TnQsaXNPYmplY3Q6dUEsaXNQbGFpbk9iamVjdDpjQSxpc1VuZGVmaW5lZDp2LGlzRGF0ZTpSdCxpc0ZpbGU6R3QsaXNCbG9iOlV0LGlzUmVnRXhwOl90LGlzRnVuY3Rpb246Ryxpc1N0cmVhbTpMdCxpc1VSTFNlYXJjaFBhcmFtczpKdCxpc1R5cGVkQXJyYXk6eHQsaXNGaWxlTGlzdDprdCxmb3JFYWNoOiQsbWVyZ2U6WUEsZXh0ZW5kOmJ0LHRyaW06TXQsc3RyaXBCT006SHQsaW5oZXJpdHM6WXQsdG9GbGF0T2JqZWN0OnF0LGtpbmRPZjpmQSxraW5kT2ZUZXN0OmssZW5kc1dpdGg6VHQsdG9BcnJheTpLdCxmb3JFYWNoRW50cnk6UHQsbWF0Y2hBbGw6V3QsaXNIVE1MRm9ybTpqdCxoYXNPd25Qcm9wZXJ0eTp5ZSxoYXNPd25Qcm9wOnllLHJlZHVjZURlc2NyaXB0b3JzOkdlLGZyZWV6ZU1ldGhvZHM6VnQsdG9PYmplY3RTZXQ6enQsdG9DYW1lbENhc2U6WnQsbm9vcDpYdCx0b0Zpbml0ZU51bWJlcjp2dCxmaW5kS2V5OlNlLGdsb2JhbDpOZSxpc0NvbnRleHREZWZpbmVkOlJlLEFMUEhBQkVUOlVlLGdlbmVyYXRlU3RyaW5nOiR0LGlzU3BlY0NvbXBsaWFudEZvcm06QUksdG9KU09OT2JqZWN0OmVJLGlzQXN5bmNGbjp0SSxpc1RoZW5hYmxlOklJfTtmdW5jdGlvbiBXKEEsZSx0LEkscil7RXJyb3IuY2FsbCh0aGlzKSxFcnJvci5jYXB0dXJlU3RhY2tUcmFjZT9FcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLHRoaXMuY29uc3RydWN0b3IpOnRoaXMuc3RhY2s9bmV3IEVycm9yKCkuc3RhY2ssdGhpcy5tZXNzYWdlPUEsdGhpcy5uYW1lPSJBeGlvc0Vycm9yIixlJiYodGhpcy5jb2RlPWUpLHQmJih0aGlzLmNvbmZpZz10KSxJJiYodGhpcy5yZXF1ZXN0PUkpLHImJih0aGlzLnJlc3BvbnNlPXIpfXMuaW5oZXJpdHMoVyxFcnJvcix7dG9KU09OOmZ1bmN0aW9uKCl7cmV0dXJue21lc3NhZ2U6dGhpcy5tZXNzYWdlLG5hbWU6dGhpcy5uYW1lLGRlc2NyaXB0aW9uOnRoaXMuZGVzY3JpcHRpb24sbnVtYmVyOnRoaXMubnVtYmVyLGZpbGVOYW1lOnRoaXMuZmlsZU5hbWUsbGluZU51bWJlcjp0aGlzLmxpbmVOdW1iZXIsY29sdW1uTnVtYmVyOnRoaXMuY29sdW1uTnVtYmVyLHN0YWNrOnRoaXMuc3RhY2ssY29uZmlnOnMudG9KU09OT2JqZWN0KHRoaXMuY29uZmlnKSxjb2RlOnRoaXMuY29kZSxzdGF0dXM6dGhpcy5yZXNwb25zZSYmdGhpcy5yZXNwb25zZS5zdGF0dXM/dGhpcy5yZXNwb25zZS5zdGF0dXM6bnVsbH19fSk7dmFyIGtlPVcucHJvdG90eXBlLExlPXt9O1siRVJSX0JBRF9PUFRJT05fVkFMVUUiLCJFUlJfQkFEX09QVElPTiIsIkVDT05OQUJPUlRFRCIsIkVUSU1FRE9VVCIsIkVSUl9ORVRXT1JLIiwiRVJSX0ZSX1RPT19NQU5ZX1JFRElSRUNUUyIsIkVSUl9ERVBSRUNBVEVEIiwiRVJSX0JBRF9SRVNQT05TRSIsIkVSUl9CQURfUkVRVUVTVCIsIkVSUl9DQU5DRUxFRCIsIkVSUl9OT1RfU1VQUE9SVCIsIkVSUl9JTlZBTElEX1VSTCJdLmZvckVhY2goQT0+e0xlW0FdPXt2YWx1ZTpBfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFcsTGUpO09iamVjdC5kZWZpbmVQcm9wZXJ0eShrZSwiaXNBeGlvc0Vycm9yIix7dmFsdWU6ITB9KTtXLmZyb209KEEsZSx0LEkscixpKT0+e2xldCBnPU9iamVjdC5jcmVhdGUoa2UpO3JldHVybiBzLnRvRmxhdE9iamVjdChBLGcsZnVuY3Rpb24oRSl7cmV0dXJuIEUhPT1FcnJvci5wcm90b3R5cGV9LG49Pm4hPT0iaXNBeGlvc0Vycm9yIiksVy5jYWxsKGcsQS5tZXNzYWdlLGUsdCxJLHIpLGcuY2F1c2U9QSxnLm5hbWU9QS5uYW1lLGkmJk9iamVjdC5hc3NpZ24oZyxpKSxnfTt2YXIgbD1XO3ZhciBkQT1udWxsO2Z1bmN0aW9uIFRBKEEpe3JldHVybiBzLmlzUGxhaW5PYmplY3QoQSl8fHMuaXNBcnJheShBKX1mdW5jdGlvbiBKZShBKXtyZXR1cm4gcy5lbmRzV2l0aChBLCJbXSIpP0Euc2xpY2UoMCwtMik6QX1mdW5jdGlvbiBPZShBLGUsdCl7cmV0dXJuIEE/QS5jb25jYXQoZSkubWFwKGZ1bmN0aW9uKHIsaSl7cmV0dXJuIHI9SmUociksIXQmJmk/IlsiK3IrIl0iOnJ9KS5qb2luKHQ/Ii4iOiIiKTplfWZ1bmN0aW9uIHJJKEEpe3JldHVybiBzLmlzQXJyYXkoQSkmJiFBLnNvbWUoVEEpfXZhciBpST1zLnRvRmxhdE9iamVjdChzLHt9LG51bGwsZnVuY3Rpb24oZSl7cmV0dXJuL15pc1tBLVpdLy50ZXN0KGUpfSk7ZnVuY3Rpb24gZ0koQSxlLHQpe2lmKCFzLmlzT2JqZWN0KEEpKXRocm93IG5ldyBUeXBlRXJyb3IoInRhcmdldCBtdXN0IGJlIGFuIG9iamVjdCIpO2U9ZXx8bmV3KGRBfHxGb3JtRGF0YSksdD1zLnRvRmxhdE9iamVjdCh0LHttZXRhVG9rZW5zOiEwLGRvdHM6ITEsaW5kZXhlczohMX0sITEsZnVuY3Rpb24oZixkKXtyZXR1cm4hcy5pc1VuZGVmaW5lZChkW2ZdKX0pO2xldCBJPXQubWV0YVRva2VucyxyPXQudmlzaXRvcnx8byxpPXQuZG90cyxnPXQuaW5kZXhlcyxFPSh0LkJsb2J8fHR5cGVvZiBCbG9iPCJ1IiYmQmxvYikmJnMuaXNTcGVjQ29tcGxpYW50Rm9ybShlKTtpZighcy5pc0Z1bmN0aW9uKHIpKXRocm93IG5ldyBUeXBlRXJyb3IoInZpc2l0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uIik7ZnVuY3Rpb24gQyhRKXtpZihRPT09bnVsbClyZXR1cm4iIjtpZihzLmlzRGF0ZShRKSlyZXR1cm4gUS50b0lTT1N0cmluZygpO2lmKCFFJiZzLmlzQmxvYihRKSl0aHJvdyBuZXcgbCgiQmxvYiBpcyBub3Qgc3VwcG9ydGVkLiBVc2UgYSBCdWZmZXIgaW5zdGVhZC4iKTtyZXR1cm4gcy5pc0FycmF5QnVmZmVyKFEpfHxzLmlzVHlwZWRBcnJheShRKT9FJiZ0eXBlb2YgQmxvYj09ImZ1bmN0aW9uIj9uZXcgQmxvYihbUV0pOkJ1ZmZlci5mcm9tKFEpOlF9ZnVuY3Rpb24gbyhRLGYsZCl7bGV0IEY9UTtpZihRJiYhZCYmdHlwZW9mIFE9PSJvYmplY3QiKXtpZihzLmVuZHNXaXRoKGYsInt9IikpZj1JP2Y6Zi5zbGljZSgwLC0yKSxRPUpTT04uc3RyaW5naWZ5KFEpO2Vsc2UgaWYocy5pc0FycmF5KFEpJiZySShRKXx8KHMuaXNGaWxlTGlzdChRKXx8cy5lbmRzV2l0aChmLCJbXSIpKSYmKEY9cy50b0FycmF5KFEpKSlyZXR1cm4gZj1KZShmKSxGLmZvckVhY2goZnVuY3Rpb24oSyxPQSl7IShzLmlzVW5kZWZpbmVkKEspfHxLPT09bnVsbCkmJmUuYXBwZW5kKGc9PT0hMD9PZShbZl0sT0EsaSk6Zz09PW51bGw/ZjpmKyJbXSIsQyhLKSl9KSwhMX1yZXR1cm4gVEEoUSk/ITA6KGUuYXBwZW5kKE9lKGQsZixpKSxDKFEpKSwhMSl9bGV0IGM9W10sYT1PYmplY3QuYXNzaWduKGlJLHtkZWZhdWx0VmlzaXRvcjpvLGNvbnZlcnRWYWx1ZTpDLGlzVmlzaXRhYmxlOlRBfSk7ZnVuY3Rpb24gQihRLGYpe2lmKCFzLmlzVW5kZWZpbmVkKFEpKXtpZihjLmluZGV4T2YoUSkhPT0tMSl0aHJvdyBFcnJvcigiQ2lyY3VsYXIgcmVmZXJlbmNlIGRldGVjdGVkIGluICIrZi5qb2luKCIuIikpO2MucHVzaChRKSxzLmZvckVhY2goUSxmdW5jdGlvbihGLFIpeyghKHMuaXNVbmRlZmluZWQoRil8fEY9PT1udWxsKSYmci5jYWxsKGUsRixzLmlzU3RyaW5nKFIpP1IudHJpbSgpOlIsZixhKSk9PT0hMCYmQihGLGY/Zi5jb25jYXQoUik6W1JdKX0pLGMucG9wKCl9fWlmKCFzLmlzT2JqZWN0KEEpKXRocm93IG5ldyBUeXBlRXJyb3IoImRhdGEgbXVzdCBiZSBhbiBvYmplY3QiKTtyZXR1cm4gQihBKSxlfXZhciBKPWdJO2Z1bmN0aW9uIE1lKEEpe2xldCBlPXsiISI6IiUyNTIxIiwiXCciOiIlMjUyNyIsIigiOiIlMjUyOCIsIikiOiIlMjUyOSIsIn4iOiIlMjU3RSIsIiUyNTIwIjoiKyIsIiUyNTAwIjoiXFwwIn07cmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChBKS5yZXBsYWNlKC9bIVwnKCl+XXwlMjUyMHwlMjUwMC9nLGZ1bmN0aW9uKEkpe3JldHVybiBlW0ldfSl9ZnVuY3Rpb24gYmUoQSxlKXt0aGlzLl9wYWlycz1bXSxBJiZKKEEsdGhpcyxlKX12YXIgSGU9YmUucHJvdG90eXBlO0hlLmFwcGVuZD1mdW5jdGlvbihlLHQpe3RoaXMuX3BhaXJzLnB1c2goW2UsdF0pfTtIZS50b1N0cmluZz1mdW5jdGlvbihlKXtsZXQgdD1lP2Z1bmN0aW9uKEkpe3JldHVybiBlLmNhbGwodGhpcyxJLE1lKX06TWU7cmV0dXJuIHRoaXMuX3BhaXJzLm1hcChmdW5jdGlvbihyKXtyZXR1cm4gdChyWzBdKSsiPSIrdChyWzFdKX0sIiIpLmpvaW4oIiYiKX07dmFyIGhBPWJlO2Z1bmN0aW9uIG9JKEEpe3JldHVybiBlbmNvZGVVUklDb21wb25lbnQoQSkucmVwbGFjZSgvJTI1M0EvZ2ksIjoiKS5yZXBsYWNlKC8lMjUyNC9nLCIkIikucmVwbGFjZSgvJTI1MkMvZ2ksIiwiKS5yZXBsYWNlKC8lMjUyMC9nLCIrIikucmVwbGFjZSgvJTI1NUIvZ2ksIlsiKS5yZXBsYWNlKC8lMjU1RC9naSwiXSIpfWZ1bmN0aW9uIEFBKEEsZSx0KXtpZighZSlyZXR1cm4gQTtsZXQgST10JiZ0LmVuY29kZXx8b0kscj10JiZ0LnNlcmlhbGl6ZSxpO2lmKHI/aT1yKGUsdCk6aT1zLmlzVVJMU2VhcmNoUGFyYW1zKGUpP2UudG9TdHJpbmcoKTpuZXcgaEEoZSx0KS50b1N0cmluZyhJKSxpKXtsZXQgZz1BLmluZGV4T2YoIiUyMyIpO2chPT0tMSYmKEE9QS5zbGljZSgwLGcpKSxBKz0oQS5pbmRleE9mKCI/Iik9PT0tMT8iPyI6IiYiKStpfXJldHVybiBBfXZhciBLQT1jbGFzc3tjb25zdHJ1Y3Rvcigpe3RoaXMuaGFuZGxlcnM9W119dXNlKGUsdCxJKXtyZXR1cm4gdGhpcy5oYW5kbGVycy5wdXNoKHtmdWxmaWxsZWQ6ZSxyZWplY3RlZDp0LHN5bmNocm9ub3VzOkk/SS5zeW5jaHJvbm91czohMSxydW5XaGVuOkk/SS5ydW5XaGVuOm51bGx9KSx0aGlzLmhhbmRsZXJzLmxlbmd0aC0xfWVqZWN0KGUpe3RoaXMuaGFuZGxlcnNbZV0mJih0aGlzLmhhbmRsZXJzW2VdPW51bGwpfWNsZWFyKCl7dGhpcy5oYW5kbGVycyYmKHRoaXMuaGFuZGxlcnM9W10pfWZvckVhY2goZSl7cy5mb3JFYWNoKHRoaXMuaGFuZGxlcnMsZnVuY3Rpb24oSSl7SSE9PW51bGwmJmUoSSl9KX19LHhBPUtBO3ZhciBtQT17c2lsZW50SlNPTlBhcnNpbmc6ITAsZm9yY2VkSlNPTlBhcnNpbmc6ITAsY2xhcmlmeVRpbWVvdXRFcnJvcjohMX07dmFyIFllPXR5cGVvZiBVUkxTZWFyY2hQYXJhbXM8InUiP1VSTFNlYXJjaFBhcmFtczpoQTt2YXIgcWU9dHlwZW9mIEZvcm1EYXRhPCJ1Ij9Gb3JtRGF0YTpudWxsO3ZhciBUZT10eXBlb2YgQmxvYjwidSI/QmxvYjpudWxsO3ZhciBuST0oKCk9PntsZXQgQTtyZXR1cm4gdHlwZW9mIG5hdmlnYXRvcjwidSImJigoQT1uYXZpZ2F0b3IucHJvZHVjdCk9PT0iUmVhY3ROYXRpdmUifHxBPT09Ik5hdGl2ZVNjcmlwdCJ8fEE9PT0iTlMiKT8hMTp0eXBlb2Ygd2luZG93PCJ1IiYmdHlwZW9mIGRvY3VtZW50PCJ1In0pKCksYUk9KCgpPT50eXBlb2YgV29ya2VyR2xvYmFsU2NvcGU8InUiJiZzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGUmJnR5cGVvZiBzZWxmLmltcG9ydFNjcmlwdHM9PSJmdW5jdGlvbiIpKCksRD17aXNCcm93c2VyOiEwLGNsYXNzZXM6e1VSTFNlYXJjaFBhcmFtczpZZSxGb3JtRGF0YTpxZSxCbG9iOlRlfSxpc1N0YW5kYXJkQnJvd3NlckVudjpuSSxpc1N0YW5kYXJkQnJvd3NlcldlYldvcmtlckVudjphSSxwcm90b2NvbHM6WyJodHRwIiwiaHR0cHMiLCJmaWxlIiwiYmxvYiIsInVybCIsImRhdGEiXX07ZnVuY3Rpb24gUEEoQSxlKXtyZXR1cm4gSihBLG5ldyBELmNsYXNzZXMuVVJMU2VhcmNoUGFyYW1zLE9iamVjdC5hc3NpZ24oe3Zpc2l0b3I6ZnVuY3Rpb24odCxJLHIsaSl7cmV0dXJuIEQuaXNOb2RlJiZzLmlzQnVmZmVyKHQpPyh0aGlzLmFwcGVuZChJLHQudG9TdHJpbmcoImJhc2U2NCIpKSwhMSk6aS5kZWZhdWx0VmlzaXRvci5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fSxlKSl9ZnVuY3Rpb24gc0koQSl7cmV0dXJuIHMubWF0Y2hBbGwoL1xcdyt8XFxbKFxcdyopXS9nLEEpLm1hcChlPT5lWzBdPT09IltdIj8iIjplWzFdfHxlWzBdKX1mdW5jdGlvbiBDSShBKXtsZXQgZT17fSx0PU9iamVjdC5rZXlzKEEpLEkscj10Lmxlbmd0aCxpO2ZvcihJPTA7STxyO0krKylpPXRbSV0sZVtpXT1BW2ldO3JldHVybiBlfWZ1bmN0aW9uIEJJKEEpe2Z1bmN0aW9uIGUodCxJLHIsaSl7bGV0IGc9dFtpKytdLG49TnVtYmVyLmlzRmluaXRlKCtnKSxFPWk+PXQubGVuZ3RoO3JldHVybiBnPSFnJiZzLmlzQXJyYXkocik/ci5sZW5ndGg6ZyxFPyhzLmhhc093blByb3AocixnKT9yW2ddPVtyW2ddLEldOnJbZ109SSwhbik6KCghcltnXXx8IXMuaXNPYmplY3QocltnXSkpJiYocltnXT1bXSksZSh0LEkscltnXSxpKSYmcy5pc0FycmF5KHJbZ10pJiYocltnXT1DSShyW2ddKSksIW4pfWlmKHMuaXNGb3JtRGF0YShBKSYmcy5pc0Z1bmN0aW9uKEEuZW50cmllcykpe2xldCB0PXt9O3JldHVybiBzLmZvckVhY2hFbnRyeShBLChJLHIpPT57ZShzSShJKSxyLHQsMCl9KSx0fXJldHVybiBudWxsfXZhciBEQT1CSTtmdW5jdGlvbiBRSShBLGUsdCl7aWYocy5pc1N0cmluZyhBKSl0cnl7cmV0dXJuKGV8fEpTT04ucGFyc2UpKEEpLHMudHJpbShBKX1jYXRjaChJKXtpZihJLm5hbWUhPT0iU3ludGF4RXJyb3IiKXRocm93IEl9cmV0dXJuKHR8fEpTT04uc3RyaW5naWZ5KShBKX12YXIgV0E9e3RyYW5zaXRpb25hbDptQSxhZGFwdGVyOlsieGhyIiwiaHR0cCJdLHRyYW5zZm9ybVJlcXVlc3Q6W2Z1bmN0aW9uKGUsdCl7bGV0IEk9dC5nZXRDb250ZW50VHlwZSgpfHwiIixyPUkuaW5kZXhPZigiYXBwbGljYXRpb24vanNvbiIpPi0xLGk9cy5pc09iamVjdChlKTtpZihpJiZzLmlzSFRNTEZvcm0oZSkmJihlPW5ldyBGb3JtRGF0YShlKSkscy5pc0Zvcm1EYXRhKGUpKXJldHVybiByJiZyP0pTT04uc3RyaW5naWZ5KERBKGUpKTplO2lmKHMuaXNBcnJheUJ1ZmZlcihlKXx8cy5pc0J1ZmZlcihlKXx8cy5pc1N0cmVhbShlKXx8cy5pc0ZpbGUoZSl8fHMuaXNCbG9iKGUpKXJldHVybiBlO2lmKHMuaXNBcnJheUJ1ZmZlclZpZXcoZSkpcmV0dXJuIGUuYnVmZmVyO2lmKHMuaXNVUkxTZWFyY2hQYXJhbXMoZSkpcmV0dXJuIHQuc2V0Q29udGVudFR5cGUoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PXV0Zi04IiwhMSksZS50b1N0cmluZygpO2xldCBuO2lmKGkpe2lmKEkuaW5kZXhPZigiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIik+LTEpcmV0dXJuIFBBKGUsdGhpcy5mb3JtU2VyaWFsaXplcikudG9TdHJpbmcoKTtpZigobj1zLmlzRmlsZUxpc3QoZSkpfHxJLmluZGV4T2YoIm11bHRpcGFydC9mb3JtLWRhdGEiKT4tMSl7bGV0IEU9dGhpcy5lbnYmJnRoaXMuZW52LkZvcm1EYXRhO3JldHVybiBKKG4/eyJmaWxlc1tdIjplfTplLEUmJm5ldyBFLHRoaXMuZm9ybVNlcmlhbGl6ZXIpfX1yZXR1cm4gaXx8cj8odC5zZXRDb250ZW50VHlwZSgiYXBwbGljYXRpb24vanNvbiIsITEpLFFJKGUpKTplfV0sdHJhbnNmb3JtUmVzcG9uc2U6W2Z1bmN0aW9uKGUpe2xldCB0PXRoaXMudHJhbnNpdGlvbmFsfHxXQS50cmFuc2l0aW9uYWwsST10JiZ0LmZvcmNlZEpTT05QYXJzaW5nLHI9dGhpcy5yZXNwb25zZVR5cGU9PT0ianNvbiI7aWYoZSYmcy5pc1N0cmluZyhlKSYmKEkmJiF0aGlzLnJlc3BvbnNlVHlwZXx8cikpe2xldCBnPSEodCYmdC5zaWxlbnRKU09OUGFyc2luZykmJnI7dHJ5e3JldHVybiBKU09OLnBhcnNlKGUpfWNhdGNoKG4pe2lmKGcpdGhyb3cgbi5uYW1lPT09IlN5bnRheEVycm9yIj9sLmZyb20obixsLkVSUl9CQURfUkVTUE9OU0UsdGhpcyxudWxsLHRoaXMucmVzcG9uc2UpOm59fXJldHVybiBlfV0sdGltZW91dDowLHhzcmZDb29raWVOYW1lOiJYU1JGLVRPS0VOIix4c3JmSGVhZGVyTmFtZToiWC1YU1JGLVRPS0VOIixtYXhDb250ZW50TGVuZ3RoOi0xLG1heEJvZHlMZW5ndGg6LTEsZW52OntGb3JtRGF0YTpELmNsYXNzZXMuRm9ybURhdGEsQmxvYjpELmNsYXNzZXMuQmxvYn0sdmFsaWRhdGVTdGF0dXM6ZnVuY3Rpb24oZSl7cmV0dXJuIGU+PTIwMCYmZTwzMDB9LGhlYWRlcnM6e2NvbW1vbjp7QWNjZXB0OiJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyoiLCJDb250ZW50LVR5cGUiOnZvaWQgMH19fTtzLmZvckVhY2goWyJkZWxldGUiLCJnZXQiLCJoZWFkIiwicG9zdCIsInB1dCIsInBhdGNoIl0sQT0+e1dBLmhlYWRlcnNbQV09e319KTt2YXIgaj1XQTt2YXIgRUk9cy50b09iamVjdFNldChbImFnZSIsImF1dGhvcml6YXRpb24iLCJjb250ZW50LWxlbmd0aCIsImNvbnRlbnQtdHlwZSIsImV0YWciLCJleHBpcmVzIiwiZnJvbSIsImhvc3QiLCJpZi1tb2RpZmllZC1zaW5jZSIsImlmLXVubW9kaWZpZWQtc2luY2UiLCJsYXN0LW1vZGlmaWVkIiwibG9jYXRpb24iLCJtYXgtZm9yd2FyZHMiLCJwcm94eS1hdXRob3JpemF0aW9uIiwicmVmZXJlciIsInJldHJ5LWFmdGVyIiwidXNlci1hZ2VudCJdKSxLZT1BPT57bGV0IGU9e30sdCxJLHI7cmV0dXJuIEEmJkEuc3BsaXQoYCUwQWApLmZvckVhY2goZnVuY3Rpb24oZyl7cj1nLmluZGV4T2YoIjoiKSx0PWcuc3Vic3RyaW5nKDAscikudHJpbSgpLnRvTG93ZXJDYXNlKCksST1nLnN1YnN0cmluZyhyKzEpLnRyaW0oKSwhKCF0fHxlW3RdJiZFSVt0XSkmJih0PT09InNldC1jb29raWUiP2VbdF0/ZVt0XS5wdXNoKEkpOmVbdF09W0ldOmVbdF09ZVt0XT9lW3RdKyIsICIrSTpJKX0pLGV9O3ZhciB4ZT1TeW1ib2woImludGVybmFscyIpO2Z1bmN0aW9uIGVBKEEpe3JldHVybiBBJiZTdHJpbmcoQSkudHJpbSgpLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24geUEoQSl7cmV0dXJuIEE9PT0hMXx8QT09bnVsbD9BOnMuaXNBcnJheShBKT9BLm1hcCh5QSk6U3RyaW5nKEEpfWZ1bmN0aW9uIGNJKEEpe2xldCBlPU9iamVjdC5jcmVhdGUobnVsbCksdD0vKFteXFxzLDs9XSspXFxzKig/Oj1cXHMqKFteLDtdKykpPy9nLEk7Zm9yKDtJPXQuZXhlYyhBKTspZVtJWzFdXT1JWzJdO3JldHVybiBlfXZhciBmST1BPT4vXlstX2EtekEtWjAtOV5gfH4sISUyMyQlJlwnKisuXSskLy50ZXN0KEEudHJpbSgpKTtmdW5jdGlvbiBqQShBLGUsdCxJLHIpe2lmKHMuaXNGdW5jdGlvbihJKSlyZXR1cm4gSS5jYWxsKHRoaXMsZSx0KTtpZihyJiYoZT10KSwhIXMuaXNTdHJpbmcoZSkpe2lmKHMuaXNTdHJpbmcoSSkpcmV0dXJuIGUuaW5kZXhPZihJKSE9PS0xO2lmKHMuaXNSZWdFeHAoSSkpcmV0dXJuIEkudGVzdChlKX19ZnVuY3Rpb24gbEkoQSl7cmV0dXJuIEEudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvKFthLXpcXGRdKShcXHcqKS9nLChlLHQsSSk9PnQudG9VcHBlckNhc2UoKStJKX1mdW5jdGlvbiB1SShBLGUpe2xldCB0PXMudG9DYW1lbENhc2UoIiAiK2UpO1siZ2V0Iiwic2V0IiwiaGFzIl0uZm9yRWFjaChJPT57T2JqZWN0LmRlZmluZVByb3BlcnR5KEEsSSt0LHt2YWx1ZTpmdW5jdGlvbihyLGksZyl7cmV0dXJuIHRoaXNbSV0uY2FsbCh0aGlzLGUscixpLGcpfSxjb25maWd1cmFibGU6ITB9KX0pfXZhciBaPWNsYXNze2NvbnN0cnVjdG9yKGUpe2UmJnRoaXMuc2V0KGUpfXNldChlLHQsSSl7bGV0IHI9dGhpcztmdW5jdGlvbiBpKG4sRSxDKXtsZXQgbz1lQShFKTtpZighbyl0aHJvdyBuZXcgRXJyb3IoImhlYWRlciBuYW1lIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nIik7bGV0IGM9cy5maW5kS2V5KHIsbyk7KCFjfHxyW2NdPT09dm9pZCAwfHxDPT09ITB8fEM9PT12b2lkIDAmJnJbY10hPT0hMSkmJihyW2N8fEVdPXlBKG4pKX1sZXQgZz0obixFKT0+cy5mb3JFYWNoKG4sKEMsbyk9PmkoQyxvLEUpKTtyZXR1cm4gcy5pc1BsYWluT2JqZWN0KGUpfHxlIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3Rvcj9nKGUsdCk6cy5pc1N0cmluZyhlKSYmKGU9ZS50cmltKCkpJiYhZkkoZSk/ZyhLZShlKSx0KTplIT1udWxsJiZpKHQsZSxJKSx0aGlzfWdldChlLHQpe2lmKGU9ZUEoZSksZSl7bGV0IEk9cy5maW5kS2V5KHRoaXMsZSk7aWYoSSl7bGV0IHI9dGhpc1tJXTtpZighdClyZXR1cm4gcjtpZih0PT09ITApcmV0dXJuIGNJKHIpO2lmKHMuaXNGdW5jdGlvbih0KSlyZXR1cm4gdC5jYWxsKHRoaXMscixJKTtpZihzLmlzUmVnRXhwKHQpKXJldHVybiB0LmV4ZWMocik7dGhyb3cgbmV3IFR5cGVFcnJvcigicGFyc2VyIG11c3QgYmUgYm9vbGVhbnxyZWdleHB8ZnVuY3Rpb24iKX19fWhhcyhlLHQpe2lmKGU9ZUEoZSksZSl7bGV0IEk9cy5maW5kS2V5KHRoaXMsZSk7cmV0dXJuISEoSSYmdGhpc1tJXSE9PXZvaWQgMCYmKCF0fHxqQSh0aGlzLHRoaXNbSV0sSSx0KSkpfXJldHVybiExfWRlbGV0ZShlLHQpe2xldCBJPXRoaXMscj0hMTtmdW5jdGlvbiBpKGcpe2lmKGc9ZUEoZyksZyl7bGV0IG49cy5maW5kS2V5KEksZyk7biYmKCF0fHxqQShJLElbbl0sbix0KSkmJihkZWxldGUgSVtuXSxyPSEwKX19cmV0dXJuIHMuaXNBcnJheShlKT9lLmZvckVhY2goaSk6aShlKSxyfWNsZWFyKGUpe2xldCB0PU9iamVjdC5rZXlzKHRoaXMpLEk9dC5sZW5ndGgscj0hMTtmb3IoO0ktLTspe2xldCBpPXRbSV07KCFlfHxqQSh0aGlzLHRoaXNbaV0saSxlLCEwKSkmJihkZWxldGUgdGhpc1tpXSxyPSEwKX1yZXR1cm4gcn1ub3JtYWxpemUoZSl7bGV0IHQ9dGhpcyxJPXt9O3JldHVybiBzLmZvckVhY2godGhpcywocixpKT0+e2xldCBnPXMuZmluZEtleShJLGkpO2lmKGcpe3RbZ109eUEociksZGVsZXRlIHRbaV07cmV0dXJufWxldCBuPWU/bEkoaSk6U3RyaW5nKGkpLnRyaW0oKTtuIT09aSYmZGVsZXRlIHRbaV0sdFtuXT15QShyKSxJW25dPSEwfSksdGhpc31jb25jYXQoLi4uZSl7cmV0dXJuIHRoaXMuY29uc3RydWN0b3IuY29uY2F0KHRoaXMsLi4uZSl9dG9KU09OKGUpe2xldCB0PU9iamVjdC5jcmVhdGUobnVsbCk7cmV0dXJuIHMuZm9yRWFjaCh0aGlzLChJLHIpPT57SSE9bnVsbCYmSSE9PSExJiYodFtyXT1lJiZzLmlzQXJyYXkoSSk/SS5qb2luKCIsICIpOkkpfSksdH1bU3ltYm9sLml0ZXJhdG9yXSgpe3JldHVybiBPYmplY3QuZW50cmllcyh0aGlzLnRvSlNPTigpKVtTeW1ib2wuaXRlcmF0b3JdKCl9dG9TdHJpbmcoKXtyZXR1cm4gT2JqZWN0LmVudHJpZXModGhpcy50b0pTT04oKSkubWFwKChbZSx0XSk9PmUrIjogIit0KS5qb2luKGAlMEFgKX1nZXRbU3ltYm9sLnRvU3RyaW5nVGFnXSgpe3JldHVybiJBeGlvc0hlYWRlcnMifXN0YXRpYyBmcm9tKGUpe3JldHVybiBlIGluc3RhbmNlb2YgdGhpcz9lOm5ldyB0aGlzKGUpfXN0YXRpYyBjb25jYXQoZSwuLi50KXtsZXQgST1uZXcgdGhpcyhlKTtyZXR1cm4gdC5mb3JFYWNoKHI9Pkkuc2V0KHIpKSxJfXN0YXRpYyBhY2Nlc3NvcihlKXtsZXQgST0odGhpc1t4ZV09dGhpc1t4ZV09e2FjY2Vzc29yczp7fX0pLmFjY2Vzc29ycyxyPXRoaXMucHJvdG90eXBlO2Z1bmN0aW9uIGkoZyl7bGV0IG49ZUEoZyk7SVtuXXx8KHVJKHIsZyksSVtuXT0hMCl9cmV0dXJuIHMuaXNBcnJheShlKT9lLmZvckVhY2goaSk6aShlKSx0aGlzfX07Wi5hY2Nlc3NvcihbIkNvbnRlbnQtVHlwZSIsIkNvbnRlbnQtTGVuZ3RoIiwiQWNjZXB0IiwiQWNjZXB0LUVuY29kaW5nIiwiVXNlci1BZ2VudCIsIkF1dGhvcml6YXRpb24iXSk7cy5yZWR1Y2VEZXNjcmlwdG9ycyhaLnByb3RvdHlwZSwoe3ZhbHVlOkF9LGUpPT57bGV0IHQ9ZVswXS50b1VwcGVyQ2FzZSgpK2Uuc2xpY2UoMSk7cmV0dXJue2dldDooKT0+QSxzZXQoSSl7dGhpc1t0XT1JfX19KTtzLmZyZWV6ZU1ldGhvZHMoWik7dmFyIHc9WjtmdW5jdGlvbiB0QShBLGUpe2xldCB0PXRoaXN8fGosST1lfHx0LHI9dy5mcm9tKEkuaGVhZGVycyksaT1JLmRhdGE7cmV0dXJuIHMuZm9yRWFjaChBLGZ1bmN0aW9uKG4pe2k9bi5jYWxsKHQsaSxyLm5vcm1hbGl6ZSgpLGU/ZS5zdGF0dXM6dm9pZCAwKX0pLHIubm9ybWFsaXplKCksaX1mdW5jdGlvbiBJQShBKXtyZXR1cm4hIShBJiZBLl9fQ0FOQ0VMX18pfWZ1bmN0aW9uIFBlKEEsZSx0KXtsLmNhbGwodGhpcyxBPz8iY2FuY2VsZWQiLGwuRVJSX0NBTkNFTEVELGUsdCksdGhpcy5uYW1lPSJDYW5jZWxlZEVycm9yIn1zLmluaGVyaXRzKFBlLGwse19fQ0FOQ0VMX186ITB9KTt2YXIgTT1QZTtmdW5jdGlvbiBaQShBLGUsdCl7bGV0IEk9dC5jb25maWcudmFsaWRhdGVTdGF0dXM7IXQuc3RhdHVzfHwhSXx8SSh0LnN0YXR1cyk/QSh0KTplKG5ldyBsKCJSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlICIrdC5zdGF0dXMsW2wuRVJSX0JBRF9SRVFVRVNULGwuRVJSX0JBRF9SRVNQT05TRV1bTWF0aC5mbG9vcih0LnN0YXR1cy8xMDApLTRdLHQuY29uZmlnLHQucmVxdWVzdCx0KSl9dmFyIFdlPUQuaXNTdGFuZGFyZEJyb3dzZXJFbnY/ZnVuY3Rpb24oKXtyZXR1cm57d3JpdGU6ZnVuY3Rpb24odCxJLHIsaSxnLG4pe2xldCBFPVtdO0UucHVzaCh0KyI9IitlbmNvZGVVUklDb21wb25lbnQoSSkpLHMuaXNOdW1iZXIocikmJkUucHVzaCgiZXhwaXJlcz0iK25ldyBEYXRlKHIpLnRvR01UU3RyaW5nKCkpLHMuaXNTdHJpbmcoaSkmJkUucHVzaCgicGF0aD0iK2kpLHMuaXNTdHJpbmcoZykmJkUucHVzaCgiZG9tYWluPSIrZyksbj09PSEwJiZFLnB1c2goInNlY3VyZSIpLGRvY3VtZW50LmNvb2tpZT1FLmpvaW4oIjsgIil9LHJlYWQ6ZnVuY3Rpb24odCl7bGV0IEk9ZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoIihefDtcXFxccyopKCIrdCsiKT0oW147XSopIikpO3JldHVybiBJP2RlY29kZVVSSUNvbXBvbmVudChJWzNdKTpudWxsfSxyZW1vdmU6ZnVuY3Rpb24odCl7dGhpcy53cml0ZSh0LCIiLERhdGUubm93KCktODY0ZTUpfX19KCk6ZnVuY3Rpb24oKXtyZXR1cm57d3JpdGU6ZnVuY3Rpb24oKXt9LHJlYWQ6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0scmVtb3ZlOmZ1bmN0aW9uKCl7fX19KCk7ZnVuY3Rpb24gX0EoQSl7cmV0dXJuL14oW2Etel1bYS16XFxkK1xcLS5dKjopP1xcL1xcLy9pLnRlc3QoQSl9ZnVuY3Rpb24gVkEoQSxlKXtyZXR1cm4gZT9BLnJlcGxhY2UoL1xcLyskLywiIikrIi8iK2UucmVwbGFjZSgvXlxcLysvLCIiKTpBfWZ1bmN0aW9uIHJBKEEsZSl7cmV0dXJuIEEmJiFfQShlKT9WQShBLGUpOmV9dmFyIGplPUQuaXNTdGFuZGFyZEJyb3dzZXJFbnY/ZnVuY3Rpb24oKXtsZXQgZT0vKG1zaWV8dHJpZGVudCkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpLEk7ZnVuY3Rpb24gcihpKXtsZXQgZz1pO3JldHVybiBlJiYodC5zZXRBdHRyaWJ1dGUoImhyZWYiLGcpLGc9dC5ocmVmKSx0LnNldEF0dHJpYnV0ZSgiaHJlZiIsZykse2hyZWY6dC5ocmVmLHByb3RvY29sOnQucHJvdG9jb2w/dC5wcm90b2NvbC5yZXBsYWNlKC86JC8sIiIpOiIiLGhvc3Q6dC5ob3N0LHNlYXJjaDp0LnNlYXJjaD90LnNlYXJjaC5yZXBsYWNlKC9eXFw/LywiIik6IiIsaGFzaDp0Lmhhc2g/dC5oYXNoLnJlcGxhY2UoL14lMjMvLCIiKToiIixob3N0bmFtZTp0Lmhvc3RuYW1lLHBvcnQ6dC5wb3J0LHBhdGhuYW1lOnQucGF0aG5hbWUuY2hhckF0KDApPT09Ii8iP3QucGF0aG5hbWU6Ii8iK3QucGF0aG5hbWV9fXJldHVybiBJPXIod2luZG93LmxvY2F0aW9uLmhyZWYpLGZ1bmN0aW9uKGcpe2xldCBuPXMuaXNTdHJpbmcoZyk/cihnKTpnO3JldHVybiBuLnByb3RvY29sPT09SS5wcm90b2NvbCYmbi5ob3N0PT09SS5ob3N0fX0oKTpmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiEwfX0oKTtmdW5jdGlvbiB6QShBKXtsZXQgZT0vXihbLStcXHddezEsMjV9KSg6P1xcL1xcL3w6KS8uZXhlYyhBKTtyZXR1cm4gZSYmZVsxXXx8IiJ9ZnVuY3Rpb24gZEkoQSxlKXtBPUF8fDEwO2xldCB0PW5ldyBBcnJheShBKSxJPW5ldyBBcnJheShBKSxyPTAsaT0wLGc7cmV0dXJuIGU9ZSE9PXZvaWQgMD9lOjFlMyxmdW5jdGlvbihFKXtsZXQgQz1EYXRlLm5vdygpLG89SVtpXTtnfHwoZz1DKSx0W3JdPUUsSVtyXT1DO2xldCBjPWksYT0wO2Zvcig7YyE9PXI7KWErPXRbYysrXSxjPWMlQTtpZihyPShyKzEpJUEscj09PWkmJihpPShpKzEpJUEpLEMtZzxlKXJldHVybjtsZXQgQj1vJiZDLW87cmV0dXJuIEI/TWF0aC5yb3VuZChhKjFlMy9CKTp2b2lkIDB9fXZhciBaZT1kSTtmdW5jdGlvbiBfZShBLGUpe2xldCB0PTAsST1aZSg1MCwyNTApO3JldHVybiByPT57bGV0IGk9ci5sb2FkZWQsZz1yLmxlbmd0aENvbXB1dGFibGU/ci50b3RhbDp2b2lkIDAsbj1pLXQsRT1JKG4pLEM9aTw9Zzt0PWk7bGV0IG89e2xvYWRlZDppLHRvdGFsOmcscHJvZ3Jlc3M6Zz9pL2c6dm9pZCAwLGJ5dGVzOm4scmF0ZTpFfHx2b2lkIDAsZXN0aW1hdGVkOkUmJmcmJkM/KGctaSkvRTp2b2lkIDAsZXZlbnQ6cn07b1tlPyJkb3dubG9hZCI6InVwbG9hZCJdPSEwLEEobyl9fXZhciBoST10eXBlb2YgWE1MSHR0cFJlcXVlc3Q8InUiLFZlPWhJJiZmdW5jdGlvbihBKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24odCxJKXtsZXQgcj1BLmRhdGEsaT13LmZyb20oQS5oZWFkZXJzKS5ub3JtYWxpemUoKSxnPUEucmVzcG9uc2VUeXBlLG47ZnVuY3Rpb24gRSgpe0EuY2FuY2VsVG9rZW4mJkEuY2FuY2VsVG9rZW4udW5zdWJzY3JpYmUobiksQS5zaWduYWwmJkEuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoImFib3J0IixuKX1sZXQgQztzLmlzRm9ybURhdGEocikmJihELmlzU3RhbmRhcmRCcm93c2VyRW52fHxELmlzU3RhbmRhcmRCcm93c2VyV2ViV29ya2VyRW52P2kuc2V0Q29udGVudFR5cGUoITEpOmkuZ2V0Q29udGVudFR5cGUoL15cXHMqbXVsdGlwYXJ0XFwvZm9ybS1kYXRhLyk/cy5pc1N0cmluZyhDPWkuZ2V0Q29udGVudFR5cGUoKSkmJmkuc2V0Q29udGVudFR5cGUoQy5yZXBsYWNlKC9eXFxzKihtdWx0aXBhcnRcXC9mb3JtLWRhdGEpOysvLCIkMSIpKTppLnNldENvbnRlbnRUeXBlKCJtdWx0aXBhcnQvZm9ybS1kYXRhIikpO2xldCBvPW5ldyBYTUxIdHRwUmVxdWVzdDtpZihBLmF1dGgpe2xldCBRPUEuYXV0aC51c2VybmFtZXx8IiIsZj1BLmF1dGgucGFzc3dvcmQ/dW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEEuYXV0aC5wYXNzd29yZCkpOiIiO2kuc2V0KCJBdXRob3JpemF0aW9uIiwiQmFzaWMgIitidG9hKFErIjoiK2YpKX1sZXQgYz1yQShBLmJhc2VVUkwsQS51cmwpO28ub3BlbihBLm1ldGhvZC50b1VwcGVyQ2FzZSgpLEFBKGMsQS5wYXJhbXMsQS5wYXJhbXNTZXJpYWxpemVyKSwhMCksby50aW1lb3V0PUEudGltZW91dDtmdW5jdGlvbiBhKCl7aWYoIW8pcmV0dXJuO2xldCBRPXcuZnJvbSgiZ2V0QWxsUmVzcG9uc2VIZWFkZXJzImluIG8mJm8uZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpLGQ9e2RhdGE6IWd8fGc9PT0idGV4dCJ8fGc9PT0ianNvbiI/by5yZXNwb25zZVRleHQ6by5yZXNwb25zZSxzdGF0dXM6by5zdGF0dXMsc3RhdHVzVGV4dDpvLnN0YXR1c1RleHQsaGVhZGVyczpRLGNvbmZpZzpBLHJlcXVlc3Q6b307WkEoZnVuY3Rpb24oUil7dChSKSxFKCl9LGZ1bmN0aW9uKFIpe0koUiksRSgpfSxkKSxvPW51bGx9aWYoIm9ubG9hZGVuZCJpbiBvP28ub25sb2FkZW5kPWE6by5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXshb3x8by5yZWFkeVN0YXRlIT09NHx8by5zdGF0dXM9PT0wJiYhKG8ucmVzcG9uc2VVUkwmJm8ucmVzcG9uc2VVUkwuaW5kZXhPZigiZmlsZToiKT09PTApfHxzZXRUaW1lb3V0KGEpfSxvLm9uYWJvcnQ9ZnVuY3Rpb24oKXtvJiYoSShuZXcgbCgiUmVxdWVzdCBhYm9ydGVkIixsLkVDT05OQUJPUlRFRCxBLG8pKSxvPW51bGwpfSxvLm9uZXJyb3I9ZnVuY3Rpb24oKXtJKG5ldyBsKCJOZXR3b3JrIEVycm9yIixsLkVSUl9ORVRXT1JLLEEsbykpLG89bnVsbH0sby5vbnRpbWVvdXQ9ZnVuY3Rpb24oKXtsZXQgZj1BLnRpbWVvdXQ/InRpbWVvdXQgb2YgIitBLnRpbWVvdXQrIm1zIGV4Y2VlZGVkIjoidGltZW91dCBleGNlZWRlZCIsZD1BLnRyYW5zaXRpb25hbHx8bUE7QS50aW1lb3V0RXJyb3JNZXNzYWdlJiYoZj1BLnRpbWVvdXRFcnJvck1lc3NhZ2UpLEkobmV3IGwoZixkLmNsYXJpZnlUaW1lb3V0RXJyb3I/bC5FVElNRURPVVQ6bC5FQ09OTkFCT1JURUQsQSxvKSksbz1udWxsfSxELmlzU3RhbmRhcmRCcm93c2VyRW52KXtsZXQgUT1qZShjKSYmQS54c3JmQ29va2llTmFtZSYmV2UucmVhZChBLnhzcmZDb29raWVOYW1lKTtRJiZpLnNldChBLnhzcmZIZWFkZXJOYW1lLFEpfXI9PT12b2lkIDAmJmkuc2V0Q29udGVudFR5cGUobnVsbCksInNldFJlcXVlc3RIZWFkZXIiaW4gbyYmcy5mb3JFYWNoKGkudG9KU09OKCksZnVuY3Rpb24oZixkKXtvLnNldFJlcXVlc3RIZWFkZXIoZCxmKX0pLHMuaXNVbmRlZmluZWQoQS53aXRoQ3JlZGVudGlhbHMpfHwoby53aXRoQ3JlZGVudGlhbHM9ISFBLndpdGhDcmVkZW50aWFscyksZyYmZyE9PSJqc29uIiYmKG8ucmVzcG9uc2VUeXBlPUEucmVzcG9uc2VUeXBlKSx0eXBlb2YgQS5vbkRvd25sb2FkUHJvZ3Jlc3M9PSJmdW5jdGlvbiImJm8uYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLF9lKEEub25Eb3dubG9hZFByb2dyZXNzLCEwKSksdHlwZW9mIEEub25VcGxvYWRQcm9ncmVzcz09ImZ1bmN0aW9uIiYmby51cGxvYWQmJm8udXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoInByb2dyZXNzIixfZShBLm9uVXBsb2FkUHJvZ3Jlc3MpKSwoQS5jYW5jZWxUb2tlbnx8QS5zaWduYWwpJiYobj1RPT57byYmKEkoIVF8fFEudHlwZT9uZXcgTShudWxsLEEsbyk6USksby5hYm9ydCgpLG89bnVsbCl9LEEuY2FuY2VsVG9rZW4mJkEuY2FuY2VsVG9rZW4uc3Vic2NyaWJlKG4pLEEuc2lnbmFsJiYoQS5zaWduYWwuYWJvcnRlZD9uKCk6QS5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcigiYWJvcnQiLG4pKSk7bGV0IEI9ekEoYyk7aWYoQiYmRC5wcm90b2NvbHMuaW5kZXhPZihCKT09PS0xKXtJKG5ldyBsKCJVbnN1cHBvcnRlZCBwcm90b2NvbCAiK0IrIjoiLGwuRVJSX0JBRF9SRVFVRVNULEEpKTtyZXR1cm59by5zZW5kKHJ8fG51bGwpfSl9O3ZhciBYQT17aHR0cDpkQSx4aHI6VmV9O3MuZm9yRWFjaChYQSwoQSxlKT0+e2lmKEEpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkoQSwibmFtZSIse3ZhbHVlOmV9KX1jYXRjaHt9T2JqZWN0LmRlZmluZVByb3BlcnR5KEEsImFkYXB0ZXJOYW1lIix7dmFsdWU6ZX0pfX0pO3ZhciB6ZT1BPT5gLSAke0F9YCxtST1BPT5zLmlzRnVuY3Rpb24oQSl8fEE9PT1udWxsfHxBPT09ITEsd0E9e2dldEFkYXB0ZXI6QT0+e0E9cy5pc0FycmF5KEEpP0E6W0FdO2xldHtsZW5ndGg6ZX09QSx0LEkscj17fTtmb3IobGV0IGk9MDtpPGU7aSsrKXt0PUFbaV07bGV0IGc7aWYoST10LCFtSSh0KSYmKEk9WEFbKGc9U3RyaW5nKHQpKS50b0xvd2VyQ2FzZSgpXSxJPT09dm9pZCAwKSl0aHJvdyBuZXcgbChgVW5rbm93biBhZGFwdGVyIFwnJHtnfVwnYCk7aWYoSSlicmVhaztyW2d8fCIlMjMiK2ldPUl9aWYoIUkpe2xldCBpPU9iamVjdC5lbnRyaWVzKHIpLm1hcCgoW24sRV0pPT5gYWRhcHRlciAke259IGArKEU9PT0hMT8iaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQiOiJpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBidWlsZCIpKSxnPWU/aS5sZW5ndGg+MT9gc2luY2UgOiUwQWAraS5tYXAoemUpLmpvaW4oYCUwQWApOiIgIit6ZShpWzBdKToiYXMgbm8gYWRhcHRlciBzcGVjaWZpZWQiO3Rocm93IG5ldyBsKCJUaGVyZSBpcyBubyBzdWl0YWJsZSBhZGFwdGVyIHRvIGRpc3BhdGNoIHRoZSByZXF1ZXN0ICIrZywiRVJSX05PVF9TVVBQT1JUIil9cmV0dXJuIEl9LGFkYXB0ZXJzOlhBfTtmdW5jdGlvbiB2QShBKXtpZihBLmNhbmNlbFRva2VuJiZBLmNhbmNlbFRva2VuLnRocm93SWZSZXF1ZXN0ZWQoKSxBLnNpZ25hbCYmQS5zaWduYWwuYWJvcnRlZCl0aHJvdyBuZXcgTShudWxsLEEpfWZ1bmN0aW9uIHBBKEEpe3JldHVybiB2QShBKSxBLmhlYWRlcnM9dy5mcm9tKEEuaGVhZGVycyksQS5kYXRhPXRBLmNhbGwoQSxBLnRyYW5zZm9ybVJlcXVlc3QpLFsicG9zdCIsInB1dCIsInBhdGNoIl0uaW5kZXhPZihBLm1ldGhvZCkhPT0tMSYmQS5oZWFkZXJzLnNldENvbnRlbnRUeXBlKCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiLCExKSx3QS5nZXRBZGFwdGVyKEEuYWRhcHRlcnx8ai5hZGFwdGVyKShBKS50aGVuKGZ1bmN0aW9uKEkpe3JldHVybiB2QShBKSxJLmRhdGE9dEEuY2FsbChBLEEudHJhbnNmb3JtUmVzcG9uc2UsSSksSS5oZWFkZXJzPXcuZnJvbShJLmhlYWRlcnMpLEl9LGZ1bmN0aW9uKEkpe3JldHVybiBJQShJKXx8KHZBKEEpLEkmJkkucmVzcG9uc2UmJihJLnJlc3BvbnNlLmRhdGE9dEEuY2FsbChBLEEudHJhbnNmb3JtUmVzcG9uc2UsSS5yZXNwb25zZSksSS5yZXNwb25zZS5oZWFkZXJzPXcuZnJvbShJLnJlc3BvbnNlLmhlYWRlcnMpKSksUHJvbWlzZS5yZWplY3QoSSl9KX12YXIgWGU9QT0+QSBpbnN0YW5jZW9mIHc/QS50b0pTT04oKTpBO2Z1bmN0aW9uIEwoQSxlKXtlPWV8fHt9O2xldCB0PXt9O2Z1bmN0aW9uIEkoQyxvLGMpe3JldHVybiBzLmlzUGxhaW5PYmplY3QoQykmJnMuaXNQbGFpbk9iamVjdChvKT9zLm1lcmdlLmNhbGwoe2Nhc2VsZXNzOmN9LEMsbyk6cy5pc1BsYWluT2JqZWN0KG8pP3MubWVyZ2Uoe30sbyk6cy5pc0FycmF5KG8pP28uc2xpY2UoKTpvfWZ1bmN0aW9uIHIoQyxvLGMpe2lmKHMuaXNVbmRlZmluZWQobykpe2lmKCFzLmlzVW5kZWZpbmVkKEMpKXJldHVybiBJKHZvaWQgMCxDLGMpfWVsc2UgcmV0dXJuIEkoQyxvLGMpfWZ1bmN0aW9uIGkoQyxvKXtpZighcy5pc1VuZGVmaW5lZChvKSlyZXR1cm4gSSh2b2lkIDAsbyl9ZnVuY3Rpb24gZyhDLG8pe2lmKHMuaXNVbmRlZmluZWQobykpe2lmKCFzLmlzVW5kZWZpbmVkKEMpKXJldHVybiBJKHZvaWQgMCxDKX1lbHNlIHJldHVybiBJKHZvaWQgMCxvKX1mdW5jdGlvbiBuKEMsbyxjKXtpZihjIGluIGUpcmV0dXJuIEkoQyxvKTtpZihjIGluIEEpcmV0dXJuIEkodm9pZCAwLEMpfWxldCBFPXt1cmw6aSxtZXRob2Q6aSxkYXRhOmksYmFzZVVSTDpnLHRyYW5zZm9ybVJlcXVlc3Q6Zyx0cmFuc2Zvcm1SZXNwb25zZTpnLHBhcmFtc1NlcmlhbGl6ZXI6Zyx0aW1lb3V0OmcsdGltZW91dE1lc3NhZ2U6Zyx3aXRoQ3JlZGVudGlhbHM6ZyxhZGFwdGVyOmcscmVzcG9uc2VUeXBlOmcseHNyZkNvb2tpZU5hbWU6Zyx4c3JmSGVhZGVyTmFtZTpnLG9uVXBsb2FkUHJvZ3Jlc3M6ZyxvbkRvd25sb2FkUHJvZ3Jlc3M6ZyxkZWNvbXByZXNzOmcsbWF4Q29udGVudExlbmd0aDpnLG1heEJvZHlMZW5ndGg6ZyxiZWZvcmVSZWRpcmVjdDpnLHRyYW5zcG9ydDpnLGh0dHBBZ2VudDpnLGh0dHBzQWdlbnQ6ZyxjYW5jZWxUb2tlbjpnLHNvY2tldFBhdGg6ZyxyZXNwb25zZUVuY29kaW5nOmcsdmFsaWRhdGVTdGF0dXM6bixoZWFkZXJzOihDLG8pPT5yKFhlKEMpLFhlKG8pLCEwKX07cmV0dXJuIHMuZm9yRWFjaChPYmplY3Qua2V5cyhPYmplY3QuYXNzaWduKHt9LEEsZSkpLGZ1bmN0aW9uKG8pe2xldCBjPUVbb118fHIsYT1jKEFbb10sZVtvXSxvKTtzLmlzVW5kZWZpbmVkKGEpJiZjIT09bnx8KHRbb109YSl9KSx0fXZhciBGQT0iMS42LjAiO3ZhciAkQT17fTtbIm9iamVjdCIsImJvb2xlYW4iLCJudW1iZXIiLCJmdW5jdGlvbiIsInN0cmluZyIsInN5bWJvbCJdLmZvckVhY2goKEEsZSk9PnskQVtBXT1mdW5jdGlvbihJKXtyZXR1cm4gdHlwZW9mIEk9PT1BfHwiYSIrKGU8MT8ibiAiOiIgIikrQX19KTt2YXIgdmU9e307JEEudHJhbnNpdGlvbmFsPWZ1bmN0aW9uKGUsdCxJKXtmdW5jdGlvbiByKGksZyl7cmV0dXJuIltBeGlvcyB2IitGQSsiXSBUcmFuc2l0aW9uYWwgb3B0aW9uIFwnIitpKyJcJyIrZysoST8iLiAiK0k6IiIpfXJldHVybihpLGcsbik9PntpZihlPT09ITEpdGhyb3cgbmV3IGwocihnLCIgaGFzIGJlZW4gcmVtb3ZlZCIrKHQ/IiBpbiAiK3Q6IiIpKSxsLkVSUl9ERVBSRUNBVEVEKTtyZXR1cm4gdCYmIXZlW2ddJiYodmVbZ109ITAsY29uc29sZS53YXJuKHIoZywiIGhhcyBiZWVuIGRlcHJlY2F0ZWQgc2luY2UgdiIrdCsiIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5lYXIgZnV0dXJlIikpKSxlP2UoaSxnLG4pOiEwfX07ZnVuY3Rpb24gREkoQSxlLHQpe2lmKHR5cGVvZiBBIT0ib2JqZWN0Iil0aHJvdyBuZXcgbCgib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIsbC5FUlJfQkFEX09QVElPTl9WQUxVRSk7bGV0IEk9T2JqZWN0LmtleXMoQSkscj1JLmxlbmd0aDtmb3IoO3ItLSA+MDspe2xldCBpPUlbcl0sZz1lW2ldO2lmKGcpe2xldCBuPUFbaV0sRT1uPT09dm9pZCAwfHxnKG4saSxBKTtpZihFIT09ITApdGhyb3cgbmV3IGwoIm9wdGlvbiAiK2krIiBtdXN0IGJlICIrRSxsLkVSUl9CQURfT1BUSU9OX1ZBTFVFKTtjb250aW51ZX1pZih0IT09ITApdGhyb3cgbmV3IGwoIlVua25vd24gb3B0aW9uICIraSxsLkVSUl9CQURfT1BUSU9OKX19dmFyIFNBPXthc3NlcnRPcHRpb25zOkRJLHZhbGlkYXRvcnM6JEF9O3ZhciBiPVNBLnZhbGlkYXRvcnMsXz1jbGFzc3tjb25zdHJ1Y3RvcihlKXt0aGlzLmRlZmF1bHRzPWUsdGhpcy5pbnRlcmNlcHRvcnM9e3JlcXVlc3Q6bmV3IHhBLHJlc3BvbnNlOm5ldyB4QX19cmVxdWVzdChlLHQpe3R5cGVvZiBlPT0ic3RyaW5nIj8odD10fHx7fSx0LnVybD1lKTp0PWV8fHt9LHQ9TCh0aGlzLmRlZmF1bHRzLHQpO2xldHt0cmFuc2l0aW9uYWw6SSxwYXJhbXNTZXJpYWxpemVyOnIsaGVhZGVyczppfT10O0khPT12b2lkIDAmJlNBLmFzc2VydE9wdGlvbnMoSSx7c2lsZW50SlNPTlBhcnNpbmc6Yi50cmFuc2l0aW9uYWwoYi5ib29sZWFuKSxmb3JjZWRKU09OUGFyc2luZzpiLnRyYW5zaXRpb25hbChiLmJvb2xlYW4pLGNsYXJpZnlUaW1lb3V0RXJyb3I6Yi50cmFuc2l0aW9uYWwoYi5ib29sZWFuKX0sITEpLHIhPW51bGwmJihzLmlzRnVuY3Rpb24ocik/dC5wYXJhbXNTZXJpYWxpemVyPXtzZXJpYWxpemU6cn06U0EuYXNzZXJ0T3B0aW9ucyhyLHtlbmNvZGU6Yi5mdW5jdGlvbixzZXJpYWxpemU6Yi5mdW5jdGlvbn0sITApKSx0Lm1ldGhvZD0odC5tZXRob2R8fHRoaXMuZGVmYXVsdHMubWV0aG9kfHwiZ2V0IikudG9Mb3dlckNhc2UoKTtsZXQgZz1pJiZzLm1lcmdlKGkuY29tbW9uLGlbdC5tZXRob2RdKTtpJiZzLmZvckVhY2goWyJkZWxldGUiLCJnZXQiLCJoZWFkIiwicG9zdCIsInB1dCIsInBhdGNoIiwiY29tbW9uIl0sUT0+e2RlbGV0ZSBpW1FdfSksdC5oZWFkZXJzPXcuY29uY2F0KGcsaSk7bGV0IG49W10sRT0hMDt0aGlzLmludGVyY2VwdG9ycy5yZXF1ZXN0LmZvckVhY2goZnVuY3Rpb24oZil7dHlwZW9mIGYucnVuV2hlbj09ImZ1bmN0aW9uIiYmZi5ydW5XaGVuKHQpPT09ITF8fChFPUUmJmYuc3luY2hyb25vdXMsbi51bnNoaWZ0KGYuZnVsZmlsbGVkLGYucmVqZWN0ZWQpKX0pO2xldCBDPVtdO3RoaXMuaW50ZXJjZXB0b3JzLnJlc3BvbnNlLmZvckVhY2goZnVuY3Rpb24oZil7Qy5wdXNoKGYuZnVsZmlsbGVkLGYucmVqZWN0ZWQpfSk7bGV0IG8sYz0wLGE7aWYoIUUpe2xldCBRPVtwQS5iaW5kKHRoaXMpLHZvaWQgMF07Zm9yKFEudW5zaGlmdC5hcHBseShRLG4pLFEucHVzaC5hcHBseShRLEMpLGE9US5sZW5ndGgsbz1Qcm9taXNlLnJlc29sdmUodCk7YzxhOylvPW8udGhlbihRW2MrK10sUVtjKytdKTtyZXR1cm4gb31hPW4ubGVuZ3RoO2xldCBCPXQ7Zm9yKGM9MDtjPGE7KXtsZXQgUT1uW2MrK10sZj1uW2MrK107dHJ5e0I9UShCKX1jYXRjaChkKXtmLmNhbGwodGhpcyxkKTticmVha319dHJ5e289cEEuY2FsbCh0aGlzLEIpfWNhdGNoKFEpe3JldHVybiBQcm9taXNlLnJlamVjdChRKX1mb3IoYz0wLGE9Qy5sZW5ndGg7YzxhOylvPW8udGhlbihDW2MrK10sQ1tjKytdKTtyZXR1cm4gb31nZXRVcmkoZSl7ZT1MKHRoaXMuZGVmYXVsdHMsZSk7bGV0IHQ9ckEoZS5iYXNlVVJMLGUudXJsKTtyZXR1cm4gQUEodCxlLnBhcmFtcyxlLnBhcmFtc1NlcmlhbGl6ZXIpfX07cy5mb3JFYWNoKFsiZGVsZXRlIiwiZ2V0IiwiaGVhZCIsIm9wdGlvbnMiXSxmdW5jdGlvbihlKXtfLnByb3RvdHlwZVtlXT1mdW5jdGlvbih0LEkpe3JldHVybiB0aGlzLnJlcXVlc3QoTChJfHx7fSx7bWV0aG9kOmUsdXJsOnQsZGF0YTooSXx8e30pLmRhdGF9KSl9fSk7cy5mb3JFYWNoKFsicG9zdCIsInB1dCIsInBhdGNoIl0sZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChJKXtyZXR1cm4gZnVuY3Rpb24oaSxnLG4pe3JldHVybiB0aGlzLnJlcXVlc3QoTChufHx7fSx7bWV0aG9kOmUsaGVhZGVyczpJP3siQ29udGVudC1UeXBlIjoibXVsdGlwYXJ0L2Zvcm0tZGF0YSJ9Ont9LHVybDppLGRhdGE6Z30pKX19Xy5wcm90b3R5cGVbZV09dCgpLF8ucHJvdG90eXBlW2UrIkZvcm0iXT10KCEwKX0pO3ZhciBpQT1fO3ZhciBBZT1jbGFzcyBBe2NvbnN0cnVjdG9yKGUpe2lmKHR5cGVvZiBlIT0iZnVuY3Rpb24iKXRocm93IG5ldyBUeXBlRXJyb3IoImV4ZWN1dG9yIG11c3QgYmUgYSBmdW5jdGlvbi4iKTtsZXQgdDt0aGlzLnByb21pc2U9bmV3IFByb21pc2UoZnVuY3Rpb24oaSl7dD1pfSk7bGV0IEk9dGhpczt0aGlzLnByb21pc2UudGhlbihyPT57aWYoIUkuX2xpc3RlbmVycylyZXR1cm47bGV0IGk9SS5fbGlzdGVuZXJzLmxlbmd0aDtmb3IoO2ktLSA+MDspSS5fbGlzdGVuZXJzW2ldKHIpO0kuX2xpc3RlbmVycz1udWxsfSksdGhpcy5wcm9taXNlLnRoZW49cj0+e2xldCBpLGc9bmV3IFByb21pc2Uobj0+e0kuc3Vic2NyaWJlKG4pLGk9bn0pLnRoZW4ocik7cmV0dXJuIGcuY2FuY2VsPWZ1bmN0aW9uKCl7SS51bnN1YnNjcmliZShpKX0sZ30sZShmdW5jdGlvbihpLGcsbil7SS5yZWFzb258fChJLnJlYXNvbj1uZXcgTShpLGcsbiksdChJLnJlYXNvbikpfSl9dGhyb3dJZlJlcXVlc3RlZCgpe2lmKHRoaXMucmVhc29uKXRocm93IHRoaXMucmVhc29ufXN1YnNjcmliZShlKXtpZih0aGlzLnJlYXNvbil7ZSh0aGlzLnJlYXNvbik7cmV0dXJufXRoaXMuX2xpc3RlbmVycz90aGlzLl9saXN0ZW5lcnMucHVzaChlKTp0aGlzLl9saXN0ZW5lcnM9W2VdfXVuc3Vic2NyaWJlKGUpe2lmKCF0aGlzLl9saXN0ZW5lcnMpcmV0dXJuO2xldCB0PXRoaXMuX2xpc3RlbmVycy5pbmRleE9mKGUpO3QhPT0tMSYmdGhpcy5fbGlzdGVuZXJzLnNwbGljZSh0LDEpfXN0YXRpYyBzb3VyY2UoKXtsZXQgZTtyZXR1cm57dG9rZW46bmV3IEEoZnVuY3Rpb24ocil7ZT1yfSksY2FuY2VsOmV9fX0sJGU9QWU7ZnVuY3Rpb24gZWUoQSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiBBLmFwcGx5KG51bGwsdCl9fWZ1bmN0aW9uIHRlKEEpe3JldHVybiBzLmlzT2JqZWN0KEEpJiZBLmlzQXhpb3NFcnJvcj09PSEwfXZhciBJZT17Q29udGludWU6MTAwLFN3aXRjaGluZ1Byb3RvY29sczoxMDEsUHJvY2Vzc2luZzoxMDIsRWFybHlIaW50czoxMDMsT2s6MjAwLENyZWF0ZWQ6MjAxLEFjY2VwdGVkOjIwMixOb25BdXRob3JpdGF0aXZlSW5mb3JtYXRpb246MjAzLE5vQ29udGVudDoyMDQsUmVzZXRDb250ZW50OjIwNSxQYXJ0aWFsQ29udGVudDoyMDYsTXVsdGlTdGF0dXM6MjA3LEFscmVhZHlSZXBvcnRlZDoyMDgsSW1Vc2VkOjIyNixNdWx0aXBsZUNob2ljZXM6MzAwLE1vdmVkUGVybWFuZW50bHk6MzAxLEZvdW5kOjMwMixTZWVPdGhlcjozMDMsTm90TW9kaWZpZWQ6MzA0LFVzZVByb3h5OjMwNSxVbnVzZWQ6MzA2LFRlbXBvcmFyeVJlZGlyZWN0OjMwNyxQZXJtYW5lbnRSZWRpcmVjdDozMDgsQmFkUmVxdWVzdDo0MDAsVW5hdXRob3JpemVkOjQwMSxQYXltZW50UmVxdWlyZWQ6NDAyLEZvcmJpZGRlbjo0MDMsTm90Rm91bmQ6NDA0LE1ldGhvZE5vdEFsbG93ZWQ6NDA1LE5vdEFjY2VwdGFibGU6NDA2LFByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZDo0MDcsUmVxdWVzdFRpbWVvdXQ6NDA4LENvbmZsaWN0OjQwOSxHb25lOjQxMCxMZW5ndGhSZXF1aXJlZDo0MTEsUHJlY29uZGl0aW9uRmFpbGVkOjQxMixQYXlsb2FkVG9vTGFyZ2U6NDEzLFVyaVRvb0xvbmc6NDE0LFVuc3VwcG9ydGVkTWVkaWFUeXBlOjQxNSxSYW5nZU5vdFNhdGlzZmlhYmxlOjQxNixFeHBlY3RhdGlvbkZhaWxlZDo0MTcsSW1BVGVhcG90OjQxOCxNaXNkaXJlY3RlZFJlcXVlc3Q6NDIxLFVucHJvY2Vzc2FibGVFbnRpdHk6NDIyLExvY2tlZDo0MjMsRmFpbGVkRGVwZW5kZW5jeTo0MjQsVG9vRWFybHk6NDI1LFVwZ3JhZGVSZXF1aXJlZDo0MjYsUHJlY29uZGl0aW9uUmVxdWlyZWQ6NDI4LFRvb01hbnlSZXF1ZXN0czo0MjksUmVxdWVzdEhlYWRlckZpZWxkc1Rvb0xhcmdlOjQzMSxVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29uczo0NTEsSW50ZXJuYWxTZXJ2ZXJFcnJvcjo1MDAsTm90SW1wbGVtZW50ZWQ6NTAxLEJhZEdhdGV3YXk6NTAyLFNlcnZpY2VVbmF2YWlsYWJsZTo1MDMsR2F0ZXdheVRpbWVvdXQ6NTA0LEh0dHBWZXJzaW9uTm90U3VwcG9ydGVkOjUwNSxWYXJpYW50QWxzb05lZ290aWF0ZXM6NTA2LEluc3VmZmljaWVudFN0b3JhZ2U6NTA3LExvb3BEZXRlY3RlZDo1MDgsTm90RXh0ZW5kZWQ6NTEwLE5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkOjUxMX07T2JqZWN0LmVudHJpZXMoSWUpLmZvckVhY2goKFtBLGVdKT0+e0llW2VdPUF9KTt2YXIgQXQ9SWU7ZnVuY3Rpb24gZXQoQSl7bGV0IGU9bmV3IGlBKEEpLHQ9WChpQS5wcm90b3R5cGUucmVxdWVzdCxlKTtyZXR1cm4gcy5leHRlbmQodCxpQS5wcm90b3R5cGUsZSx7YWxsT3duS2V5czohMH0pLHMuZXh0ZW5kKHQsZSxudWxsLHthbGxPd25LZXlzOiEwfSksdC5jcmVhdGU9ZnVuY3Rpb24ocil7cmV0dXJuIGV0KEwoQSxyKSl9LHR9dmFyIGg9ZXQoaik7aC5BeGlvcz1pQTtoLkNhbmNlbGVkRXJyb3I9TTtoLkNhbmNlbFRva2VuPSRlO2guaXNDYW5jZWw9SUE7aC5WRVJTSU9OPUZBO2gudG9Gb3JtRGF0YT1KO2guQXhpb3NFcnJvcj1sO2guQ2FuY2VsPWguQ2FuY2VsZWRFcnJvcjtoLmFsbD1mdW5jdGlvbihlKXtyZXR1cm4gUHJvbWlzZS5hbGwoZSl9O2guc3ByZWFkPWVlO2guaXNBeGlvc0Vycm9yPXRlO2gubWVyZ2VDb25maWc9TDtoLkF4aW9zSGVhZGVycz13O2guZm9ybVRvSlNPTj1BPT5EQShzLmlzSFRNTEZvcm0oQSk/bmV3IEZvcm1EYXRhKEEpOkEpO2guZ2V0QWRhcHRlcj13QS5nZXRBZGFwdGVyO2guSHR0cFN0YXR1c0NvZGU9QXQ7aC5kZWZhdWx0PWg7dmFyIE5BPWg7dmFye0F4aW9zOlJnLEF4aW9zRXJyb3I6R2csQ2FuY2VsZWRFcnJvcjpVZyxpc0NhbmNlbDprZyxDYW5jZWxUb2tlbjpMZyxWRVJTSU9OOk9nLGFsbDpKZyxDYW5jZWw6TWcsaXNBeGlvc0Vycm9yOmJnLHNwcmVhZDpIZyx0b0Zvcm1EYXRhOllnLEF4aW9zSGVhZGVyczpxZyxIdHRwU3RhdHVzQ29kZTpUZyxmb3JtVG9KU09OOktnLGdldEFkYXB0ZXI6eGcsbWVyZ2VDb25maWc6UGd9PU5BO3ZhciBnQSxPLGllLHJlPXtlbnY6e2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGg6ZnVuY3Rpb24oQSl7aWU9bmV3IFVpbnQ4QXJyYXkoTy5leHBvcnRzLm1lbW9yeS5idWZmZXIpfX19LFJBPWNsYXNze2luaXQoKXtyZXR1cm4gZ0F8fCh0eXBlb2YgZmV0Y2g8InUiP2dBPWZldGNoKCJkYXRhOmFwcGxpY2F0aW9uL3dhc207YmFzZTY0LCIrdHQpLnRoZW4oZT0+ZS5hcnJheUJ1ZmZlcigpKS50aGVuKGU9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGUscmUpKS50aGVuKHRoaXMuX2luaXQpOmdBPVdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKEJ1ZmZlci5mcm9tKHR0LCJiYXNlNjQiKSxyZSkudGhlbih0aGlzLl9pbml0KSxnQSl9X2luaXQoZSl7Tz1lLmluc3RhbmNlLHJlLmVudi5lbXNjcmlwdGVuX25vdGlmeV9tZW1vcnlfZ3Jvd3RoKDApfWRlY29kZShlLHQ9MCl7aWYoIU8pdGhyb3cgbmV3IEVycm9yKCJaU1RERGVjb2RlcjogQXdhaXQgLmluaXQoKSBiZWZvcmUgZGVjb2RpbmcuIik7bGV0IEk9ZS5ieXRlTGVuZ3RoLHI9Ty5leHBvcnRzLm1hbGxvYyhJKTtpZS5zZXQoZSxyKSx0PXR8fE51bWJlcihPLmV4cG9ydHMuWlNURF9maW5kRGVjb21wcmVzc2VkU2l6ZShyLEkpKTtsZXQgaT1PLmV4cG9ydHMubWFsbG9jKHQpLGc9Ty5leHBvcnRzLlpTVERfZGVjb21wcmVzcyhpLHQscixJKSxuPWllLnNsaWNlKGksaStnKTtyZXR1cm4gTy5leHBvcnRzLmZyZWUociksTy5leHBvcnRzLmZyZWUoaSksbn19LHR0PSJBR0Z6YlFFQUFBQUJiZzVnQTM5L2Z3Ri9ZQUYvQVg5Z0FuOS9BR0FCZndCZ0JYOS9mMzkvQVg5Z0EzOS9md0JnQkg5L2YzOEJmMkFBQVg5Z0FuOS9BWDlnQjM5L2YzOS9mMzhCZjJBQ2YzOEJmbUFJZjM5L2YzOS9mMzhCZjJBRmYzOS9mMzhBWUE1L2YzOS9mMzkvZjM5L2YzOS9md0YvQWljQkEyVnVkaDlsYlhOamNtbHdkR1Z1WDI1dmRHbG1lVjl0WlcxdmNubGZaM0p2ZDNSb0FBTURJeUlIQUFBQkFRTUhBd0VBQ1FRQUJRRUlDQUVGQmdRRUJBTUdBQUFLQUFVTERBMEdCQVVCY0FFQkFRVUhBUUdBQW9DQUFnWUlBWDhCUVlDakJBc0hyZ0VMQm0xbGJXOXllUUlBQm0xaGJHeHZZd0FGQkdaeVpXVUFCZ3hhVTFSRVgybHpSWEp5YjNJQUVobGFVMVJFWDJacGJtUkVaV052YlhCeVpYTnpaV1JUYVhwbEFCd1BXbE5VUkY5a1pXTnZiWEJ5WlhOekFDSVpYMTlwYm1ScGNtVmpkRjltZFc1amRHbHZibDkwWVdKc1pRRUFFRjlmWlhKeWJtOWZiRzlqWVhScGIyNEFBUWx6ZEdGamExTmhkbVVBQnd4emRHRmphMUpsYzNSdmNtVUFDQXB6ZEdGamEwRnNiRzlqQUFrS2kvSUJJZ1VBUVlRZkN6TUJBWDhnQWdSQUlBQWhBd05BSUFNZ0FTMEFBRG9BQUNBRFFRRnFJUU1nQVVFQmFpRUJJQUpCQVdzaUFnMEFDd3NnQUFzcEFRRi9JQUlFUUNBQUlRTURRQ0FESUFFNkFBQWdBMEVCYWlFRElBSkJBV3NpQWcwQUN3c2dBQXRzQVFKL1FZQWZLQUlBSWdFZ0FFRUhha0Y0Y1NJQ2FpRUFBa0FnQWtFQUlBQWdBVTBiRFFBZ0FEOEFRUkIwU3dSQUlBQS9BRUVRZEd0Qi8vOERha0VRZGtBQVFYOUdCSDlCQUFWQkFCQUFRUUVMUlEwQkMwR0FIeUFBTmdJQUlBRVBDMEdFSDBFd05nSUFRWDhMdVNjQkMzOGpBRUVRYXlJS0pBQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUFrQUNRQUpBQWtBQ1FBSkFJQUJCOUFGTkJFQkJpQjhvQWdBaUJrRVFJQUJCQzJwQmVIRWdBRUVMU1JzaUJVRURkaUlBZGlJQlFRTnhCRUFDUUNBQlFYOXpRUUZ4SUFCcUlnSkJBM1FpQVVHd0gyb2lBQ0FCUWJnZmFpZ0NBQ0lCS0FJSUlnUkdCRUJCaUI4Z0JrRitJQUozY1RZQ0FBd0JDeUFFSUFBMkFnd2dBQ0FFTmdJSUN5QUJRUWhxSVFBZ0FTQUNRUU4wSWdKQkEzSTJBZ1FnQVNBQ2FpSUJJQUVvQWdSQkFYSTJBZ1FNRHdzZ0JVR1FIeWdDQUNJSFRRMEJJQUVFUUFKQVFRSWdBSFFpQWtFQUlBSnJjaUFCSUFCMGNXZ2lBVUVEZENJQVFiQWZhaUlDSUFCQnVCOXFLQUlBSWdBb0FnZ2lCRVlFUUVHSUh5QUdRWDRnQVhkeElnWTJBZ0FNQVFzZ0JDQUNOZ0lNSUFJZ0JEWUNDQXNnQUNBRlFRTnlOZ0lFSUFBZ0JXb2lDQ0FCUVFOMElnRWdCV3NpQkVFQmNqWUNCQ0FBSUFGcUlBUTJBZ0FnQndSQUlBZEJlSEZCc0I5cUlRRkJuQjhvQWdBaEFnSi9JQVpCQVNBSFFRTjJkQ0lEY1VVRVFFR0lIeUFESUFaeU5nSUFJQUVNQVFzZ0FTZ0NDQXNoQXlBQklBSTJBZ2dnQXlBQ05nSU1JQUlnQVRZQ0RDQUNJQU0yQWdnTElBQkJDR29oQUVHY0h5QUlOZ0lBUVpBZklBUTJBZ0FNRHd0QmpCOG9BZ0FpQzBVTkFTQUxhRUVDZEVHNElXb29BZ0FpQWlnQ0JFRjRjU0FGYXlFRElBSWhBUU5BQWtBZ0FTZ0NFQ0lBUlFSQUlBRW9BaFFpQUVVTkFRc2dBQ2dDQkVGNGNTQUZheUlCSUFNZ0FTQURTU0lCR3lFRElBQWdBaUFCR3lFQ0lBQWhBUXdCQ3dzZ0FpZ0NHQ0VKSUFJZ0FpZ0NEQ0lFUndSQVFaZ2ZLQUlBR2lBQ0tBSUlJZ0FnQkRZQ0RDQUVJQUEyQWdnTURnc2dBa0VVYWlJQktBSUFJZ0JGQkVBZ0FpZ0NFQ0lBUlEwRElBSkJFR29oQVFzRFFDQUJJUWdnQUNJRVFSUnFJZ0VvQWdBaUFBMEFJQVJCRUdvaEFTQUVLQUlRSWdBTkFBc2dDRUVBTmdJQURBMExRWDhoQlNBQVFiOS9TdzBBSUFCQkMyb2lBRUY0Y1NFRlFZd2ZLQUlBSWdoRkRRQkJBQ0FGYXlFREFrQUNRQUpBQW45QkFDQUZRWUFDU1EwQUdrRWZJQVZCLy8vL0Iwc05BQm9nQlVFbUlBQkJDSFpuSWdCcmRrRUJjU0FBUVFGMGEwRSthZ3NpQjBFQ2RFRzRJV29vQWdBaUFVVUVRRUVBSVFBTUFRdEJBQ0VBSUFWQkdTQUhRUUYyYTBFQUlBZEJIMGNiZENFQ0EwQUNRQ0FCS0FJRVFYaHhJQVZySWdZZ0EwOE5BQ0FCSVFRZ0JpSUREUUJCQUNFRElBRWhBQXdEQ3lBQUlBRW9BaFFpQmlBR0lBRWdBa0VkZGtFRWNXb29BaEFpQVVZYklBQWdCaHNoQUNBQ1FRRjBJUUlnQVEwQUN3c2dBQ0FFY2tVRVFFRUFJUVJCQWlBSGRDSUFRUUFnQUd0eUlBaHhJZ0JGRFFNZ0FHaEJBblJCdUNGcUtBSUFJUUFMSUFCRkRRRUxBMEFnQUNnQ0JFRjRjU0FGYXlJQ0lBTkpJUUVnQWlBRElBRWJJUU1nQUNBRUlBRWJJUVFnQUNnQ0VDSUJCSDhnQVFVZ0FDZ0NGQXNpQUEwQUN3c2dCRVVOQUNBRFFaQWZLQUlBSUFWclR3MEFJQVFvQWhnaEJ5QUVJQVFvQWd3aUFrY0VRRUdZSHlnQ0FCb2dCQ2dDQ0NJQUlBSTJBZ3dnQWlBQU5nSUlEQXdMSUFSQkZHb2lBU2dDQUNJQVJRUkFJQVFvQWhBaUFFVU5BeUFFUVJCcUlRRUxBMEFnQVNFR0lBQWlBa0VVYWlJQktBSUFJZ0FOQUNBQ1FSQnFJUUVnQWlnQ0VDSUFEUUFMSUFaQkFEWUNBQXdMQ3lBRlFaQWZLQUlBSWdSTkJFQkJuQjhvQWdBaEFBSkFJQVFnQldzaUFVRVFUd1JBSUFBZ0JXb2lBaUFCUVFGeU5nSUVJQUFnQkdvZ0FUWUNBQ0FBSUFWQkEzSTJBZ1FNQVFzZ0FDQUVRUU55TmdJRUlBQWdCR29pQVNBQktBSUVRUUZ5TmdJRVFRQWhBa0VBSVFFTFFaQWZJQUUyQWdCQm5COGdBallDQUNBQVFRaHFJUUFNRFFzZ0JVR1VIeWdDQUNJQ1NRUkFRWlFmSUFJZ0JXc2lBVFlDQUVHZ0gwR2dIeWdDQUNJQUlBVnFJZ0kyQWdBZ0FpQUJRUUZ5TmdJRUlBQWdCVUVEY2pZQ0JDQUFRUWhxSVFBTURRdEJBQ0VBSUFWQkwyb2lBd0ovUWVBaUtBSUFCRUJCNkNJb0FnQU1BUXRCN0NKQ2Z6Y0NBRUhrSWtLQW9JQ0FnSUFFTndJQVFlQWlJQXBCREdwQmNIRkIyS3JWcWdWek5nSUFRZlFpUVFBMkFnQkJ4Q0pCQURZQ0FFR0FJQXNpQVdvaUJrRUFJQUZySWdoeElnRWdCVTBOREVIQUlpZ0NBQ0lFQkVCQnVDSW9BZ0FpQnlBQmFpSUpJQWROSUFRZ0NVbHlEUTBMQWtCQnhDSXRBQUJCQkhGRkJFQUNRQUpBQWtBQ1FFR2dIeWdDQUNJRUJFQkJ5Q0loQUFOQUlBUWdBQ2dDQUNJSFR3UkFJQWNnQUNnQ0JHb2dCRXNOQXdzZ0FDZ0NDQ0lBRFFBTEMwRUFFQVFpQWtGL1JnMERJQUVoQmtIa0lpZ0NBQ0lBUVFGcklnUWdBbkVFUUNBQklBSnJJQUlnQkdwQkFDQUFhM0ZxSVFZTElBVWdCazhOQTBIQUlpZ0NBQ0lBQkVCQnVDSW9BZ0FpQkNBR2FpSUlJQVJOSUFBZ0NFbHlEUVFMSUFZUUJDSUFJQUpIRFFFTUJRc2dCaUFDYXlBSWNTSUdFQVFpQWlBQUtBSUFJQUFvQWdScVJnMEJJQUloQUFzZ0FFRi9SZzBCSUFWQk1Hb2dCazBFUUNBQUlRSU1CQXRCNkNJb0FnQWlBaUFESUFacmFrRUFJQUpyY1NJQ0VBUkJmMFlOQVNBQ0lBWnFJUVlnQUNFQ0RBTUxJQUpCZjBjTkFndEJ4Q0pCeENJb0FnQkJCSEkyQWdBTElBRVFCQ0lDUVg5R1FRQVFCQ0lBUVg5R2NpQUFJQUpOY2cwRklBQWdBbXNpQmlBRlFTaHFUUTBGQzBHNElrRzRJaWdDQUNBR2FpSUFOZ0lBUWJ3aUtBSUFJQUJKQkVCQnZDSWdBRFlDQUFzQ1FFR2dIeWdDQUNJREJFQkJ5Q0loQUFOQUlBSWdBQ2dDQUNJQklBQW9BZ1FpQkdwR0RRSWdBQ2dDQ0NJQURRQUxEQVFMUVpnZktBSUFJZ0JCQUNBQUlBSk5HMFVFUUVHWUh5QUNOZ0lBQzBFQUlRQkJ6Q0lnQmpZQ0FFSElJaUFDTmdJQVFhZ2ZRWDgyQWdCQnJCOUI0Q0lvQWdBMkFnQkIxQ0pCQURZQ0FBTkFJQUJCQTNRaUFVRzRIMm9nQVVHd0gyb2lCRFlDQUNBQlFid2ZhaUFFTmdJQUlBQkJBV29pQUVFZ1J3MEFDMEdVSHlBR1FTaHJJZ0JCZUNBQ2EwRUhjU0lCYXlJRU5nSUFRYUFmSUFFZ0Ftb2lBVFlDQUNBQklBUkJBWEkyQWdRZ0FDQUNha0VvTmdJRVFhUWZRZkFpS0FJQU5nSUFEQVFMSUFJZ0EwMGdBU0FEUzNJTkFpQUFLQUlNUVFoeERRSWdBQ0FFSUFacU5nSUVRYUFmSUFOQmVDQURhMEVIY1NJQWFpSUJOZ0lBUVpRZlFaUWZLQUlBSUFacUlnSWdBR3NpQURZQ0FDQUJJQUJCQVhJMkFnUWdBaUFEYWtFb05nSUVRYVFmUWZBaUtBSUFOZ0lBREFNTFFRQWhCQXdLQzBFQUlRSU1DQXRCbUI4b0FnQWdBa3NFUUVHWUh5QUNOZ0lBQ3lBQ0lBWnFJUUZCeUNJaEFBSkFBa0FDUUFOQUlBRWdBQ2dDQUVjRVFDQUFLQUlJSWdBTkFRd0NDd3NnQUMwQURFRUljVVVOQVF0QnlDSWhBQU5BSUFNZ0FDZ0NBQ0lCVHdSQUlBRWdBQ2dDQkdvaUJDQURTdzBEQ3lBQUtBSUlJUUFNQUFzQUN5QUFJQUkyQWdBZ0FDQUFLQUlFSUFacU5nSUVJQUpCZUNBQ2EwRUhjV29pQnlBRlFRTnlOZ0lFSUFGQmVDQUJhMEVIY1dvaUJpQUZJQWRxSWdWcklRQWdBeUFHUmdSQVFhQWZJQVUyQWdCQmxCOUJsQjhvQWdBZ0FHb2lBRFlDQUNBRklBQkJBWEkyQWdRTUNBdEJuQjhvQWdBZ0JrWUVRRUdjSHlBRk5nSUFRWkFmUVpBZktBSUFJQUJxSWdBMkFnQWdCU0FBUVFGeU5nSUVJQUFnQldvZ0FEWUNBQXdJQ3lBR0tBSUVJZ05CQTNGQkFVY05CaUFEUVhoeElRa2dBMEgvQVUwRVFDQUdLQUlNSWdFZ0JpZ0NDQ0lDUmdSQVFZZ2ZRWWdmS0FJQVFYNGdBMEVEZG5keE5nSUFEQWNMSUFJZ0FUWUNEQ0FCSUFJMkFnZ01CZ3NnQmlnQ0dDRUlJQVlnQmlnQ0RDSUNSd1JBSUFZb0FnZ2lBU0FDTmdJTUlBSWdBVFlDQ0F3RkN5QUdRUlJxSWdFb0FnQWlBMFVFUUNBR0tBSVFJZ05GRFFRZ0JrRVFhaUVCQ3dOQUlBRWhCQ0FESWdKQkZHb2lBU2dDQUNJRERRQWdBa0VRYWlFQklBSW9BaEFpQXcwQUN5QUVRUUEyQWdBTUJBdEJsQjhnQmtFb2F5SUFRWGdnQW10QkIzRWlBV3NpQ0RZQ0FFR2dIeUFCSUFKcUlnRTJBZ0FnQVNBSVFRRnlOZ0lFSUFBZ0FtcEJLRFlDQkVHa0gwSHdJaWdDQURZQ0FDQURJQVJCSnlBRWEwRUhjV3BCTDJzaUFDQUFJQU5CRUdwSkd5SUJRUnMyQWdRZ0FVSFFJaWtDQURjQ0VDQUJRY2dpS1FJQU53SUlRZEFpSUFGQkNHbzJBZ0JCekNJZ0JqWUNBRUhJSWlBQ05nSUFRZFFpUVFBMkFnQWdBVUVZYWlFQUEwQWdBRUVITmdJRUlBQkJDR29nQUVFRWFpRUFJQVJKRFFBTElBRWdBMFlOQUNBQklBRW9BZ1JCZm5FMkFnUWdBeUFCSUFOcklnSkJBWEkyQWdRZ0FTQUNOZ0lBSUFKQi93Rk5CRUFnQWtGNGNVR3dIMm9oQUFKL1FZZ2ZLQUlBSWdGQkFTQUNRUU4yZENJQ2NVVUVRRUdJSHlBQklBSnlOZ0lBSUFBTUFRc2dBQ2dDQ0FzaEFTQUFJQU0yQWdnZ0FTQUROZ0lNSUFNZ0FEWUNEQ0FESUFFMkFnZ01BUXRCSHlFQUlBSkIvLy8vQjAwRVFDQUNRU1lnQWtFSWRtY2lBR3QyUVFGeElBQkJBWFJyUVQ1cUlRQUxJQU1nQURZQ0hDQURRZ0EzQWhBZ0FFRUNkRUc0SVdvaEFRSkFBa0JCakI4b0FnQWlCRUVCSUFCMElnWnhSUVJBUVl3ZklBUWdCbkkyQWdBZ0FTQUROZ0lBREFFTElBSkJHU0FBUVFGMmEwRUFJQUJCSDBjYmRDRUFJQUVvQWdBaEJBTkFJQVFpQVNnQ0JFRjRjU0FDUmcwQ0lBQkJIWFloQkNBQVFRRjBJUUFnQVNBRVFRUnhhaUlHS0FJUUlnUU5BQXNnQmlBRE5nSVFDeUFESUFFMkFoZ2dBeUFETmdJTUlBTWdBellDQ0F3QkN5QUJLQUlJSWdBZ0F6WUNEQ0FCSUFNMkFnZ2dBMEVBTmdJWUlBTWdBVFlDRENBRElBQTJBZ2dMUVpRZktBSUFJZ0FnQlUwTkFFR1VIeUFBSUFWcklnRTJBZ0JCb0I5Qm9COG9BZ0FpQUNBRmFpSUNOZ0lBSUFJZ0FVRUJjallDQkNBQUlBVkJBM0kyQWdRZ0FFRUlhaUVBREFnTFFZUWZRVEEyQWdCQkFDRUFEQWNMUVFBaEFnc2dDRVVOQUFKQUlBWW9BaHdpQVVFQ2RFRzRJV29pQkNnQ0FDQUdSZ1JBSUFRZ0FqWUNBQ0FDRFFGQmpCOUJqQjhvQWdCQmZpQUJkM0UyQWdBTUFnc2dDRUVRUVJRZ0NDZ0NFQ0FHUmh0cUlBSTJBZ0FnQWtVTkFRc2dBaUFJTmdJWUlBWW9BaEFpQVFSQUlBSWdBVFlDRUNBQklBSTJBaGdMSUFZb0FoUWlBVVVOQUNBQ0lBRTJBaFFnQVNBQ05nSVlDeUFBSUFscUlRQWdCaUFKYWlJR0tBSUVJUU1MSUFZZ0EwRitjVFlDQkNBRklBQkJBWEkyQWdRZ0FDQUZhaUFBTmdJQUlBQkIvd0ZOQkVBZ0FFRjRjVUd3SDJvaEFRSi9RWWdmS0FJQUlnSkJBU0FBUVFOMmRDSUFjVVVFUUVHSUh5QUFJQUp5TmdJQUlBRU1BUXNnQVNnQ0NBc2hBQ0FCSUFVMkFnZ2dBQ0FGTmdJTUlBVWdBVFlDRENBRklBQTJBZ2dNQVF0Qkh5RURJQUJCLy8vL0IwMEVRQ0FBUVNZZ0FFRUlkbWNpQVd0MlFRRnhJQUZCQVhSclFUNXFJUU1MSUFVZ0F6WUNIQ0FGUWdBM0FoQWdBMEVDZEVHNElXb2hBUUpBQWtCQmpCOG9BZ0FpQWtFQklBTjBJZ1J4UlFSQVFZd2ZJQUlnQkhJMkFnQWdBU0FGTmdJQURBRUxJQUJCR1NBRFFRRjJhMEVBSUFOQkgwY2JkQ0VESUFFb0FnQWhBZ05BSUFJaUFTZ0NCRUY0Y1NBQVJnMENJQU5CSFhZaEFpQURRUUYwSVFNZ0FTQUNRUVJ4YWlJRUtBSVFJZ0lOQUFzZ0JDQUZOZ0lRQ3lBRklBRTJBaGdnQlNBRk5nSU1JQVVnQlRZQ0NBd0JDeUFCS0FJSUlnQWdCVFlDRENBQklBVTJBZ2dnQlVFQU5nSVlJQVVnQVRZQ0RDQUZJQUEyQWdnTElBZEJDR29oQUF3Q0N3SkFJQWRGRFFBQ1FDQUVLQUljSWdCQkFuUkJ1Q0ZxSWdFb0FnQWdCRVlFUUNBQklBSTJBZ0FnQWcwQlFZd2ZJQWhCZmlBQWQzRWlDRFlDQUF3Q0N5QUhRUkJCRkNBSEtBSVFJQVJHRzJvZ0FqWUNBQ0FDUlEwQkN5QUNJQWMyQWhnZ0JDZ0NFQ0lBQkVBZ0FpQUFOZ0lRSUFBZ0FqWUNHQXNnQkNnQ0ZDSUFSUTBBSUFJZ0FEWUNGQ0FBSUFJMkFoZ0xBa0FnQTBFUFRRUkFJQVFnQXlBRmFpSUFRUU55TmdJRUlBQWdCR29pQUNBQUtBSUVRUUZ5TmdJRURBRUxJQVFnQlVFRGNqWUNCQ0FFSUFWcUlnSWdBMEVCY2pZQ0JDQUNJQU5xSUFNMkFnQWdBMEgvQVUwRVFDQURRWGh4UWJBZmFpRUFBbjlCaUI4b0FnQWlBVUVCSUFOQkEzWjBJZ054UlFSQVFZZ2ZJQUVnQTNJMkFnQWdBQXdCQ3lBQUtBSUlDeUVCSUFBZ0FqWUNDQ0FCSUFJMkFnd2dBaUFBTmdJTUlBSWdBVFlDQ0F3QkMwRWZJUUFnQTBILy8vOEhUUVJBSUFOQkppQURRUWgyWnlJQWEzWkJBWEVnQUVFQmRHdEJQbW9oQUFzZ0FpQUFOZ0ljSUFKQ0FEY0NFQ0FBUVFKMFFiZ2hhaUVCQWtBQ1FDQUlRUUVnQUhRaUJuRkZCRUJCakI4Z0JpQUljallDQUNBQklBSTJBZ0FNQVFzZ0EwRVpJQUJCQVhaclFRQWdBRUVmUnh0MElRQWdBU2dDQUNFRkEwQWdCU0lCS0FJRVFYaHhJQU5HRFFJZ0FFRWRkaUVHSUFCQkFYUWhBQ0FCSUFaQkJIRnFJZ1lvQWhBaUJRMEFDeUFHSUFJMkFoQUxJQUlnQVRZQ0dDQUNJQUkyQWd3Z0FpQUNOZ0lJREFFTElBRW9BZ2dpQUNBQ05nSU1JQUVnQWpZQ0NDQUNRUUEyQWhnZ0FpQUJOZ0lNSUFJZ0FEWUNDQXNnQkVFSWFpRUFEQUVMQWtBZ0NVVU5BQUpBSUFJb0Fod2lBRUVDZEVHNElXb2lBU2dDQUNBQ1JnUkFJQUVnQkRZQ0FDQUVEUUZCakI4Z0MwRitJQUIzY1RZQ0FBd0NDeUFKUVJCQkZDQUpLQUlRSUFKR0cyb2dCRFlDQUNBRVJRMEJDeUFFSUFrMkFoZ2dBaWdDRUNJQUJFQWdCQ0FBTmdJUUlBQWdCRFlDR0FzZ0FpZ0NGQ0lBUlEwQUlBUWdBRFlDRkNBQUlBUTJBaGdMQWtBZ0EwRVBUUVJBSUFJZ0F5QUZhaUlBUVFOeU5nSUVJQUFnQW1vaUFDQUFLQUlFUVFGeU5nSUVEQUVMSUFJZ0JVRURjallDQkNBQ0lBVnFJZ1FnQTBFQmNqWUNCQ0FESUFScUlBTTJBZ0FnQndSQUlBZEJlSEZCc0I5cUlRQkJuQjhvQWdBaEFRSi9RUUVnQjBFRGRuUWlCU0FHY1VVRVFFR0lIeUFGSUFaeU5nSUFJQUFNQVFzZ0FDZ0NDQXNoQmlBQUlBRTJBZ2dnQmlBQk5nSU1JQUVnQURZQ0RDQUJJQVkyQWdnTFFad2ZJQVEyQWdCQmtCOGdBellDQUFzZ0FrRUlhaUVBQ3lBS1FSQnFKQUFnQUF2U0N3RUhmd0pBSUFCRkRRQWdBRUVJYXlJQ0lBQkJCR3NvQWdBaUFVRjRjU0lBYWlFRkFrQWdBVUVCY1EwQUlBRkJBM0ZGRFFFZ0FpQUNLQUlBSWdGcklnSkJtQjhvQWdCSkRRRWdBQ0FCYWlFQUFrQUNRRUdjSHlnQ0FDQUNSd1JBSUFGQi93Rk5CRUFnQVVFRGRpRUVJQUlvQWd3aUFTQUNLQUlJSWdOR0JFQkJpQjlCaUI4b0FnQkJmaUFFZDNFMkFnQU1CUXNnQXlBQk5nSU1JQUVnQXpZQ0NBd0VDeUFDS0FJWUlRWWdBaUFDS0FJTUlnRkhCRUFnQWlnQ0NDSURJQUUyQWd3Z0FTQUROZ0lJREFNTElBSkJGR29pQkNnQ0FDSURSUVJBSUFJb0FoQWlBMFVOQWlBQ1FSQnFJUVFMQTBBZ0JDRUhJQU1pQVVFVWFpSUVLQUlBSWdNTkFDQUJRUkJxSVFRZ0FTZ0NFQ0lERFFBTElBZEJBRFlDQUF3Q0N5QUZLQUlFSWdGQkEzRkJBMGNOQWtHUUh5QUFOZ0lBSUFVZ0FVRitjVFlDQkNBQ0lBQkJBWEkyQWdRZ0JTQUFOZ0lBRHd0QkFDRUJDeUFHUlEwQUFrQWdBaWdDSENJRFFRSjBRYmdoYWlJRUtBSUFJQUpHQkVBZ0JDQUJOZ0lBSUFFTkFVR01IMEdNSHlnQ0FFRitJQU4zY1RZQ0FBd0NDeUFHUVJCQkZDQUdLQUlRSUFKR0cyb2dBVFlDQUNBQlJRMEJDeUFCSUFZMkFoZ2dBaWdDRUNJREJFQWdBU0FETmdJUUlBTWdBVFlDR0FzZ0FpZ0NGQ0lEUlEwQUlBRWdBellDRkNBRElBRTJBaGdMSUFJZ0JVOE5BQ0FGS0FJRUlnRkJBWEZGRFFBQ1FBSkFBa0FDUUNBQlFRSnhSUVJBUWFBZktBSUFJQVZHQkVCQm9COGdBallDQUVHVUgwR1VIeWdDQUNBQWFpSUFOZ0lBSUFJZ0FFRUJjallDQkNBQ1Fad2ZLQUlBUncwR1FaQWZRUUEyQWdCQm5COUJBRFlDQUE4TFFad2ZLQUlBSUFWR0JFQkJuQjhnQWpZQ0FFR1FIMEdRSHlnQ0FDQUFhaUlBTmdJQUlBSWdBRUVCY2pZQ0JDQUFJQUpxSUFBMkFnQVBDeUFCUVhoeElBQnFJUUFnQVVIL0FVMEVRQ0FCUVFOMklRUWdCU2dDRENJQklBVW9BZ2dpQTBZRVFFR0lIMEdJSHlnQ0FFRitJQVIzY1RZQ0FBd0ZDeUFESUFFMkFnd2dBU0FETmdJSURBUUxJQVVvQWhnaEJpQUZJQVVvQWd3aUFVY0VRRUdZSHlnQ0FCb2dCU2dDQ0NJRElBRTJBZ3dnQVNBRE5nSUlEQU1MSUFWQkZHb2lCQ2dDQUNJRFJRUkFJQVVvQWhBaUEwVU5BaUFGUVJCcUlRUUxBMEFnQkNFSElBTWlBVUVVYWlJRUtBSUFJZ01OQUNBQlFSQnFJUVFnQVNnQ0VDSUREUUFMSUFkQkFEWUNBQXdDQ3lBRklBRkJmbkUyQWdRZ0FpQUFRUUZ5TmdJRUlBQWdBbW9nQURZQ0FBd0RDMEVBSVFFTElBWkZEUUFDUUNBRktBSWNJZ05CQW5SQnVDRnFJZ1FvQWdBZ0JVWUVRQ0FFSUFFMkFnQWdBUTBCUVl3ZlFZd2ZLQUlBUVg0Z0EzZHhOZ0lBREFJTElBWkJFRUVVSUFZb0FoQWdCVVliYWlBQk5nSUFJQUZGRFFFTElBRWdCallDR0NBRktBSVFJZ01FUUNBQklBTTJBaEFnQXlBQk5nSVlDeUFGS0FJVUlnTkZEUUFnQVNBRE5nSVVJQU1nQVRZQ0dBc2dBaUFBUVFGeU5nSUVJQUFnQW1vZ0FEWUNBQ0FDUVp3ZktBSUFSdzBBUVpBZklBQTJBZ0FQQ3lBQVFmOEJUUVJBSUFCQmVIRkJzQjlxSVFFQ2YwR0lIeWdDQUNJRFFRRWdBRUVEZG5RaUFIRkZCRUJCaUI4Z0FDQURjallDQUNBQkRBRUxJQUVvQWdnTElRQWdBU0FDTmdJSUlBQWdBallDRENBQ0lBRTJBZ3dnQWlBQU5nSUlEd3RCSHlFRElBQkIvLy8vQjAwRVFDQUFRU1lnQUVFSWRtY2lBV3QyUVFGeElBRkJBWFJyUVQ1cUlRTUxJQUlnQXpZQ0hDQUNRZ0EzQWhBZ0EwRUNkRUc0SVdvaEFRSkFBa0FDUUVHTUh5Z0NBQ0lFUVFFZ0EzUWlCM0ZGQkVCQmpCOGdCQ0FIY2pZQ0FDQUJJQUkyQWdBZ0FpQUJOZ0lZREFFTElBQkJHU0FEUVFGMmEwRUFJQU5CSDBjYmRDRURJQUVvQWdBaEFRTkFJQUVpQkNnQ0JFRjRjU0FBUmcwQ0lBTkJIWFloQVNBRFFRRjBJUU1nQkNBQlFRUnhhaUlIUVJCcUtBSUFJZ0VOQUFzZ0J5QUNOZ0lRSUFJZ0JEWUNHQXNnQWlBQ05nSU1JQUlnQWpZQ0NBd0JDeUFFS0FJSUlnQWdBallDRENBRUlBSTJBZ2dnQWtFQU5nSVlJQUlnQkRZQ0RDQUNJQUEyQWdnTFFhZ2ZRYWdmS0FJQVFRRnJJZ0JCZnlBQUd6WUNBQXNMQkFBakFBc0dBQ0FBSkFBTEVBQWpBQ0FBYTBGd2NTSUFKQUFnQUF0S0FRRi9JQUFnQVVrRVFDQUFJQUVnQWhBQ0R3c2dBZ1JBSUFBZ0Ftb2hBeUFCSUFKcUlRRURRQ0FEUVFGcklnTWdBVUVCYXlJQkxRQUFPZ0FBSUFKQkFXc2lBZzBBQ3dzZ0FBdjlEZ0lSZndGK0l3QkJNR3NpQnlRQVFiaC9JUWdDUUNBRlJRMEFJQVFzQUFBaUNVSC9BWEVoQ3dKQUlBbEJBRWdFUUNBTFFmNEFhMEVCZGlJR0lBVlBEUUpCYkNFSUlBdEIvd0JySWd0Qi93RkxEUUlnQkVFQmFpRUlRUUFoQlFOQUlBVWdDMDhFUUNBTElRZ2dCaUVMREFNRklBQWdCV29nQ0NBRlFRRjJhaUlFTFFBQVFRUjJPZ0FBSUFBZ0JVRUJjbW9nQkMwQUFFRVBjVG9BQUNBRlFRSnFJUVVNQVFzQUN3QUxJQVVnQzAwTkFTQUhRZjhCTmdJRUlBWWdCMEVFYWlBSFFRaHFJQVJCQVdvaURpQUxFQXdpQkVHSWYwc0VRQ0FFSVFnTUFndEJWQ0VJSUFjb0FnZ2lFRUVHU3cwQklBY29BZ1FpRVVFQmRDSUpRUUpxclVJQklCQ3RoaUlZUVFFZ0VIUWlEVUVCYWlJRnJVSUNobng4UWd0OFF2ei8vLy8vLy8vLy93Q0RRdVFDVmcwQlFWSWhDQ0FSUWY4QlN3MEJJQTFCZjNOQkFuUkI1QUpxclNBUlFRRnFJaFZCQVhTdElCaDhRZ2g4VkEwQklBc2dCR3NoRmlBRUlBNXFJUmNnQmtHQUJHb2lFaUFGUVFKMGFpSVJJQWxxUVFKcUlRNGdCa0dFQkdvaEUwR0FnQUlnRUhSQkVIWWhDVUVBSVFWQkFTRVBJQTFCQVdzaUZDRUtBMEFnQlNBVlJrVUVRQUpBSUFZZ0JVRUJkQ0lJYWk4QkFDSUVRZi8vQTBZRVFDQVRJQXBCQW5ScUlBVTZBQUlnQ2tFQmF5RUtRUUVoQkF3QkN5QVBRUUFnQ1NBRXdVb2JJUThMSUFnZ0VXb2dCRHNCQUNBRlFRRnFJUVVNQVFzTElBWWdEenNCZ2dRZ0JpQVFPd0dBQkFKQUlBb2dGRVlFUUNBTlFRTjJJUWhDQUNFWVFRQWhEd05BSUF3Z0ZVWUVRQ0FJSUExQkFYWnFRUU5xSWdsQkFYUWhDRUVBSVFSQkFDRUtBMEJCQUNFRklBb2dEVThOQkFOQUlBVkJBa1pGQkVBZ0V5QUZJQWxzSUFScUlCUnhRUUowYWlBT0lBVWdDbXBxTFFBQU9nQUNJQVZCQVdvaEJRd0JDd3NnQ2tFQ2FpRUtJQVFnQ0dvZ0ZIRWhCQXdBQ3dBRklBWWdERUVCZEdvdUFRQWhDU0FPSUE5cUlnUWdHRGNBQUVFSUlRVURRQ0FGSUFsT1JRUkFJQVFnQldvZ0dEY0FBQ0FGUVFocUlRVU1BUXNMSUJoQ2dZS0VpSkNnd0lBQmZDRVlJQXhCQVdvaERDQUpJQTlxSVE4TUFRc0FDd0FMSUExQkEzWWdEVUVCZG1wQkEyb2hDRUVBSVFVRFFDQU1JQlZHUlFSQVFRQWhDU0FHSUF4QkFYUnFMZ0VBSWdSQkFDQUVRUUJLR3lFRUEwQWdCQ0FKUmtVRVFDQVRJQVZCQW5ScUlBdzZBQUlEUUNBRklBaHFJQlJ4SWdVZ0Nrc05BQXNnQ1VFQmFpRUpEQUVMQ3lBTVFRRnFJUXdNQVFzTFFYOGhDQ0FGRFFJTElCQkJBV29oQ0VFQUlRVURRQ0FGSUExR1JRUkFJQkVnRXlBRlFRSjBhaUlPTFFBQ1FRRjBhaUlFSUFRdkFRQWlDVUVCYWpzQkFDQU9JQWdnQ1dkQllITnFJZ1E2QUFNZ0RpQUpJQVIwSUExck93RUFJQVZCQVdvaEJRd0JDd3NDUUFKQUlBWXZBWUlFQkVBZ0IwRWNhaUlFSUJjZ0ZoQU5JZ2hCaUg5TERRSWdCMEVVYWlBRUlCSVFEaUFIUVF4cUlBUWdFaEFPUVFBaEJRTkFJQWRCSEdvaUJCQVBJQVZCK3dGTGNnMENJQUFnQldvaUJpQUhRUlJxSUFRUUVEb0FBQ0FHSUFkQkRHb2dCQkFRT2dBQklBVkJBbkloQkNBSFFSeHFFQThFUUNBRUlRVU1Bd1VnQUNBRWFpQUhRUlJxSUFkQkhHb2lCQkFRT2dBQUlBWWdCMEVNYWlBRUVCQTZBQU1nQlVFRWFpRUZEQUVMQUFzQUN5QUhRUnhxSWdRZ0Z5QVdFQTBpQ0VHSWYwc05BU0FIUVJScUlBUWdFaEFPSUFkQkRHb2dCQ0FTRUE1QkFDRUZBMEFnQjBFY2FpSUVFQThnQlVIN0FVdHlSUVJBSUFBZ0JXb2lCaUFIUVJScUlBUVFFVG9BQUNBR0lBZEJER29nQkJBUk9nQUJJQVZCQW5JaEJDQUhRUnhxRUE4RVFDQUVJUVVGSUFBZ0JHb2dCMEVVYWlBSFFSeHFJZ1FRRVRvQUFDQUdJQWRCREdvZ0JCQVJPZ0FESUFWQkJHb2hCUXdDQ3dzTEFuOERRRUc2ZnlFSUlBVkIvUUZMRFFNZ0FDQUZhaUlHSUFkQkZHb2dCMEVjYWlJSkVCRTZBQUFnQmtFQmFpRUVJQWtRRDBFRFJnUkFJQWRCREdvaENFRUNEQUlMSUFWQi9BRkxEUU1nQmlBSFFReHFJQWRCSEdvaUJCQVJPZ0FCSUFWQkFtb2hCU0FFRUE5QkEwY05BQXNnQUNBRmFpRUVJQWRCRkdvaENFRURDeUFFSUFnZ0IwRWNhaEFST2dBQUlBWnFJQUJySVFnTUFRc0Nmd05BUWJwL0lRZ2dCVUg5QVVzTkFpQUFJQVZxSWdZZ0IwRVVhaUFIUVJ4cUlna1FFRG9BQUNBR1FRRnFJUVFnQ1JBUFFRTkdCRUFnQjBFTWFpRUlRUUlNQWdzZ0JVSDhBVXNOQWlBR0lBZEJER29nQjBFY2FpSUVFQkE2QUFFZ0JVRUNhaUVGSUFRUUQwRURSdzBBQ3lBQUlBVnFJUVFnQjBFVWFpRUlRUU1MSUFRZ0NDQUhRUnhxRUJBNkFBQWdCbW9nQUdzaENBc2dDRUdJZjBzTkFRc2dDQ0VFUVFBaEJTQUJRUUJCTkJBRElRbEJBQ0VLQTBBZ0JDQUZSd1JBSUFBZ0JXb2lCaTBBQUNJQlFRdExCRUJCYkNFSURBTUZJQWtnQVVFQ2RHb2lBU0FCS0FJQVFRRnFOZ0lBSUFWQkFXb2hCVUVCSUFZdEFBQjBRUUYxSUFwcUlRb01BZ3NBQ3d0QmJDRUlJQXBGRFFBZ0NtY2lCVUVmY3lJQlFRdExEUUFnQTBFZ0lBVnJOZ0lBUVFGQkFpQUJkQ0FLYXlJRFowRWZjeUlCZENBRFJ3MEFJQUFnQkdvZ0FVRUJhaUlBT2dBQUlBa2dBRUVDZEdvaUFDQUFLQUlBUVFGcU5nSUFJQWtvQWdRaUFFRUNTU0FBUVFGeGNnMEFJQUlnQkVFQmFqWUNBQ0FMUVFGcUlRZ0xJQWRCTUdva0FDQUlDNkFGQVF4L0l3QkJFR3NpRENRQUFuOGdCRUVIVFFSQUlBeENBRGNEQ0NBTVFRaHFJZ1VnQXlBRUVBSWFRV3dnQUNBQklBSWdCVUVJRUF3aUFDQUFJQVJMR3lBQUlBQkJpWDlKR3d3QkN5QUFRUUFnQVNnQ0FFRUJhaUlOUVFGMEVBTWhEMEZVSUFNb0FBQWlCa0VQY1NJQVFRcExEUUFhSUFJZ0FFRUZhallDQUNBRElBUnFJZ0pCQkdzaEJ5QUNRUWRySVFzZ0FFRUdhaUVPUVFRaEFpQUdRUVIySVFWQklDQUFkQ0lJUVFGeUlRbEJBQ0VBUVFFaEJpQURJUVFEUUFKQUlBWkJBWEZGQkVBRFFDQUZRWDl6UVlDQWdJQjRjbWdpQmtFWVNVVUVRQ0FBUVNScUlRQWdCQ0FMVFFSL0lBUkJBMm9GSUFRZ0MydEJBM1FnQW1wQkgzRWhBaUFIQ3lJRUtBQUFJQUoySVFVTUFRc0xJQUlnQmtFZWNTSUtha0VDYWlFQ0lBWkJBWFpCQTJ3Z0FHb2dCU0FLZGtFRGNXb2lBQ0FOVHcwQkFuOGdCQ0FMU3lBQ1FRTjJJQVJxSWdVZ0IwdHhSUVJBSUFKQkIzRWhBaUFGREFFTElBUWdCMnRCQTNRZ0FtcEJIM0VoQWlBSEN5SUVLQUFBSUFKMklRVUxJQVVnQ0VFQmEzRWlCaUFJUVFGMFFRRnJJZ29nQ1dzaUVFa0VmeUFPUVFGckJTQUZJQXB4SWdVZ0VFRUFJQVVnQ0U0YmF5RUdJQTRMSVFVZ0R5QUFRUUYwYWlBR1FRRnJJZ283QVFBZ0FFRUJhaUVBSUFJZ0JXb2hBaUFJUVFFZ0Jtc2dDaUFHUVFCS0d5QUphaUlKU2dSQUlBbEJBa2dOQVVFZ0lBbG5JZ1ZySVE1QkFTQUZRUjl6ZENFSUN5QUFJQTFQRFFBZ0NrRUFSeUVHQW44Z0JDQUxTeUFDUVFOMUlBUnFJZ1VnQjB0eFJRUkFJQUpCQjNFaEFpQUZEQUVMSUFJZ0JDQUhhMEVEZEdwQkgzRWhBaUFIQ3lJRUtBQUFJQUoySVFVTUFRc0xRV3dnQ1VFQlJ3MEFHa0ZRSUFBZ0RVc05BQnBCYkNBQ1FTQktEUUFhSUFFZ0FFRUJhellDQUNBRUlBSkJCMnBCQTNWcUlBTnJDeUFNUVJCcUpBQUw4Z0VCQVg4Z0FrVUVRQ0FBUWdBM0FnQWdBRUVBTmdJUUlBQkNBRGNDQ0VHNGZ3OExJQUFnQVRZQ0RDQUFJQUZCQkdvMkFoQWdBa0VFVHdSQUlBQWdBU0FDYWlJQlFRUnJJZ00yQWdnZ0FDQURLQUFBTmdJQUlBRkJBV3N0QUFBaUFRUkFJQUFnQVdkQkYyczJBZ1FnQWc4TElBQkJBRFlDQkVGL0R3c2dBQ0FCTmdJSUlBQWdBUzBBQUNJRE5nSUFBa0FDUUFKQUlBSkJBbXNPQWdFQUFnc2dBQ0FCTFFBQ1FSQjBJQU55SWdNMkFnQUxJQUFnQVMwQUFVRUlkQ0FEYWpZQ0FBc2dBU0FDYWtFQmF5MEFBQ0lCUlFSQUlBQkJBRFlDQkVGc0R3c2dBQ0FCWnlBQ1FRTjBhMEVKYWpZQ0JDQUNDMFFCQW44Z0FTQUNMd0VBSWdNZ0FTZ0NCR29pQkRZQ0JDQUFJQU5CQW5SQm9CMXFLQUlBSUFFb0FnQkJBQ0FFYTNaeE5nSUFJQUVRRHhvZ0FDQUNRUVJxTmdJRUM1OEJBUVIvUVFNaEFTQUFLQUlFSWdKQklFMEVRQ0FBS0FJSUlnRWdBQ2dDRUU4RVFDQUFJQUpCQjNFMkFnUWdBQ0FCSUFKQkEzWnJJZ0kyQWdnZ0FDQUNLQUFBTmdJQVFRQVBDeUFBS0FJTUlnTWdBVVlFUUVFQlFRSWdBa0VnU1JzUEN5QUFJQUVnQVNBRGF5QUNRUU4ySWdRZ0FTQUVheUFEU1NJQkd5SURheUlFTmdJSUlBQWdBaUFEUVFOMGF6WUNCQ0FBSUFRb0FBQTJBZ0FMSUFFTFNBRUVmeUFBS0FJRUlBQW9BZ0JCQW5ScUlnSXRBQUlnQWk4QkFDRUVJQUVnQVNnQ0JDSUZJQUl0QUFNaUFtbzJBZ1FnQUNBRUlBRW9BZ0FnQlhSQkFDQUNhM1pxTmdJQUMxSUJCSDhnQUNnQ0JDQUFLQUlBUVFKMGFpSUNMUUFDSUFJdkFRQWhCQ0FCSUFJdEFBTWlBaUFCS0FJRWFpSUZOZ0lFSUFBZ0JDQUNRUUowUWFBZGFpZ0NBQ0FCS0FJQVFRQWdCV3QyY1dvMkFnQUxDQUFnQUVHSWYwc0xHZ0FnQUFSQUlBRUVRQ0FDSUFBZ0FSRUNBQThMSUFBUUJnc0xwZ2dDRFg4QmZpTUFRUkJySWdra0FDQUpRUUEyQWd3Z0NVRUFOZ0lJQW44Q1FDQURRZWdKYWlBRElBbEJDR29nQ1VFTWFpQUJJQUlnQTBHQUFXb1FDeUlQUVloL1N3MEFRVlFnQ1NnQ0RDSUVJQUFvQWdBaUFVSC9BWEZCQVdwTERRRWFJQUJCQkdvaEN5QUFJQUZCLzRHQWVIRWdCRUVRZEVHQWdQd0hjWEkyQWdCQmZ5QUVJQVJCQUVnYlFRRnFJUUJCQUNFQklBa29BZ2doQlVFQUlRSURRQ0FBSUFKR0JFQWdCVUVEYXlFQlFRQWhBQU5BQWtCQkFDRUNJQUFnQVU0RVFBTkFJQUFnQlU0TkFpQURJQUFnQTJwQjZBbHFMUUFBUVFKMGFrRkFheUlCSUFFb0FnQWlBVUVCYWpZQ0FDQUJJQU5xSUFBNkFPZ0hJQUJCQVdvaEFBd0FDd0FGQTBBZ0FrRUVSa1VFUUNBRElBTWdBQ0FDYWlJSGFrSG9DV290QUFCQkFuUnFRVUJySWdnZ0NDZ0NBQ0lJUVFGcU5nSUFJQU1nQ0dvZ0J6b0E2QWNnQWtFQmFpRUNEQUVMQ3lBQVFRUnFJUUFNQWdzQUN3c2dCRUVCYWlFT0lBTW9BZ0FoQjBFQUlRQkJBU0VJQTBBZ0NDQU9SZzBESUE0Z0NHc2hCQ0FESUFoQkFuUnFLQUlBSVFVQ1FBSkFBa0FDUUFKQUFrQkJBU0FJZEVFQmRTSU5RUUZyRGdnQUFRUUNCQVFFQXdRTFFRQWhBaUFGUVFBZ0JVRUFTaHNoQmlBQUlRRURRQ0FDSUFaR0RRVWdBeUFDSUFkcWFpMEE2QWNoQ2lBTElBRkJBWFJxSWd3Z0JEb0FBU0FNSUFvNkFBQWdBa0VCYWlFQ0lBRkJBV29oQVF3QUN3QUxRUUFoQWlBRlFRQWdCVUVBU2hzaENpQUFJUUVEUUNBQ0lBcEdEUVFnQ3lBQlFRRjBhaUlHSUFNZ0FpQUhhbW90QU9nSElndzZBQUlnQmlBRU9nQUJJQVlnRERvQUFDQUdJQVE2QUFNZ0FrRUJhaUVDSUFGQkFtb2hBUXdBQ3dBTFFRQWhBaUFGUVFBZ0JVRUFTaHNoQmlBRVFRaDBRWUQrQTNFaEJDQUFJUUVEUUNBQ0lBWkdEUU1nQ3lBQlFRRjBhaUFFSUFNZ0FpQUhhbW90QU9nSGNxMUNnWUNFZ0pDQXdBQitOd0FBSUFKQkFXb2hBaUFCUVFScUlRRU1BQXNBQzBFQUlRSWdCVUVBSUFWQkFFb2JJUVlnQkVFSWRFR0EvZ054SVFRZ0FDRUJBMEFnQWlBR1JnMENJQXNnQVVFQmRHb2lDaUFFSUFNZ0FpQUhhbW90QU9nSGNxMUNnWUNFZ0pDQXdBQitJaEUzQUFnZ0NpQVJOd0FBSUFKQkFXb2hBaUFCUVFocUlRRU1BQXNBQzBFQUlRRWdCVUVBSUFWQkFFb2JJUW9nQkVFSWRFR0EvZ054SVF3Z0FDRUVBMEFnQVNBS1JnMEJJQXNnQkVFQmRHb2hFQ0FNSUFNZ0FTQUhhbW90QU9nSGNxMUNnWUNFZ0pDQXdBQitJUkZCQUNFQ0EwQWdBaUFOVGtVRVFDQVFJQUpCQVhScUlnWWdFVGNBR0NBR0lCRTNBQkFnQmlBUk53QUlJQVlnRVRjQUFDQUNRUkJxSVFJTUFRc0xJQUZCQVdvaEFTQUVJQTFxSVFRTUFBc0FDeUFJUVFGcUlRZ2dCU0FIYWlFSElBVWdEV3dnQUdvaEFBd0FDd0FGSUFNZ0FrRUNkR29pQjBGQWF5QUJOZ0lBSUFKQkFXb2hBaUFIS0FJQUlBRnFJUUVNQVFzQUN3QUxJQThMSUFsQkVHb2tBQXZ5QWdFR2Z5TUFRU0JySWdVa0FDQUVLQUlBSVFZZ0JVRU1haUFDSUFNUURTSURRWWgvVFFSQUlBUkJCR29oQWlBQUlBRnFJZ2xCQTJzaEJFRUFJQVpCRUhaclFSOXhJUU1EUUNBRlFReHFFQThnQUNBRVQzSkZCRUFnQWlBRktBSU1JZ1lnQlNnQ0VDSUhkQ0FEZGtFQmRHb2lDQzBBQVNFS0lBQWdDQzBBQURvQUFDQUNJQVlnQnlBS2FpSUdkQ0FEZGtFQmRHb2lCeTBBQUNFSUlBVWdCaUFITFFBQmFqWUNFQ0FBSUFnNkFBRWdBRUVDYWlFQURBRUxDd05BSUFWQkRHb1FEeUVISUFVb0Fnd2hCaUFGS0FJUUlRUWdBQ0FKVHlBSGNrVUVRQ0FDSUFZZ0JIUWdBM1pCQVhScUlnWXRBQUFoQnlBRklBUWdCaTBBQVdvMkFoQWdBQ0FIT2dBQUlBQkJBV29oQUF3QkN3c0RRQ0FBSUFsUFJRUkFJQUlnQmlBRWRDQURka0VCZEdvaUJ5MEFBU0VJSUFBZ0J5MEFBRG9BQUNBQVFRRnFJUUFnQkNBSWFpRUVEQUVMQzBGc1FXd2dBU0FGS0FJVUlBVW9BaGhIR3lBRVFTQkhHeUVEQ3lBRlFTQnFKQUFnQXd2UEZBRWpmeU1BUWRBQWF5SUZKQUJCYkNFSkFrQWdBMEVLU1EwQUFrQWdBeUFDTHdBRUlnY2dBaThBQUNJSUlBSXZBQUlpRFdwcVFRWnFJZ3hKRFFBZ0JDOEJBaUVHSUFWQlBHb2dBa0VHYWlJQ0lBZ1FEU0lKUVloL1N3MEJJQVZCS0dvZ0FpQUlhaUlDSUEwUURTSUpRWWgvU3cwQklBVkJGR29nQWlBTmFpSUNJQWNRRFNJSlFZaC9TdzBCSUFVZ0FpQUhhaUFESUF4ckVBMGlDVUdJZjBzTkFTQUVRUVJxSVFvZ0FDQUJhaUlmUVFOcklTQkJBQ0FHYTBFZmNTRUxJQVVvQWdnaEVTQUZLQUljSVJJZ0JTZ0NNQ0VUSUFVb0FrUWhGQ0FGS0FJRUlRa2dCU2dDR0NFTklBVW9BaXdoRENBRktBSkFJUVlnQlNnQ0VDRWhJQVVvQWlRaElpQUZLQUk0SVNNZ0JTZ0NUQ0VrSUFVb0FnQWhGU0FGS0FJVUlSWWdCU2dDS0NFWElBVW9BandoR0VFQklROGdBQ0FCUVFOcVFRSjJJZ1JxSWdNZ0JHb2lBaUFFYWlJWklRUWdBaUVJSUFNaEJ3TkFJQTlCQVhGRklBUWdJRTl5UlFSQUlBQWdDaUFZSUFaMElBdDJRUUowYWlJT0x3RUFPd0FBSUE0dEFBSWhHaUFPTFFBRElSQWdCeUFLSUJjZ0RIUWdDM1pCQW5ScUlnNHZBUUE3QUFBZ0RpMEFBaUViSUE0dEFBTWhEeUFJSUFvZ0ZpQU5kQ0FMZGtFQ2RHb2lEaThCQURzQUFDQU9MUUFDSVJ3Z0RpMEFBeUVkSUFRZ0NpQVZJQWwwSUF0MlFRSjBhaUlPTHdFQU93QUFJQTR0QUFJaEhpQU9MUUFESVE0Z0FDQVFhaUlsSUFvZ0dDQUdJQnBxSWdaMElBdDJRUUowYWlJUUx3RUFPd0FBSUJBdEFBSWdFQzBBQXlFbUlBY2dEMm9pSnlBS0lCY2dEQ0FiYWlJYWRDQUxka0VDZEdvaUJ5OEJBRHNBQUNBSExRQUNJUXdnQnkwQUF5RVFJQWdnSFdvaUd5QUtJQllnRFNBY2FpSVBkQ0FMZGtFQ2RHb2lDQzhCQURzQUFDQUlMUUFDSVEwZ0NDMEFBeUVjSUFRZ0Rtb2lIU0FLSUJVZ0NTQWVhaUlPZENBTGRrRUNkR29pQ1M4QkFEc0FBQ0FHYWlFQVFRTWhCd0ovSUJRZ0pFa0VRQ0FBSVFaQkF3d0JDeUFBUVFkeElRWWdGQ0FBUVFOMmF5SVVLQUFBSVJoQkFBc2dDUzBBQXlFZUlBa3RBQUloQ0NBTUlCcHFJUUFnRXlBalNRUi9JQUFGSUJNZ0FFRURkbXNpRXlnQUFDRVhRUUFoQnlBQVFRZHhDeUVNSUEwZ0Qyb2hBQ0FIY2lFSlFRTWhEd0ovSUJJZ0lra0VRQ0FBSVExQkF3d0JDeUFBUVFkeElRMGdFaUFBUVFOMmF5SVNLQUFBSVJaQkFBc2dDQ0FPYWlFQUlBbHlJQkVnSVVrRWZ5QUFCU0FSSUFCQkEzWnJJaEVvQUFBaEZVRUFJUThnQUVFSGNRc2hDU0FsSUNacUlRQWdFQ0FuYWlFSElCc2dIR29oQ0NBZElCNXFJUVFnRDNKRklROE1BUXNMSUFVZ0REWUNMQ0FGSUFZMkFrQWdCU0FOTmdJWUlBVWdDVFlDQkNBRklCUTJBa1FnQlNBVE5nSXdJQVVnRWpZQ0hDQUZJQkUyQWdnZ0JTQVlOZ0k4SUFVZ0Z6WUNLQ0FGSUJZMkFoUWdCU0FWTmdJQUlBSWdCMGtnQUNBRFMzSU5BRUZzSVFrZ0NDQVpTdzBCSUFOQkEyc2hDUU5BSUFWQlBHb1FEMFVnQUNBSlNYRUVRQ0FBSUFvZ0JTZ0NQQ0lOSUFVb0FrQWlESFFnQzNaQkFuUnFJZzR2QVFBN0FBQWdBQ0FPTFFBRGFpSUdJQW9nRFNBTUlBNHRBQUpxSWdCMElBdDJRUUowYWlJTUx3RUFPd0FBSUFVZ0FDQU1MUUFDYWpZQ1FDQUdJQXd0QUFOcUlRQU1BUVVnQTBFQ2F5RU1BMEFnQlVFOGFoQVBJUVlnQlNnQ1BDRU5JQVVvQWtBaENTQUFJQXhMSUFaeVJRUkFJQUFnQ2lBTklBbDBJQXQyUVFKMGFpSUdMd0VBT3dBQUlBVWdDU0FHTFFBQ2FqWUNRQ0FBSUFZdEFBTnFJUUFNQVFzTEEwQWdBQ0FNUzBVRVFDQUFJQW9nRFNBSmRDQUxka0VDZEdvaUJpOEJBRHNBQUNBQUlBWXRBQU5xSVFBZ0NTQUdMUUFDYWlFSkRBRUxDd0pBSUFBZ0EwOE5BQ0FBSUFvZ0RTQUpkQ0FMZGlJQVFRSjBhaUlETFFBQU9nQUFJQU10QUFOQkFVWUVRQ0FKSUFNdEFBSnFJUWtNQVFzZ0NVRWZTdzBBUVNBZ0NTQUtJQUJCQW5ScUxRQUNhaUlBSUFCQklFOGJJUWtMSUFKQkEyc2hEQU5BSUFWQktHb1FEMFVnQnlBTVNYRUVRQ0FISUFvZ0JTZ0NLQ0lHSUFVb0Fpd2lBSFFnQzNaQkFuUnFJZzB2QVFBN0FBQWdCeUFOTFFBRGFpSURJQW9nQmlBQUlBMHRBQUpxSWdCMElBdDJRUUowYWlJR0x3RUFPd0FBSUFVZ0FDQUdMUUFDYWpZQ0xDQURJQVl0QUFOcUlRY01BUVVnQWtFQ2F5RUdBMEFnQlVFb2FoQVBJUU1nQlNnQ0tDRU1JQVVvQWl3aEFDQUdJQWRKSUFOeVJRUkFJQWNnQ2lBTUlBQjBJQXQyUVFKMGFpSURMd0VBT3dBQUlBVWdBQ0FETFFBQ2FqWUNMQ0FISUFNdEFBTnFJUWNNQVFzTEEwQWdCaUFIU1VVRVFDQUhJQW9nRENBQWRDQUxka0VDZEdvaUF5OEJBRHNBQUNBSElBTXRBQU5xSVFjZ0FDQURMUUFDYWlFQURBRUxDd0pBSUFJZ0IwME5BQ0FISUFvZ0RDQUFkQ0FMZGlJQ1FRSjBhaUlETFFBQU9nQUFJQU10QUFOQkFVWUVRQ0FBSUFNdEFBSnFJUUFNQVFzZ0FFRWZTdzBBUVNBZ0FDQUtJQUpCQW5ScUxRQUNhaUlBSUFCQklFOGJJUUFMSUJsQkEyc2hEQU5BSUFWQkZHb1FEMFVnQ0NBTVNYRUVRQ0FJSUFvZ0JTZ0NGQ0lHSUFVb0FoZ2lBblFnQzNaQkFuUnFJZzB2QVFBN0FBQWdDQ0FOTFFBRGFpSURJQW9nQmlBQ0lBMHRBQUpxSWdKMElBdDJRUUowYWlJR0x3RUFPd0FBSUFVZ0FpQUdMUUFDYWpZQ0dDQURJQVl0QUFOcUlRZ01BUVVnR1VFQ2F5RURBMEFnQlVFVWFoQVBJUUlnQlNnQ0ZDRUdJQVVvQWhnaEJ5QURJQWhKSUFKeVJRUkFJQWdnQ2lBR0lBZDBJQXQyUVFKMGFpSUNMd0VBT3dBQUlBVWdCeUFDTFFBQ2FqWUNHQ0FJSUFJdEFBTnFJUWdNQVFzTEEwQWdBeUFJU1VVRVFDQUlJQW9nQmlBSGRDQUxka0VDZEdvaUFpOEJBRHNBQUNBSUlBSXRBQU5xSVFnZ0J5QUNMUUFDYWlFSERBRUxDd0pBSUFnZ0dVOE5BQ0FJSUFvZ0JpQUhkQ0FMZGlJQ1FRSjBhaUlETFFBQU9nQUFJQU10QUFOQkFVWUVRQ0FISUFNdEFBSnFJUWNNQVFzZ0IwRWZTdzBBUVNBZ0J5QUtJQUpCQW5ScUxRQUNhaUlDSUFKQklFOGJJUWNMQTBBZ0JSQVBSU0FFSUNCSmNRUkFJQVFnQ2lBRktBSUFJZ1lnQlNnQ0JDSUNkQ0FMZGtFQ2RHb2lEQzhCQURzQUFDQUVJQXd0QUFOcUlnTWdDaUFHSUFJZ0RDMEFBbW9pQW5RZ0MzWkJBblJxSWdRdkFRQTdBQUFnQlNBQ0lBUXRBQUpxTmdJRUlBTWdCQzBBQTJvaEJBd0JCU0FmUVFKcklRTURRQ0FGRUE4aEFpQUZLQUlBSVFZZ0JTZ0NCQ0VJSUFNZ0JFa2dBbkpGQkVBZ0JDQUtJQVlnQ0hRZ0MzWkJBblJxSWdJdkFRQTdBQUFnQlNBSUlBSXRBQUpxTmdJRUlBUWdBaTBBQTJvaEJBd0JDd3NEUUNBRElBUkpSUVJBSUFRZ0NpQUdJQWgwSUF0MlFRSjBhaUlDTHdFQU93QUFJQVFnQWkwQUEyb2hCQ0FJSUFJdEFBSnFJUWdNQVFzTEFrQWdCQ0FmVHcwQUlBUWdDaUFHSUFoMElBdDJJZ0pCQW5ScUlnTXRBQUE2QUFBZ0F5MEFBMEVCUmdSQUlBZ2dBeTBBQW1vaENBd0JDeUFJUVI5TERRQkJJQ0FJSUFvZ0FrRUNkR290QUFKcUlnSWdBa0VnVHhzaENBdEJiRUZzUVd4QmJFRnNRV3hCYkVGc0lBRWdDRUVnUnhzZ0JTZ0NDQ0FGS0FJTVJ4c2dCMEVnUnhzZ0JTZ0NIQ0FGS0FJZ1J4c2dBRUVnUnhzZ0JTZ0NNQ0FGS0FJMFJ4c2dDVUVnUnhzZ0JTZ0NSQ0FGS0FKSVJ4c2hDUXdKQ3dBTEFBc0FDd0FMQUFzQUN3QUxBQXRCYkNFSkN5QUZRZEFBYWlRQUlBa0w3QkFCSG44akFFSFFBR3NpQlNRQVFXd2hDUUpBSUFOQkNra05BQUpBSUFNZ0FpOEFCQ0lHSUFJdkFBQWlCeUFDTHdBQ0lnaHFha0VHYWlJT1NRMEFJQVF2QVFJaER5QUZRVHhxSUFKQkJtb2lBaUFIRUEwaUNVR0lmMHNOQVNBRlFTaHFJQUlnQjJvaUFpQUlFQTBpQ1VHSWYwc05BU0FGUVJScUlBSWdDR29pQWlBR0VBMGlDVUdJZjBzTkFTQUZJQUlnQm1vZ0F5QU9heEFOSWdsQmlIOUxEUUVnQkVFRWFpRUtJQUFnQVdvaUhFRURheUVkUVFBZ0QydEJIM0VoQ3lBRktBSUlJUkVnQlNnQ0hDRVNJQVVvQWpBaEV5QUZLQUpFSVJRZ0JTZ0NCQ0VKSUFVb0FoZ2hCaUFGS0FJc0lRY2dCU2dDUUNFSUlBVW9BaEFoSGlBRktBSWtJUjhnQlNnQ09DRWdJQVVvQWt3aElTQUZLQUlBSVJVZ0JTZ0NGQ0VXSUFVb0FpZ2hGeUFGS0FJOElSaEJBU0VOSUFBZ0FVRURha0VDZGlJQ2FpSU9JQUpxSWc4Z0Ftb2lHU0VFSUE4aEFpQU9JUU1EUUNBTlJTQUVJQjFQY2tVRVFDQUtJQmdnQ0hRZ0MzWkJBWFJxSWd3dEFBRWhEU0FBSUF3dEFBQTZBQUFnQ2lBWElBZDBJQXQyUVFGMGFpSU1MUUFCSVJBZ0F5QU1MUUFBT2dBQUlBb2dGaUFHZENBTGRrRUJkR29pREMwQUFTRWFJQUlnREMwQUFEb0FBQ0FLSUJVZ0NYUWdDM1pCQVhScUlnd3RBQUVoR3lBRUlBd3RBQUE2QUFBZ0NpQVlJQWdnRFdvaUNIUWdDM1pCQVhScUlnd3RBQUVoRFNBQUlBd3RBQUE2QUFFZ0NpQVhJQWNnRUdvaUIzUWdDM1pCQVhScUlnd3RBQUVoRUNBRElBd3RBQUE2QUFFZ0NpQVdJQVlnR21vaURIUWdDM1pCQVhScUlnWXRBQUVoR2lBQ0lBWXRBQUE2QUFFZ0NpQVZJQWtnRzJvaUczUWdDM1pCQVhScUlna3RBQUVoSWlBRUlBa3RBQUE2QUFFZ0NDQU5haUVHUVFNaENRSi9JQlFnSVVrRVFFRURJUTBnQmd3QkN5QVVJQVpCQTNackloUW9BQUFoR0VFQUlRMGdCa0VIY1FzaENDQUhJQkJxSVFZZ0V5QWdTUVIvSUFZRklCTWdCa0VEZG1zaUV5Z0FBQ0VYUVFBaENTQUdRUWR4Q3lFSElBd2dHbW9oRENBSklBMXlJUkJCQXlFTkFuOGdFaUFmU1FSQUlBd2hCa0VEREFFTElBeEJCM0VoQmlBU0lBeEJBM1pySWhJb0FBQWhGa0VBQ3lBYklDSnFJUXdnRUhJaEVDQVJJQjVKQkg4Z0RBVWdFU0FNUVFOMmF5SVJLQUFBSVJWQkFDRU5JQXhCQjNFTElRa2dCRUVDYWlFRUlBSkJBbW9oQWlBRFFRSnFJUU1nQUVFQ2FpRUFJQTBnRUhKRklRME1BUXNMSUFVZ0J6WUNMQ0FGSUFnMkFrQWdCU0FHTmdJWUlBVWdDVFlDQkNBRklCUTJBa1FnQlNBVE5nSXdJQVVnRWpZQ0hDQUZJQkUyQWdnZ0JTQVlOZ0k4SUFVZ0Z6WUNLQ0FGSUJZMkFoUWdCU0FWTmdJQUlBQWdEa3NnQXlBUFMzSU5BRUZzSVFrZ0FpQVpTdzBCSUE1QkEyc2hDUU5BSUFWQlBHb1FEeUFBSUFsUGNrVUVRQ0FLSUFVb0Fqd2lCaUFGS0FKQUlnZDBJQXQyUVFGMGFpSUlMUUFCSVF3Z0FDQUlMUUFBT2dBQUlBb2dCaUFISUF4cUlnWjBJQXQyUVFGMGFpSUhMUUFBSVFnZ0JTQUdJQWN0QUFGcU5nSkFJQUFnQ0RvQUFTQUFRUUpxSVFBTUFRc0xBMEFnQlVFOGFoQVBJUWNnQlNnQ1BDRUdJQVVvQWtBaENTQUFJQTVQSUFkeVJRUkFJQW9nQmlBSmRDQUxka0VCZEdvaUJpMEFBQ0VISUFVZ0NTQUdMUUFCYWpZQ1FDQUFJQWM2QUFBZ0FFRUJhaUVBREFFTEN3TkFJQUFnRGs5RkJFQWdDaUFHSUFsMElBdDJRUUYwYWlJSExRQUJJQUFnQnkwQUFEb0FBQ0FBUVFGcUlRQWdDV29oQ1F3QkN3c2dEMEVEYXlFQUEwQWdCVUVvYWhBUElBQWdBMDF5UlFSQUlBb2dCU2dDS0NJR0lBVW9BaXdpQjNRZ0MzWkJBWFJxSWdndEFBRWhEaUFESUFndEFBQTZBQUFnQ2lBR0lBY2dEbW9pQm5RZ0MzWkJBWFJxSWdjdEFBQWhDQ0FGSUFZZ0J5MEFBV28yQWl3Z0F5QUlPZ0FCSUFOQkFtb2hBd3dCQ3dzRFFDQUZRU2hxRUE4aEJ5QUZLQUlvSVFZZ0JTZ0NMQ0VBSUFNZ0QwOGdCM0pGQkVBZ0NpQUdJQUIwSUF0MlFRRjBhaUlHTFFBQUlRY2dCU0FBSUFZdEFBRnFOZ0lzSUFNZ0J6b0FBQ0FEUVFGcUlRTU1BUXNMQTBBZ0F5QVBUMFVFUUNBS0lBWWdBSFFnQzNaQkFYUnFJZ2N0QUFFaENDQURJQWN0QUFBNkFBQWdBMEVCYWlFRElBQWdDR29oQUF3QkN3c2dHVUVEYXlFREEwQWdCVUVVYWhBUElBSWdBMDl5UlFSQUlBb2dCU2dDRkNJR0lBVW9BaGdpQjNRZ0MzWkJBWFJxSWdndEFBRWhEaUFDSUFndEFBQTZBQUFnQ2lBR0lBY2dEbW9pQm5RZ0MzWkJBWFJxSWdjdEFBQWhDQ0FGSUFZZ0J5MEFBV28yQWhnZ0FpQUlPZ0FCSUFKQkFtb2hBZ3dCQ3dzRFFDQUZRUlJxRUE4aEJ5QUZLQUlVSVFZZ0JTZ0NHQ0VESUFJZ0dVOGdCM0pGQkVBZ0NpQUdJQU4wSUF0MlFRRjBhaUlHTFFBQUlRY2dCU0FESUFZdEFBRnFOZ0lZSUFJZ0J6b0FBQ0FDUVFGcUlRSU1BUXNMQTBBZ0FpQVpUMFVFUUNBS0lBWWdBM1FnQzNaQkFYUnFJZ2N0QUFFaENDQUNJQWN0QUFBNkFBQWdBa0VCYWlFQ0lBTWdDR29oQXd3QkN3c0RRQ0FGRUE4Z0JDQWRUM0pGQkVBZ0NpQUZLQUlBSWdJZ0JTZ0NCQ0lHZENBTGRrRUJkR29pQnkwQUFTRUlJQVFnQnkwQUFEb0FBQ0FLSUFJZ0JpQUlhaUlDZENBTGRrRUJkR29pQmkwQUFDRUhJQVVnQWlBR0xRQUJhallDQkNBRUlBYzZBQUVnQkVFQ2FpRUVEQUVMQ3dOQUlBVVFEeUVISUFVb0FnQWhCaUFGS0FJRUlRSWdCQ0FjVHlBSGNrVUVRQ0FLSUFZZ0FuUWdDM1pCQVhScUlnWXRBQUFoQnlBRklBSWdCaTBBQVdvMkFnUWdCQ0FIT2dBQUlBUkJBV29oQkF3QkN3c0RRQ0FFSUJ4UFJRUkFJQW9nQmlBQ2RDQUxka0VCZEdvaUJ5MEFBU0VJSUFRZ0J5MEFBRG9BQUNBRVFRRnFJUVFnQWlBSWFpRUNEQUVMQzBGc1FXeEJiRUZzUVd4QmJFRnNRV3dnQVNBQ1FTQkhHeUFGS0FJSUlBVW9BZ3hIR3lBRFFTQkhHeUFGS0FJY0lBVW9BaUJIR3lBQVFTQkhHeUFGS0FJd0lBVW9BalJIR3lBSlFTQkhHeUFGS0FKRUlBVW9Ba2hIR3lFSkRBRUxRV3doQ1FzZ0JVSFFBR29rQUNBSkMxZ0JBMzhDUUNBQUtBS1E2d0VpQVVVTkFDQUJLQUlBSUFGQnROVUJhaWdDQUNJQ0lBRkJ1TlVCYWlnQ0FDSURFQk1nQWdSQUlBTWdBU0FDRVFJQURBRUxJQUVRQmdzZ0FFRUFOZ0tnNndFZ0FFSUFOd09RNndFTDZRTUNCSDhDZmlBQVFRQkJLQkFESVFRZ0FrRUJRUVVnQXhzaUFFa0VRQ0FBRHdzZ0FVVUVRRUYvRHd0QkFTRUdBa0FDUUNBRFFRRkdEUUFnQXlFR0lBRW9BQUFpQlVHbzZyNXBSZzBBUVhZaEF5QUZRWEJ4UWREVXRNSUJSdzBCUVFnaEF5QUNRUWhKRFFFZ0FUVUFCQ0VJSUFSQkFUWUNGQ0FFSUFnM0F3QkJBQThMSUFFZ0FpQUdFQm9pQXlBQ1N3MEFJQVFnQXpZQ0dFRnlJUU1nQUNBQmFpSUZRUUZyTFFBQUlnSkJDSEVOQUNBQ1FTQnhJZ1pGQkVCQmNDRURJQVV0QUFBaUJVR25BVXNOQVNBRlFRZHhyVUlCSUFWQkEzWkJDbXF0aGlJSVFnT0lmaUFJZkNFSklBQkJBV29oQUFzZ0FrRUdkaUVGSUFKQkFuWkJBQ0VEQWtBQ1FBSkFBa0FnQWtFRGNVRUJhdzREQUFFQ0F3c2dBQ0FCYWkwQUFDRURJQUJCQVdvaEFBd0NDeUFBSUFGcUx3QUFJUU1nQUVFQ2FpRUFEQUVMSUFBZ0FXb29BQUFoQXlBQVFRUnFJUUFMUVFGeElRSUNmZ0pBQWtBQ1FBSkFJQVZCQVdzT0F3RUNBd0FMUW44Z0JrVU5BeG9nQUNBQmFqRUFBQXdEQ3lBQUlBRnFNd0FBUW9BQ2ZBd0NDeUFBSUFGcU5RQUFEQUVMSUFBZ0FXb3BBQUFMSVFnZ0JDQUNOZ0lnSUFRZ0F6WUNIQ0FFSUFnM0F3QkJBQ0VESUFSQkFEWUNGQ0FFSUFnZ0NTQUdHeUlJTndNSUlBUkNnSUFJSUFnZ0NFS0FnQWhhR3o0Q0VBc2dBd3RmQVFGL1FiaC9JUU1nQVVFQlFRVWdBaHNpQWs4RWZ5QUFJQUpxUVFGckxRQUFJZ0JCQTNGQkFuUkJvQjVxS0FJQUlBSnFJQUJCQkhaQkRIRkJzQjVxS0FJQWFpQUFRU0J4SWdGRmFpQUJRUVYySUFCQndBQkpjV29GUWJoL0N3c01BQ0FBSUFFZ0FrRUFFQmtMbHdNQ0JYOENmaU1BUVVCcUlnUWtBQUpBQTBBZ0FVRUZUd1JBQWtBZ0FDZ0FBRUZ3Y1VIUTFMVENBVVlFUUVKK0lRY2dBVUVJU1EwRUlBQW9BQVFpQWtGM1N3MEVJQUpCQ0dvaUF5QUJTdzBFSUFKQmdYOUpEUUVNQkFzZ0JFRVlhaUFBSUFFUUd5RUNRbjRnQkNrREdFSUFJQVFvQWl4QkFVY2JJQUliSWdkQ2ZWWU5BeUFISUFoOElnZ2dCMVJDZmlFSERRTUNRQUpBSUFGQkNFa05BQ0FBS0FBQVFYQnhRZERVdE1JQlJ3MEFJQUFvQUFRaUFrRjNTdzBGUWJoL0lBSkJDR29pQWlBQklBSkpHeUVEREFFTElBUkJHR29nQUNBQkVCc2lBa0dJZjBzRVFDQUNJUU1NQVF0QnVIOGhBeUFDRFFBZ0FTQUVLQUl3SWdKcklRVWdBQ0FDYWlFR0EwQWdCaUFGSUFSQkRHb1FIU0lEUVloL1N3MEJJQU5CQTJvaUFpQUZTd1JBUWJoL0lRTU1BZ3NnQlNBQ2F5RUZJQUlnQm1vaEJpQUVLQUlRUlEwQUN5QUVLQUk0Qkg5QnVIOGhBeUFGUVFSSkRRRWdCa0VFYWdVZ0Jnc2dBR3NoQXdzZ0EwR0lmMHNOQXdzZ0FTQURheUVCSUFBZ0Eyb2hBQXdCQ3d0Q2ZpQUlJQUViSVFjTElBUkJRR3NrQUNBSEMyUUJBWDlCdUg4aEF3SkFJQUZCQTBrTkFDQUFMUUFDSVFFZ0FpQUFMd0FBSWdCQkFYRTJBZ1FnQWlBQVFRRjJRUU54SWdNMkFnQWdBaUFBSUFGQkVIUnlRUU4ySWdBMkFnZ0NRQUpBSUFOQkFXc09Bd0lCQUFFTFFXd1BDeUFBSVFNTElBTUxSQUVDZnlBQklBSW9BZ1FpQXlBQktBSUVhaUlFTmdJRUlBQWdBMEVDZEVHZ0hXb29BZ0FnQVNnQ0FFRUFJQVJyZG5FMkFnQWdBUkFQR2lBQUlBSkJDR28yQWdRTHpnRUJCbjlCdW44aENnSkFJQUlvQWdRaUNDQUNLQUlBSWdscUlnMGdBU0FBYTBzTkFFRnNJUW9nQ1NBRUlBTW9BZ0FpQzJ0TERRQWdBQ0FKYWlJRUlBSW9BZ2dpREdzaEFpQUFJQUZCSUdzaUFDQUxJQWxCQUJBZ0lBTWdDU0FMYWpZQ0FBSkFBa0FnQkNBRmF5QU1Ud1JBSUFJaEJRd0JDeUFNSUFRZ0JtdExEUUlnQnlBSElBSWdCV3NpQW1vaUFTQUlhazhFUUNBRUlBRWdDQkFLR2d3Q0N5QUNJQWhxSVFnZ0JDQUJRUUFnQW1zUUNpQUNheUVFQ3lBRUlBQWdCU0FJUVFFUUlBc2dEU0VLQ3lBS0M4Y0VBUUovSUFBZ0Eyb2hCZ0pBSUFOQkIwd0VRQU5BSUFBZ0JrOE5BaUFBSUFJdEFBQTZBQUFnQUVFQmFpRUFJQUpCQVdvaEFnd0FDd0FMSUFSQkFVWUVRQUpBSUFBZ0Ftc2lCVUVIVFFSQUlBQWdBaTBBQURvQUFDQUFJQUl0QUFFNkFBRWdBQ0FDTFFBQ09nQUNJQUFnQWkwQUF6b0FBeUFBSUFJZ0JVRUNkQ0lGUWNBZWFpZ0NBR29pQWlnQUFEWUFCQ0FDSUFWQjRCNXFLQUlBYXlFQ0RBRUxJQUFnQWlrQUFEY0FBQXNnQWtFSWFpRUNJQUJCQ0dvaEFBc2dBU0FHVHdSQUlBQWdBMm9oQVNBRVFRRkhJQUFnQW10QkQwcHlSUVJBQTBBZ0FDQUNLUUFBTndBQUlBSkJDR29oQWlBQVFRaHFJZ0FnQVVrTkFBd0RDd0FMSUFBZ0Fpa0FBRGNBQUNBQUlBSXBBQWczQUFnZ0EwRVJTUTBCSUFCQkVHb2hBQU5BSUFBZ0Fpa0FFRGNBQUNBQUlBSXBBQmczQUFnZ0FDQUNLUUFnTndBUUlBQWdBaWtBS0RjQUdDQUNRU0JxSVFJZ0FFRWdhaUlBSUFGSkRRQUxEQUVMQWtBZ0FDQUJTd1JBSUFBaEFRd0JDeUFCSUFCcklRVUNRQ0FFUVFGSElBQWdBbXRCRDBweVJRUkFJQUloQXdOQUlBQWdBeWtBQURjQUFDQURRUWhxSVFNZ0FFRUlhaUlBSUFGSkRRQUxEQUVMSUFBZ0Fpa0FBRGNBQUNBQUlBSXBBQWczQUFnZ0JVRVJTQTBBSUFCQkVHb2hBQ0FDSVFNRFFDQUFJQU1wQUJBM0FBQWdBQ0FES1FBWU53QUlJQUFnQXlrQUlEY0FFQ0FBSUFNcEFDZzNBQmdnQTBFZ2FpRURJQUJCSUdvaUFDQUJTUTBBQ3dzZ0FpQUZhaUVDQ3dOQUlBRWdCazhOQVNBQklBSXRBQUE2QUFBZ0FVRUJhaUVCSUFKQkFXb2hBZ3dBQ3dBTEM2NEhBZ1YvQVg0akFFR0FBV3NpRVNRQUlCRWdBellDZkVGL0lROENRQUpBQWtBQ1FBSkFJQUlPQkFFQUF3SUVDeUFHUlFSQVFiaC9JUThNQkF0QmJDRVBJQVV0QUFBaUFpQURTdzBESUFnZ0FrRUNkQ0lDYWlnQ0FDRURJQUlnQjJvb0FnQWhBaUFBUVFBNkFBc2dBRUlBTndJQUlBQWdBallDRENBQUlBTTZBQW9nQUVFQU93RUlJQUVnQURZQ0FFRUJJUThNQXdzZ0FTQUpOZ0lBUVFBaER3d0NDeUFLUlFSQVFXd2hEd3dDQzBFQUlROGdDMFVnREVFWlNISU5BVUVJSUFSMFFRaHFJUUJCQUNFREEwQWdBQ0FEVFEwQ0lBTkJRR3NoQXd3QUN3QUxRV3doRHlBUklCRkIvQUJxSUJGQitBQnFJQVVnQmhBTUlnTkJpSDlMRFFBZ0VTZ0NlQ0lDSUFSTERRQWdFU2dDZkVFQmFpRUpJQUJCQ0dvaEMwR0FnQUlnQW5SQkVIVWhCVUVCSVJCQkFTQUNkQ0lQUVFGcklnb2hFZ05BSUFrZ0RrY0VRQUpBSUJFZ0RrRUJkQ0lFYWk4QkFDSU1RZi8vQTBZRVFDQUxJQkpCQTNScUlBNDJBZ1FnRWtFQmF5RVNRUUVoREF3QkN5QVFRUUFnQlNBTXdVb2JJUkFMSUFRZ0RXb2dERHNCQUNBT1FRRnFJUTRNQVFzTElBQWdBallDQkNBQUlCQTJBZ0FDUUNBS0lCSkdCRUFnRFVIcUFHb2hCa0VBSVJCQkFDRU1BMEFnQ1NBUVJnUkFJQTlCQTNZZ0QwRUJkbXBCQTJvaUJVRUJkQ0VFUVFBaERFRUFJUklEUUVFQUlRNGdEeUFTVFEwRUEwQWdEa0VDUndSQUlBc2dCU0FPYkNBTWFpQUtjVUVEZEdvZ0JpQU9JQkpxYWkwQUFEWUNCQ0FPUVFGcUlRNE1BUXNMSUJKQkFtb2hFaUFFSUF4cUlBcHhJUXdNQUFzQUJTQVJJQkJCQVhScUxnRUFJUVVnQmlBTWFpSUVJQk0zQUFCQkNDRU9BMEFnQlNBT1NnUkFJQVFnRG1vZ0V6Y0FBQ0FPUVFocUlRNE1BUXNMSUJOQ2dZS0VpSkNnd0lBQmZDRVRJQkJCQVdvaEVDQUZJQXhxSVF3TUFRc0FDd0FMSUE5QkEzWWdEMEVCZG1wQkEyb2hCVUVBSVJCQkFDRU9BMEFnQ1NBUVJnMEJRUUFoRENBUklCQkJBWFJxTGdFQUlnUkJBQ0FFUVFCS0d5RUVBMEFnQkNBTVJ3UkFJQXNnRGtFRGRHb2dFRFlDQkFOQUlBVWdEbW9nQ25FaURpQVNTdzBBQ3lBTVFRRnFJUXdNQVFzTElCQkJBV29oRUF3QUN3QUxJQUpCQVdvaEJVRUFJUXdEUUNBTUlBOUhCRUFnRFNBTElBeEJBM1JxSWdrb0FnUWlCRUVCZEdvaUFpQUNMd0VBSWdaQkFXbzdBUUFnQ1NBRklBWm5RV0J6YWlJQ09nQURJQWtnQmlBQ2RDQVBhenNCQUNBSklBZ2dCRUVDZENJQ2FpZ0NBRG9BQWlBSklBSWdCMm9vQWdBMkFnUWdERUVCYWlFTURBRUxDeUFCSUFBMkFnQWdBeUVQQ3lBUlFZQUJhaVFBSUE4TDdWb0NPMzhHZmlNQVFlQUJheUlFSkFBQ1FFR3c3QWtRQlNJRlJRUkFRVUFoQnd3QkN5QUZRZ0EzQXZUcUFTQUZRUUEyQXNUckFTQUZRUUEyQXJUckFTQUZRZ0EzQXB6ckFTQUZRUUEyQXJqcEFTQUZRUUEyQXF6c0NTQUZRZ0EzQXRUckFTQUZRZ0EzQXF6ckFTQUZRZ0EzQTRqckFTQUZRZ0EzQXVUcUFTQUZRZ0EzQXVUckFTQUZRWUdBZ01BQU5nSzg2d0VnQlVJQU53S2s2d0VnQlVIODZnRnFRUUEyQWdBZ0JVR1E2d0ZxUWdBM0F3QWdCUkFZSUFWQnJOVUJhaUVVSUFWQitPc0JhaUVjSUFWQnNPb0JhaUVpSUFWQm9EQnFJU29nQlVHWUlHb2hLeUFGUWFqUUFHb2hIaUFGUVJCcUlTd2dCVUVJYWlFb0lBVkJCR29oTFNBRlFjRHBBV29oS1NBRlFZanJBV29nQkVHVUFXb2hMeUFFUVl3QmFpRXdJQVJCaEFGcUlURWdCRUhjQUdvaE1pQUVRZFFBYWlFeklBUkJ6QUJxSVRRZ0FDRWRBa0FDUUFKQUFrQUNRQU5BUVFGQkJTQUZLQUxrNmdFYklRWUNRQU5BSUFNZ0Jra05BU0FDS0FBQVFYQnhRZERVdE1JQlJnUkFRYmgvSVFjZ0EwRUlTUTBJSUFJb0FBUWlEa0YzU3dSQVFYSWhCd3dKQ3lBRElBNUJDR29pQ1VrTkNDQU9RWUIvU3dSQUlBa2hCd3dKQ3lBRElBbHJJUU1nQWlBSmFpRUNEQUVMQ3lBRlFnQTNBcXpwQVNBRlFnQTNBK2pwQVNBRlFRQTJBcGpyQVNBRlFnQTNBNERxQVNBRlFnTTNBL2pwQVNBRlFiVHBBV3BDQURjQ0FDQUZRZkRwQVdwQ0FEY0RBQ0FGUWFqUUFHb2lDVUdNZ0lEZ0FEWUNBQ0FGUWF6UUFXcEI0QklwQWdBM0FnQWdCVUcwMEFGcVFlZ1NLQUlBTmdJQUlBVWdCVUVRYWpZQ0FDQUZJQVZCb0RCcU5nSUVJQVVnQlVHWUlHbzJBZ2dnQlNBSk5nSU1JQVZCQVVFRklBVW9BdVRxQVJzMkFyenBBUUpBSUFGRkRRQWdCU2dDck9rQklna2dIVVlOQUNBRklBazJBcmpwQVNBRklCMDJBcXpwQVNBRktBS3c2UUVoRGlBRklCMDJBckRwQVNBRklCMGdEaUFKYTJvMkFyVHBBUXRCdUg4aENTQURRUVZCQ1NBRktBTGs2Z0VpQmh0SkRRVWdBa0VCUVFVZ0Joc2dCaEFhSWc1QmlIOUxCRUFnRGlFSkRBVUxJQU1nRGtFRGFra05CU0FwSUFJZ0RpQUdFQmtpQmtHSWYwc0VRQ0FHSVFrTUJRc2dCZzBGQWtBQ1FDQUZLQUtvNndGQkFVY05BQ0FGS0FLazZ3RWlDVVVOQUNBRktBS1U2d0ZGRFFBZ0NTZ0NCRUVCYXlJSElBVW9BdHpwQVNJS3JVS0hsYSt2bUxiZW01NS9ma0xKejlteThlVzY2aWVGUWhlSlFzL1cwNzdTeDZ2WlFuNUMrZlBkOFpuMm1hc1dmQ0kvUWlHSUlEK0ZRcy9XMDc3U3g2dlpRbjRpUDBJZGlDQS9oVUw1ODkzeG1mYVpxeForSWo5Q0lJZ2dQNFduY1NFR0lBa29BZ0FoRlFOQVFRQWhDQUpBSUJVZ0JrRUNkR29vQWdBaUNVVU5BQ0FKS0FJSVFRaEpEUUFnQ1NnQ0JDSVNLQUFBUWJmSXd1RitSdzBBSUJJb0FBUWhDQXNnQ0NBS1J3UkFJQVlnQjNGQkFXb2hCaUFJRFFFTEN5QUpSUTBBSUFVUUdDQUZRWDgyQXFEckFTQUZJQWsyQXBUckFTQUZJQVVvQXR6cEFTSUlOZ0tZNndFTUFRc2dCU2dDM09rQklRZ0xBa0FnQ0VVTkFDQUZLQUtZNndFZ0NFWU5BRUZnSVFrTUJnc0NRQ0FGS0FMZzZRRUVRQ0FGSUFVb0F1anFBU0lKUlRZQzdPb0JJQWtOQVNBRlF2bnEwTkRueWFIazRRQTNBNmpxQVNBRlFnQTNBNkRxQVNBRlFzL1cwNzdTeDZ2WlFqY0RtT29CSUFWQzF1dUM3dXI5aWZYZ0FEY0RrT29CSUFWQ0FEY0RpT29CSUNKQkFFRW9FQU1hREFFTElBVkJBRFlDN09vQkN5QUJJQjFxSVNVZ0JTQUZLUVBvNlFFZ0RxMThOd1BvNlFFZ0F5QU9heUVESUFJZ0Rtb2hBaUFkSVE0RFFDQUNJQU1nQkVFc2FoQWRJaFZCaUg5TEJFQWdGU0VKREFZTElBTkJBMnNpTlNBVlNRMEVJQUpCQTJvaEcwRnNJUWtDUUFKQUFrQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUFrQUNRQUpBQWtBQ1FDQUVLQUlzRGdNQ0FRQVZDeUFWUWYvL0Iwc05FeUFWUVFOSkRSSWdCU2tEeU9rQklUOENRQUpBSUJzdEFBQWlDVUVEY1NJYVFRRnJEZ01HQVFBSEN5QUZLQUtBNmdFTkFFRmlJUWtNRlFzZ0ZVRUZTUTBTSUJzb0FBQWhBd0ovQWtBQ1FBSkFJQWxCQW5aQkEzRWlDVUVDYXc0Q0FRSUFDeUFKUVFCSElRY2dBMEVFZGtIL0IzRWhDMEVESVFZZ0EwRU9ka0gvQjNFTUFndEJCQ0VHSUFOQkJIWkIvLzhBY1NFTFFRRWhCeUFEUVJKMkRBRUxJQU5CQkhaQi8vOFBjU0lMUVlDQUNFc05FMEVCSVFkQkJTRUdJQUl0QUFkQkNuUWdBMEVXZG5JTElnZ2dCbW9pQ1NBVlN3MFNBa0FnQzBHQkJra05BQ0FGS0FLYzZ3RkZEUUJCQUNFREEwQWdBMEdEZ0FGTERRRWdBMEZBYXlFRERBQUxBQXNnQmlBYmFpRVBJQnBCQTBjTkJpQUZLQUlNSWdJdEFBRkJDSFFoQXlBSERRY2dBMFVOQ0NBRVFmQUFhaUFQSUFnUURTSURRWWgvU3cwSklBSkJCR29oQmlBTElCeHFJaEpCQTJzaENrRUFJQUl2QVFKclFSOXhJUWNnSENFREEwQWdCRUh3QUdvUUQwVWdBeUFLU1hFRVFDQURJQVlnQkNnQ2NDSUlJQVFvQW5RaUQzUWdCM1pCQW5ScUlnSXZBUUE3QUFBZ0F5QUNMUUFEYWlJRElBWWdDQ0FQSUFJdEFBSnFJZ2gwSUFkMlFRSjBhaUlDTHdFQU93QUFJQVFnQ0NBQ0xRQUNhallDZENBRElBSXRBQU5xSVFNTUFRVWdFa0VDYXlFSUEwQWdCRUh3QUdvUUR5RVBJQVFvQW5BaENpQUVLQUowSVFJZ0F5QUlTeUFQY2tVRVFDQURJQVlnQ2lBQ2RDQUhka0VDZEdvaUNpOEJBRHNBQUNBRUlBSWdDaTBBQW1vMkFuUWdBeUFLTFFBRGFpRUREQUVMQ3dOQUlBTWdDRTBFUUNBRElBWWdDaUFDZENBSGRrRUNkR29pRHk4QkFEc0FBQ0FESUE4dEFBTnFJUU1nQWlBUExRQUNhaUVDREFFTEN3SkFJQU1nRWs4TkFDQURJQVlnQ2lBQ2RDQUhka0VDZEdvaUF5MEFBRG9BQUNBRExRQURRUUZHQkVBZ0FpQURMUUFDYWlFQ0RBRUxJQUpCSDBzTkFFRWdJQUlnQXkwQUFtb2lBaUFDUVNCUEd5RUNDMEZzUVd3Z0N5QUVLQUo0SUFRb0FueEhHeUFDUVNCSEd5RUREQXNMQUFzQUN5QUVLQUkwSWdJZ0pTQU9hMHNOQ2lBT1JRUkFRUUFoQ1NBQ0RRSU1EZ3NnRGlBYkxRQUFJQUlRQXhvZ0FpRUpEQXdMSUJVZ0pTQU9hMHNOQ1NBT0RRRkJBQ0VKSUJWRkRRd0xRYlovSVFrTUVRc2dEaUFiSUJVUUFob2dGU0VKREFvTElCd2dHd0ovQWtBQ1FBSkFJQWxCQW5aQkEzRkJBV3NPQXdFQUFnQUxJQWxCQTNZaEEwRUJEQUlMSUJzdkFBQkJCSFloQTBFQ0RBRUxJQlZCQkVrTkRpQUNMd0FESUFJdEFBVkJFSFJ5SWdKQmo0Q0FBVXNORGlBQ1FRUjJJUU5CQXdzaUFtb3RBQUFnQTBFZ2FoQURJUWtnQlNBRE5nS0E2d0VnQlNBSk5nTHc2Z0VnQWtFQmFpRUpEQVVMSUJVQ2Z3SkFBa0FDUUNBSlFRSjJRUU54UVFGckRnTUJBQUlBQ3lBSlFRTjJJUU5CQVF3Q0N5QWJMd0FBUVFSMklRTkJBZ3dCQ3lBQ0x3QURJQUl0QUFWQkVIUnlRUVIySVFOQkF3c2lBaUFEYWlJSlFTQnFTUVJBSUFrZ0ZVc05EU0FjSUFJZ0cyb2dBeEFDSVFJZ0JTQUROZ0tBNndFZ0JTQUNOZ0x3NmdFZ0FpQURhaUlDUWdBM0FCZ2dBa0lBTndBUUlBSkNBRGNBQ0NBQ1FnQTNBQUFNQlFzZ0JTQUROZ0tBNndFZ0JTQUNJQnRxTmdMdzZnRU1CQXNnQjBVRVFDQWVJQThnQ0NBVUVCUWlBa0dJZjBzZ0FpQUlUM0lORENBY0lBc2dBaUFQYWlBSUlBSnJJQjRRRlNFRERBTUxJQXRGSUFoRmNnMExJQXRCQ0hZaUF5QUlJQXRKQkg4Z0NFRUVkQ0FMYmdWQkR3dEJHR3dpQWtHTUNHb29BZ0JzSUFKQmlBaHFLQUlBYWlJR1FRTjJJQVpxSUFKQmdBaHFLQUlBSUFKQmhBaHFLQUlBSUFOc2Fra0VRQ01BUVJCckloQWtBQ0FlS0FJQUlRTWdGRUh3QkdwQkFFSHNBQkFESVFaQlZDRUNBa0FnQTBIL0FYRWlERUVNU3cwQUFrQWdGRUhjQ1dvZ0JpQVFRUWhxSUJCQkRHb2dEeUFJSUJSQjNBdHFJaGNRQ3lJU1FZaC9TdzBBSUJBb0Fnd2lCaUFNU3cwQklCUkJxQVZxSVEwZ0ZFR2tCV29oTmlBZVFRUnFJUkVnQTBHQWdJQjRjU0UzSUFaQkFXb2lFeUVDSUFZaEF3TkFJQUlpQjBFQmF5RUNJQU1pQ2tFQmF5RURJQlFnQ2tFQ2RHb29BdkFFUlEwQUMwRUJJQWNnQjBFQlRSc2hGa0VBSVFkQkFTRUNBMEFnQWlBV1J3UkFJQlFnQWtFQ2RDSURhaWdDOEFRaEdDQURJQTFxSUFjMkFnQWdBa0VCYWlFQ0lBY2dHR29oQnd3QkN3c2dEU0FITmdJQVFRQWhBaUFRS0FJSUlRTURRQ0FDSUFOSEJFQWdEU0FDSUJScVFkd0phaTBBQUNJWVFRSjBhaUlaSUJrb0FnQWlHVUVCYWpZQ0FDQVVJQmxCQVhScUloa2dHRG9BM1FVZ0dTQUNPZ0RjQlNBQ1FRRnFJUUlNQVFzTFFRQWhBeUFOUVFBMkFnQWdEQ0FHUVg5emFpRUdRUUVoQWdOQUlBSWdGa2NFUUNBVUlBSkJBblJxSWcwZ0F6WUNBQ0FOS0FMd0JDQUNJQVpxZENBRGFpRURJQUpCQVdvaEFnd0JDd3NnRENBVElBcHJJZ1pyUVFGcUlRb2dCaUVEQTBBZ0F5QUtTUVJBSUJRZ0EwRTBiR29oRFVFQklRSURRQ0FDSUJaSEJFQWdEU0FDUVFKMEloaHFJQlFnR0dvb0FnQWdBM1kyQWdBZ0FrRUJhaUVDREFFTEN5QURRUUZxSVFNTUFRc0xJQmNnRkVFMEVBSWhPQ0FVUVpBTWFpRTVJQk1nREdzaE9pQVVRZHdGYWlFWFFRQWhDZ05BQWtBQ1FDQUhJQXBIQkVCQkFTQU1JQk1nRnlBS1FRRjBhaUlDTFFBQklnMXJJZ05ySWhoMElSa2dBaTBBQUNFV0lEZ2dEVUVDZEdvaUh5Z0NBQ0VDSUFZZ0dFMEVRQ0EyUVFFZ0F5QTZhaUlOSUExQkFVd2JJaUJCQW5RaUpHb29BZ0FoRFNBNUlCUWdBMEUwYkdwQk5CQUNJU0VnRFVFQmRDRW1JQkVnQWtFQ2RHb2hJeUFnUVFGTkRRSWdBMEVRZEVHQWdQd0hjU0FXY2tHQWdJQUljaUVnSUNFZ0pHb29BZ0FoSkVFQUlRSURRQ0FDSUNSR0RRTWdJeUFDUVFKMGFpQWdOZ0VBSUFKQkFXb2hBZ3dBQ3dBTElBSWdBaUFaYWlJTklBSWdEVXNiSVEwZ0EwRVFkRUdBZ1B3SGNTQVdja0dBZ0lBSWNpRURBMEFnQWlBTlJnMERJQkVnQWtFQ2RHb2dBellCQUNBQ1FRRnFJUUlNQUFzQUN5QWVJQXhCRUhRZ04zSWdESEpCZ0FKeU5nSUFEQU1MSUFjZ0RXc2hKQ0FYSUNacUlTWkJBQ0VOQTBBZ0RTQWtSZzBCUVFFZ0dDQVRJQ1lnRFVFQmRHb2lKeTBBQVNJQ2F5STdhM1FpUENBaElBSkJBblJxSWlBb0FnQWlBbW9oUFNBRElEdHFRUkIwUVlDQS9BZHhJQ2N0QUFCQkNIUnlJQlp5UVlDQWdCQnlJU2NEUUNBaklBSkJBblJxSUNjMkFRQWdBa0VCYWlJQ0lEMUpEUUFMSUNBZ0lDZ0NBQ0E4YWpZQ0FDQU5RUUZxSVEwTUFBc0FDeUFmSUI4b0FnQWdHV28yQWdBZ0NrRUJhaUVLREFBTEFBc2dFaUVDQ3lBUVFSQnFKQUFnQWtHSWYwc2dBaUFJVDNJTkRDQWNJQXNnQWlBUGFpQUlJQUpySUI0UUZpRUREQU1MSUI0Z0R5QUlJQlFRRkNJQ1FZaC9TeUFDSUFoUGNnMExJQndnQ3lBQ0lBOXFJQWdnQW1zZ0hoQVhJUU1NQWdzZ0F3UkFJQndnQ3lBUElBZ2dBaEFXSVFNTUFnc2dIQ0FMSUE4Z0NDQUNFQmNoQXd3QkN5QWNJQXNnRHlBSUlBSVFGU0VEQ3lBRFFZaC9TdzBJSUFVZ0N6WUNnT3NCSUFVZ0hEWUM4T29CSUFWQkFUWUNnT29CSUJwQkFrWUVRQ0FGSUI0MkFnd0xJQXNnSEdvaUFrSUFOd0FBSUFKQ0FEY0FHQ0FDUWdBM0FCQWdBa0lBTndBSUlBbEJpSDlMRFFvTElBa2dGVVlOQ0NBVklBbHJJUVlnQlNnQ25Pc0JJUW9DUUNBSklCdHFJZ010QUFBaUQwVUVRRUVCSVFKQkFDRVBRYmgvSVFrZ0JrRUJSZzBCREFzTEFuOGdBMEVCYWlBUHdDSUNRUUJPRFFBYUlBSkJmMFlFUUNBR1FRTklEUXNnQXk4QUFVR0EvZ0ZxSVE4Z0EwRURhZ3dCQ3lBR1FRSklEUW9nQXkwQUFTQVBRUWgwY2tHQWdBSnJJUThnQTBFQ2Fnc2hFa0c0ZnlFSklCSkJBV29pQWlBVklCdHFJZ2RMRFFvZ0xDQUZJQkl0QUFBaUVrRUdka0VqUVFrZ0FpQUhJQUpyUWNBUVFkQVJRZkFTSUFVb0FvVHFBU0FLSUE4Z0ZCQWhJZ2xCaUg5TERRZ2dLeUFvSUJKQkJIWkJBM0ZCSDBFSUlBSWdDV29pQWlBSElBSnJRWUFMUVlBTVFZQVhJQVVvQW9UcUFTQUZLQUtjNndFZ0R5QVVFQ0VpQ0VHSWYwc05DRUZzSVFrZ0tpQXRJQkpCQW5aQkEzRkJORUVKSUFJZ0NHb2lBaUFISUFKclFZQU5RZUFPUVpBWklBVW9Bb1RxQVNBRktBS2M2d0VnRHlBVUVDRWlCMEdJZjBzTkNpQUNJQWRxSUFOcklnSWhDU0FDUVloL1N3MEtDeUFPSUE5QkFFeHlEUUVMUWJwL0lRa01DQXNnSlNBT2F5RUpJQVlnQW1zaEJpQUNJQU5xSVFjQ1FBSkFBa0FnQ2tVRVFDQVBRUWxJSUFVcEE4anBBVUtCZ0lBSVZISU5BaUFvS0FJQUlnSkJDR29oRWlBQ0tBSUVJUXBCQUNFRFFRQWhBZ05BSUFNZ0NuWkZCRUFnQWlBU0lBTkJBM1JxTFFBQ1FSWkxhaUVDSUFOQkFXb2hBd3dCQ3dzZ0JVRUFOZ0tjNndFZ0FrRUlJQXByZEVFVVR3MEJEQU1MSUFWQkFEWUNuT3NCQ3lBRUlBVW9BdkRxQVNJRE5nTGNBU0FKSUE1cUlSWWdBeUFGS0FLQTZ3RnFJUmNDUUNBUFJRUkFJQTRoQnd3QkN5QUZLQUs0NlFFaEdpQUZLQUswNlFFaEdDQUZLQUt3NlFFaEVpQUZRUUUyQW9UcUFVRUFJUU1EUUNBRFFRTkhCRUFnQkNBRFFRSjBJZ0pxSUFJZ0JXcEJyTkFCYWlnQ0FEWUNaQ0FEUVFGcUlRTU1BUXNMUVd3aENTQUVRVGhxSWdJZ0J5QUdFQTFCaUg5TERRTkJDQ0FQSUE5QkNFNGJJUjhnTkNBQ0lBVW9BZ0FRSGlBeklBSWdCU2dDQ0JBZUlESWdBaUFGS0FJRUVCNGdEaUFTYXlFWlFRQWhDQU5BSUFSQk9Hb1FEMEVEUmlBSUlCOU9ja1VFUUNBRUtBSlFJQVFvQWt4QkEzUnFLUUlBSWtDbklnZEJFSFlpRVVIL0FYRWhDeUFFS0FKZ0lBUW9BbHhCQTNScUtRSUFJa0duSWd4QkVIWWlJVUgvQVhFaEVDQUVLQUpZSUFRb0FsUkJBM1JxS1FJQUlrSkNJSWluSVFZZ1FVSWdpQ0JBUWlDSXB5RURBa0FnUWtJUWlLY2lDa0gvQVhFaUFrRUNUd1JBQWtBZ0FrRVpTU0EvUW9HQWdCQlVja1VFUUNBRVFTQWdCQ2dDUENJS2F5SU5JQUlnQWlBTlN4c2lFeUFLYWpZQ1BDQUdJQVFvQWpnZ0NuUkJBQ0FUYTNZZ0FpQVRheUlUZEdvaENpQUVRVGhxRUE4YUlBSWdEVTBOQVNBRUlBUW9BandpQWlBVGFqWUNQQ0FFS0FJNElBSjBRUUFnRTJ0MklBcHFJUW9NQVFzZ0JDQUNJQVFvQWp3aURXbzJBandnQkNnQ09DQU5kRUVBSUFwcmRpQUdhaUVLSUFSQk9Hb1FEeG9MSUFRcEFtUWhSQ0FFSUFvMkFtUWdCQ0JFTndKb0RBRUxBa0FnQWtVRVFDQURCRUFnQkNnQ1pDRUtEQU1MSUFRb0FtZ2hDZ3dCQ3lBRUlBUW9BandpQWtFQmFqWUNQQUovSUFZZ0EwVnFJQVFvQWpnZ0FuUkJIM1pxSWdKQkEwWUVRQ0FFS0FKa1FRRnJEQUVMSUFKQkFuUWdCR29vQW1RTElnWkZJQVpxSVFvZ0FrRUJSd1JBSUFRZ0JDZ0NhRFlDYkFzTElBUWdCQ2dDWkRZQ2FDQUVJQW8yQW1RTHB5RUNJRUZDZ0lEOEI0TlFSUVJBSUFRZ0JDZ0NQQ0lHSUJCcU5nSThJQVFvQWpnZ0JuUkJBQ0FoYTNZZ0Ftb2hBZ3NnQ3lBUWFrRVVUd1JBSUFSQk9Hb1FEeG9MSUVCQ2dJRDhCNE5RUlFSQUlBUWdCQ2dDUENJR0lBdHFOZ0k4SUFRb0FqZ2dCblJCQUNBUmEzWWdBMm9oQXdzZ0JFRTRhaEFQR2lBRUlBUW9BamdpQmtFQUlBZEJHSFlpQ3lBRUtBSThhaUlRYTNZZ0MwRUNkRUdnSFdvb0FnQnhJQWRCLy84RGNXbzJBa3dnQkNBUUlBeEJHSFlpQjJvaUN6WUNQQ0FFSUFkQkFuUkJvQjFxS0FJQUlBWkJBQ0FMYTNaeElBeEIvLzhEY1dvMkFsd2dCRUU0YWhBUEdpQUVJRUtuSWdaQkdIWWlCeUFFS0FJOGFpSUxOZ0k4SUFRZ0IwRUNkRUdnSFdvb0FnQWdCQ2dDT0VFQUlBdHJkbkVnQmtILy93TnhhallDVkNBRVFmQUFhaUFJUVF4c2FpSUdJQW8yQWdnZ0JpQUNOZ0lFSUFZZ0F6WUNBQ0FJUVFGcUlRZ2dBeUFaYWlBQ2FpRVpEQUVMQ3lBSUlCOUlEUU1nRmtFZ2F5RWhJQTRoQndOQUlBUkJPR29RRDBFRFJpQUlJQTlPY2tVRVFDQUVLQUpRSUFRb0FreEJBM1JxS1FJQUlrQ25JZ1pCRUhZaUkwSC9BWEVoQ2lBRUtBSmdJQVFvQWx4QkEzUnFLUUlBSWtHbklnMUJFSFlpSUVIL0FYRWhFeUFFS0FKWUlBUW9BbFJCQTNScUtRSUFJa0pDSUlpbklRTWdRVUlnaUNCQVFpQ0lweUVMQWtBZ1FrSVFpS2NpREVIL0FYRWlBa0VDVHdSQUFrQWdBa0VaU1NBL1FvR0FnQkJVY2tVRVFDQUVRU0FnQkNnQ1BDSU1heUlSSUFJZ0FpQVJTeHNpRUNBTWFqWUNQQ0FESUFRb0FqZ2dESFJCQUNBUWEzWWdBaUFRYXlJTWRHb2hFQ0FFUVRocUVBOGFJQUlnRVUwTkFTQUVJQVFvQWp3aUFpQU1hallDUENBRUtBSTRJQUowUVFBZ0RHdDJJQkJxSVJBTUFRc2dCQ0FDSUFRb0Fqd2lFR28yQWp3Z0JDZ0NPQ0FRZEVFQUlBeHJkaUFEYWlFUUlBUkJPR29RRHhvTElBUXBBbVFoUkNBRUlCQTJBbVFnQkNCRU53Sm9EQUVMQWtBZ0FrVUVRQ0FMQkVBZ0JDZ0NaQ0VRREFNTElBUW9BbWdoRUF3QkN5QUVJQVFvQWp3aUFrRUJhallDUEFKL0lBTWdDMFZxSUFRb0FqZ2dBblJCSDNacUlnSkJBMFlFUUNBRUtBSmtRUUZyREFFTElBSkJBblFnQkdvb0FtUUxJZ05GSUFOcUlSQWdBa0VCUndSQUlBUWdCQ2dDYURZQ2JBc0xJQVFnQkNnQ1pEWUNhQ0FFSUJBMkFtUUxweUVNSUVGQ2dJRDhCNE5RUlFSQUlBUWdCQ2dDUENJQ0lCTnFOZ0k4SUFRb0FqZ2dBblJCQUNBZ2EzWWdER29oREFzZ0NpQVRha0VVVHdSQUlBUkJPR29RRHhvTElFQkNnSUQ4QjROUVJRUkFJQVFnQkNnQ1BDSUNJQXBxTmdJOElBUW9BamdnQW5SQkFDQWphM1lnQzJvaEN3c2dCRUU0YWhBUEdpQUVJQVFvQWpnaUFrRUFJQVpCR0hZaUF5QUVLQUk4YWlJS2EzWWdBMEVDZEVHZ0hXb29BZ0J4SUFaQi8vOERjV28yQWt3Z0JDQUtJQTFCR0hZaUEyb2lCallDUENBRUlBTkJBblJCb0IxcUtBSUFJQUpCQUNBR2EzWnhJQTFCLy84RGNXbzJBbHdnQkVFNGFoQVBHaUFFSUVLbklnSkJHSFlpQXlBRUtBSThhaUlHTmdJOElBUWdBMEVDZEVHZ0hXb29BZ0FnQkNnQ09FRUFJQVpyZG5FZ0FrSC8vd054YWpZQ1ZBSkFBa0FDUUNBRUtBTGNBU0lESUFSQjhBQnFJQWhCQjNGQkRHeHFJaE1vQWdBaUVXb2lJeUFYU3cwQUlBY2dFeWdDQkNJTklCRnFJZ3BxSUNGTERRQWdDa0VnYWlBV0lBZHJUUTBCQ3lBRUlCTW9BZ2cyQWhnZ0JDQVRLUUlBTndNUUlBY2dGaUFFUVJCcUlBUkIzQUZxSUJjZ0VpQVlJQm9RSHlFS0RBRUxJQWNnRVdvaEFpQVRLQUlJSVFZZ0J5QURLUUFBTndBQUlBY2dBeWtBQ0RjQUNBSkFJQkZCRVVrTkFDQUhJQU1wQUJBM0FCQWdCeUFES1FBWU53QVlJQkZCRUd0QkVVZ05BQ0FEUVJCcUlRTWdCMEVnYWlFUkEwQWdFU0FES1FBUU53QUFJQkVnQXlrQUdEY0FDQ0FSSUFNcEFDQTNBQkFnRVNBREtRQW9Od0FZSUFOQklHb2hBeUFSUVNCcUloRWdBa2tOQUFzTElBSWdCbXNoQXlBRUlDTTJBdHdCSUFJZ0Vtc2dCa2tFUUNBR0lBSWdHR3RMRFFjZ0dpQWFJQU1nRW1zaUEyb2lFU0FOYWs4RVFDQUNJQkVnRFJBS0dnd0NDeUFESUExcUlRMGdBaUFSUVFBZ0Eyc1FDaUFEYXlFQ0lCSWhBd3NnQmtFUVR3UkFJQUlnQXlrQUFEY0FBQ0FDSUFNcEFBZzNBQWdnRFVFUlNBMEJJQUlnRFdvaEJpQUNRUkJxSVFJRFFDQUNJQU1wQUJBM0FBQWdBaUFES1FBWU53QUlJQUlnQXlrQUlEY0FFQ0FDSUFNcEFDZzNBQmdnQTBFZ2FpRURJQUpCSUdvaUFpQUdTUTBBQ3d3QkN3SkFJQVpCQjAwRVFDQUNJQU10QUFBNkFBQWdBaUFETFFBQk9nQUJJQUlnQXkwQUFqb0FBaUFDSUFNdEFBTTZBQU1nQWlBRElBWkJBblFpQmtIQUhtb29BZ0JxSWdNb0FBQTJBQVFnQXlBR1FlQWVhaWdDQUdzaEF3d0JDeUFDSUFNcEFBQTNBQUFMSUExQkNVa05BQ0FDSUExcUlSRWdBa0VJYWlJR0lBTkJDR29pQTJ0QkQwd0VRQU5BSUFZZ0F5a0FBRGNBQUNBRFFRaHFJUU1nQmtFSWFpSUdJQkZKRFFBTUFnc0FDeUFHSUFNcEFBQTNBQUFnQmlBREtRQUlOd0FJSUExQkdVZ05BQ0FDUVJocUlRSURRQ0FDSUFNcEFCQTNBQUFnQWlBREtRQVlOd0FJSUFJZ0F5a0FJRGNBRUNBQ0lBTXBBQ2czQUJnZ0EwRWdhaUVESUFKQklHb2lBaUFSU1EwQUN3c2dDa0dJZjBzRVFDQUtJUWtNQmdVZ0V5QVFOZ0lJSUJNZ0REWUNCQ0FUSUFzMkFnQWdDRUVCYWlFSUlBY2dDbW9oQnlBTElCbHFJQXhxSVJrTUFnc0FDd3NnQ0NBUFNBMERJQWdnSDJzaEJnTkFBa0FnQmlBUFRnUkFRUUFoQXdOQUlBTkJBMFlOQWlBRklBTkJBblFpQW1wQnJOQUJhaUFDSUFScUtBSmtOZ0lBSUFOQkFXb2hBd3dBQ3dBTEFrQUNRQUpBSUFRb0F0d0JJZ01nQkVId0FHb2dCa0VIY1VFTWJHb2lDQ2dDQUNJTWFpSVFJQmRMRFFBZ0J5QUlLQUlFSWdzZ0RHb2lDbW9nSVVzTkFDQUtRU0JxSUJZZ0IydE5EUUVMSUFRZ0NDZ0NDRFlDS0NBRUlBZ3BBZ0EzQXlBZ0J5QVdJQVJCSUdvZ0JFSGNBV29nRnlBU0lCZ2dHaEFmSVFvTUFRc2dCeUFNYWlFQ0lBZ29BZ2doQ0NBSElBTXBBQUEzQUFBZ0J5QURLUUFJTndBSUFrQWdERUVSU1EwQUlBY2dBeWtBRURjQUVDQUhJQU1wQUJnM0FCZ2dERUVRYTBFUlNBMEFJQU5CRUdvaEF5QUhRU0JxSVF3RFFDQU1JQU1wQUJBM0FBQWdEQ0FES1FBWU53QUlJQXdnQXlrQUlEY0FFQ0FNSUFNcEFDZzNBQmdnQTBFZ2FpRURJQXhCSUdvaURDQUNTUTBBQ3dzZ0FpQUlheUVESUFRZ0VEWUMzQUVnQWlBU2F5QUlTUVJBSUFnZ0FpQVlhMHNOQnlBYUlCb2dBeUFTYXlJRGFpSU1JQXRxVHdSQUlBSWdEQ0FMRUFvYURBSUxJQU1nQzJvaEN5QUNJQXhCQUNBRGF4QUtJQU5ySVFJZ0VpRURDeUFJUVJCUEJFQWdBaUFES1FBQU53QUFJQUlnQXlrQUNEY0FDQ0FMUVJGSURRRWdBaUFMYWlFSUlBSkJFR29oQWdOQUlBSWdBeWtBRURjQUFDQUNJQU1wQUJnM0FBZ2dBaUFES1FBZ053QVFJQUlnQXlrQUtEY0FHQ0FEUVNCcUlRTWdBa0VnYWlJQ0lBaEpEUUFMREFFTEFrQWdDRUVIVFFSQUlBSWdBeTBBQURvQUFDQUNJQU10QUFFNkFBRWdBaUFETFFBQ09nQUNJQUlnQXkwQUF6b0FBeUFDSUFNZ0NFRUNkQ0lJUWNBZWFpZ0NBR29pQXlnQUFEWUFCQ0FESUFoQjRCNXFLQUlBYXlFRERBRUxJQUlnQXlrQUFEY0FBQXNnQzBFSlNRMEFJQUlnQzJvaERDQUNRUWhxSWdnZ0EwRUlhaUlEYTBFUFRBUkFBMEFnQ0NBREtRQUFOd0FBSUFOQkNHb2hBeUFJUVFocUlnZ2dERWtOQUF3Q0N3QUxJQWdnQXlrQUFEY0FBQ0FJSUFNcEFBZzNBQWdnQzBFWlNBMEFJQUpCR0dvaEFnTkFJQUlnQXlrQUVEY0FBQ0FDSUFNcEFCZzNBQWdnQWlBREtRQWdOd0FRSUFJZ0F5a0FLRGNBR0NBRFFTQnFJUU1nQWtFZ2FpSUNJQXhKRFFBTEN5QUtRWWgvU3dSQUlBb2hDUXdHQlNBR1FRRnFJUVlnQnlBS2FpRUhEQUlMQUFzTElBUW9BdHdCSVFNTFFicC9JUWtnRnlBRGF5SUNJQllnQjJ0TERRSWdCd1IvSUFjZ0F5QUNFQUlnQW1vRlFRQUxJQTVySVFrTUFnc2dCVUVBTmdLYzZ3RUxJQVFnQlNnQzhPb0JJZ00yQXR3QklBa2dEbW9oRENBRElBVW9Bb0RyQVdvaEVBSkFJQTlGQkVBZ0RpRUdEQUVMSUFVb0FyanBBU0VOSUFVb0FyVHBBU0VUSUFVb0FyRHBBU0VTSUFWQkFUWUNoT29CUVFBaEF3TkFJQU5CQTBjRVFDQUVJQU5CQW5RaUFtb2dBaUFGYWtHczBBRnFLQUlBTmdLY0FTQURRUUZxSVFNTUFRc0xRV3doQ1NBRVFmQUFhaUlDSUFjZ0JoQU5RWWgvU3cwQklERWdBaUFGS0FJQUVCNGdNQ0FDSUFVb0FnZ1FIaUF2SUFJZ0JTZ0NCQkFlSUF4QklHc2hHQ0FPSVFZRFFDQUVLQUtJQVNBRUtBS0VBVUVEZEdvcEFnQWlRS2NpQ2tFUWRpSVpRZjhCY1NFTElBUW9BcGdCSUFRb0FwUUJRUU4wYWlrQ0FDSkJweUlXUVJCMkloOUIvd0Z4SVJvZ0JDZ0NrQUVnQkNnQ2pBRkJBM1JxS1FJQUlrSkNJSWluSVFjZ1FVSWdpQ0JBUWlDSXB5RURBa0FnUWtJUWlLY2lDRUgvQVhFaUFrRUNUd1JBQWtBZ0FrRVpTU0EvUW9HQWdCQlVja1VFUUNBRVFTQWdCQ2dDZENJSWF5SVJJQUlnQWlBUlN4c2lGeUFJYWpZQ2RDQUhJQVFvQW5BZ0NIUkJBQ0FYYTNZZ0FpQVhheUlYZEdvaENDQUVRZkFBYWhBUEdpQUNJQkZORFFFZ0JDQUVLQUowSWdJZ0YybzJBblFnQkNnQ2NDQUNkRUVBSUJkcmRpQUlhaUVJREFFTElBUWdBaUFFS0FKMEloRnFOZ0owSUFRb0FuQWdFWFJCQUNBSWEzWWdCMm9oQ0NBRVFmQUFhaEFQR2dzZ0JDa0NuQUVoUkNBRUlBZzJBcHdCSUFRZ1JEY0NvQUVNQVFzQ1FDQUNSUVJBSUFNRVFDQUVLQUtjQVNFSURBTUxJQVFvQXFBQklRZ01BUXNnQkNBRUtBSjBJZ0pCQVdvMkFuUUNmeUFISUFORmFpQUVLQUp3SUFKMFFSOTJhaUlDUVFOR0JFQWdCQ2dDbkFGQkFXc01BUXNnQWtFQ2RDQUVhaWdDbkFFTElnZEZJQWRxSVFnZ0FrRUJSd1JBSUFRZ0JDZ0NvQUUyQXFRQkN3c2dCQ0FFS0FLY0FUWUNvQUVnQkNBSU5nS2NBUXVuSVFJZ1FVS0FnUHdIZzFCRkJFQWdCQ0FFS0FKMElnY2dHbW8yQW5RZ0JDZ0NjQ0FIZEVFQUlCOXJkaUFDYWlFQ0N5QUxJQnBxUVJSUEJFQWdCRUh3QUdvUUR4b0xJRUJDZ0lEOEI0TlFSUVJBSUFRZ0JDZ0NkQ0lISUF0cU5nSjBJQVFvQW5BZ0IzUkJBQ0FaYTNZZ0Eyb2hBd3NnQkVId0FHb1FEeG9nQkNBRUtBSndJZ2RCQUNBS1FSaDJJZ3NnQkNnQ2RHb2lHbXQySUF0QkFuUkJvQjFxS0FJQWNTQUtRZi8vQTNGcU5nS0VBU0FFSUJvZ0ZrRVlkaUlLYWlJTE5nSjBJQVFnQ2tFQ2RFR2dIV29vQWdBZ0IwRUFJQXRyZG5FZ0ZrSC8vd054YWpZQ2xBRWdCRUh3QUdvUUR4b2dCQ0JDcHlJSFFSaDJJZ29nQkNnQ2RHb2lDellDZENBRUlBcEJBblJCb0IxcUtBSUFJQVFvQW5CQkFDQUxhM1p4SUFkQi8vOERjV28yQW93QklBUWdBellDT0NBRUlBSTJBandnQkNBSU5nSkFBa0FDUUFKQUlBUW9BdHdCSWdzZ0Eyb2lGaUFRU3cwQUlBWWdBaUFEYWlJS2FpQVlTdzBBSUFwQklHb2dEQ0FHYTAwTkFRc2dCQ0FFUVVCcktBSUFOZ0lJSUFRZ0JDa0RPRGNEQUNBR0lBd2dCQ0FFUWR3QmFpQVFJQklnRXlBTkVCOGhDZ3dCQ3lBRElBWnFJUWNnQmlBTEtRQUFOd0FBSUFZZ0N5a0FDRGNBQ0FKQUlBTkJFVWtOQUNBR0lBc3BBQkEzQUJBZ0JpQUxLUUFZTndBWUlBTkJFR3RCRVVnTkFDQUxRUkJxSVFNZ0JrRWdhaUVMQTBBZ0N5QURLUUFRTndBQUlBc2dBeWtBR0RjQUNDQUxJQU1wQUNBM0FCQWdDeUFES1FBb053QVlJQU5CSUdvaEF5QUxRU0JxSWdzZ0Iwa05BQXNMSUFjZ0NHc2hBeUFFSUJZMkF0d0JJQWNnRW1zZ0NFa0VRQ0FJSUFjZ0UydExEUVFnRFNBTklBTWdFbXNpQTJvaUN5QUNhazhFUUNBSElBc2dBaEFLR2d3Q0N5QUhJQXRCQUNBRGF4QUtJQVFnQWlBRGFpSUNOZ0k4SUFOcklRY2dFaUVEQ3lBSVFSQlBCRUFnQnlBREtRQUFOd0FBSUFjZ0F5a0FDRGNBQ0NBQ1FSRklEUUVnQWlBSGFpRUlJQWRCRUdvaEFnTkFJQUlnQXlrQUVEY0FBQ0FDSUFNcEFCZzNBQWdnQWlBREtRQWdOd0FRSUFJZ0F5a0FLRGNBR0NBRFFTQnFJUU1nQWtFZ2FpSUNJQWhKRFFBTERBRUxBa0FnQ0VFSFRRUkFJQWNnQXkwQUFEb0FBQ0FISUFNdEFBRTZBQUVnQnlBRExRQUNPZ0FDSUFjZ0F5MEFBem9BQXlBSElBTWdDRUVDZENJSVFjQWVhaWdDQUdvaUF5Z0FBRFlBQkNBRElBaEI0QjVxS0FJQWF5RUREQUVMSUFjZ0F5a0FBRGNBQUFzZ0FrRUpTUTBBSUFJZ0Iyb2hDeUFIUVFocUlnZ2dBMEVJYWlJRGEwRVBUQVJBQTBBZ0NDQURLUUFBTndBQUlBTkJDR29oQXlBSVFRaHFJZ2dnQzBrTkFBd0NDd0FMSUFnZ0F5a0FBRGNBQUNBSUlBTXBBQWczQUFnZ0FrRVpTQTBBSUFkQkdHb2hBZ05BSUFJZ0F5a0FFRGNBQUNBQ0lBTXBBQmczQUFnZ0FpQURLUUFnTndBUUlBSWdBeWtBS0RjQUdDQURRU0JxSVFNZ0FrRWdhaUlDSUF0SkRRQUxDeUFLUVloL1N3UkFJQW9oQ1F3REN5QUdJQXBxSVFZZ0JFSHdBR29RRHlFRElBOUJBV3NpRHcwQUMwRUFJUUlnQTBFQ1NRMEJBMEFnQWtFRFJ3UkFJQVVnQWtFQ2RDSURha0dzMEFGcUlBTWdCR29vQXB3Qk5nSUFJQUpCQVdvaEFnd0JDd3NnQkNnQzNBRWhBd3RCdW44aENTQVFJQU5ySWdJZ0RDQUdhMHNOQUNBR0JIOGdCaUFESUFJUUFpQUNhZ1ZCQUFzZ0Rtc2hDUXNnQ1VHSWYwc05CZ3NDUUNBRktBTHM2Z0ZGRFFBZ0JTQUZLUU9JNmdFZ0NhMThOd09JNmdFQ1FDQUZLQUxRNmdFaUFpQUphaUlJUVI5TkJFQWdEa1VOQVNBQ0lDSnFJQTRnQ1JBQ0dpQUZLQUxRNmdFZ0NXb2hDQXdCQ3lBT0lRTWdBZ1JBSUFJZ0ltb2dBMEVnSUFKckVBSWFJQVVvQXREcUFTRUNJQVZCQURZQzBPb0JJQVVnQlNrRGtPb0JJQVVwQUxEcUFVTFAxdE8rMHNlcjJVSitmRUlmaVVLSGxhK3ZtTGJlbTU1L2ZqY0RrT29CSUFVZ0JTa0RtT29CSUFVcEFManFBVUxQMXRPKzBzZXIyVUorZkVJZmlVS0hsYSt2bUxiZW01NS9mamNEbU9vQklBVWdCU2tEb09vQklBVXBBTURxQVVMUDF0Tyswc2VyMlVKK2ZFSWZpVUtIbGErdm1MYmVtNTUvZmpjRG9Pb0JJQVVnQlNrRHFPb0JJQVVwQU1qcUFVTFAxdE8rMHNlcjJVSitmRUlmaVVLSGxhK3ZtTGJlbTU1L2ZqY0RxT29CSUFNZ0FtdEJJR29oQXdzZ0NTQU9haUlDSUFOQklHcFBCRUFnQWtFZ2F5RUdJQVVwQTZqcUFTRS9JQVVwQTZEcUFTRkFJQVVwQTVqcUFTRkJJQVVwQTVEcUFTRkNBMEFnQXlrQUdFTFAxdE8rMHNlcjJVSitJRDk4UWgrSlFvZVZyNitZdHQ2Ym5uOStJVDhnQXlrQUVFTFAxdE8rMHNlcjJVSitJRUI4UWgrSlFvZVZyNitZdHQ2Ym5uOStJVUFnQXlrQUNFTFAxdE8rMHNlcjJVSitJRUY4UWgrSlFvZVZyNitZdHQ2Ym5uOStJVUVnQXlrQUFFTFAxdE8rMHNlcjJVSitJRUo4UWgrSlFvZVZyNitZdHQ2Ym5uOStJVUlnQTBFZ2FpSURJQVpORFFBTElBVWdQemNEcU9vQklBVWdRRGNEb09vQklBVWdRVGNEbU9vQklBVWdRamNEa09vQkN5QUNJQU5ORFFFZ0lpQURJQUlnQTJzaUNCQUNHZ3NnQlNBSU5nTFE2Z0VMSURVZ0ZXc2hBeUFWSUJ0cUlRSWdDU0FPYWlFT0lBUW9BakJGRFFBTElDa3BBd0FpUDBKL1VTQS9JQTRnSFd1c1VYSkZCRUJCYkNFSkRBWUxJQVVvQXVEcEFRUkFRV29oQ1NBRFFRUkpEUVlnQlNnQzZPb0JSUVJBSUNJZ0JTZ0MwT29CYWlFS0FuNGdCU2tEaU9vQklqOUNJRm9FUUNBRktRT1k2Z0VpUUVJSGlTQUZLUU9RNmdFaVFVSUJpWHdnQlNrRG9Pb0JJa0pDRElsOElBVXBBNmpxQVNKRFFoS0pmQ0JCUXMvVzA3N1N4NnZaUW41Q0g0bENoNVd2cjVpMjNwdWVmMzZGUW9lVnI2K1l0dDZibm45K1FwMmp0ZXFEc1kySytnQjlJRUJDejliVHZ0TEhxOWxDZmtJZmlVS0hsYSt2bUxiZW01NS9mb1ZDaDVXdnI1aTIzcHVlZjM1Q25hTzE2b094allyNkFIMGdRa0xQMXRPKzBzZXIyVUorUWgrSlFvZVZyNitZdHQ2Ym5uOStoVUtIbGErdm1MYmVtNTUvZmtLZG83WHFnN0dOaXZvQWZTQkRRcy9XMDc3U3g2dlpRbjVDSDRsQ2g1V3ZyNWkyM3B1ZWYzNkZRb2VWcjYrWXR0NmJubjkrUXAyanRlcURzWTJLK2dCOURBRUxJQVVwQTZEcUFVTEZ6OW15OGVXNjZpZDhDeUEvZkNFL0lDSWhCZ05BSUFvZ0JrRUlhaUlIVHdSQUlBWXBBQUJDejliVHZ0TEhxOWxDZmtJZmlVS0hsYSt2bUxiZW01NS9maUEvaFVJYmlVS0hsYSt2bUxiZW01NS9ma0tkbzdYcWc3R05pdm9BZlNFL0lBY2hCZ3dCQ3dzQ1FDQUtJQVpCQkdvaUNFa0VRQ0FHSVFnTUFRc2dCalVBQUVLSGxhK3ZtTGJlbTU1L2ZpQS9oVUlYaVVMUDF0Tyswc2VyMlVKK1F2bnozZkdaOXBtckZud2hQd3NEUUNBSUlBcEpCRUFnQ0RFQUFFTEZ6OW15OGVXNjZpZCtJRCtGUWd1SlFvZVZyNitZdHQ2Ym5uOStJVDhnQ0VFQmFpRUlEQUVMQ3lBQ0tBQUFJRDlDSVlnZ1A0VkN6OWJUdnRMSHE5bENmaUkvUWgySUlEK0ZRdm56M2ZHWjlwbXJGbjRpUDBJZ2lDQS9oYWRIRFFjTElBTkJCR3NoQXlBQ1FRUnFJUUlMSUE0Z0hXc2lDVUdKZjA4TkJDQUJJQWxySVFFZ0NTQWRhaUVkUVFFaFBnd0JDd3RCdUg4aEJ5QUREUVFnSFNBQWF5RUhEQVFMUVd3aENRd0JDMEc0ZnlFSkMwRzRmeUVISUFsQmRrWWdQbkVOQVFzZ0NTRUhDeWdDQUEwQUlBVkIvT29CYWlnQ0FDRUJJQVZCK09vQmFpZ0NBQ0VBSUFVUUdDQUZLQUt3NndFZ0FDQUJFQk1nQlVFQU5nS3c2d0VnQlNnQ3BPc0JJZ0lFUUFKQUFrQUNRQUpBSUFJb0FnQWlBd1JBSUFCRkRRSWdBU0FESUFBUkFnQU1BUXNnQUVVTkFnc2dBU0FDSUFBUkFnQU1BZ3NnQXhBR0N5QUNFQVlMSUFWQkFEWUNwT3NCQ3lBQUJFQWdBU0FGSUFBUkFnQU1BUXNnQlJBR0N5QUVRZUFCYWlRQUlBY0xDNmdWQ1FCQmlBZ0xEUUVBQUFBQkFBQUFBZ0FBQUFJQVFhQUlDN01HQVFBQUFBRUFBQUFDQUFBQUFnQUFBQ1lBQUFDQ0FBQUFJUVVBQUVvQUFBQm5DQUFBSmdBQUFNQUJBQUNBQUFBQVNRVUFBRW9BQUFDK0NBQUFLUUFBQUN3Q0FBQ0FBQUFBU1FVQUFFb0FBQUMrQ0FBQUx3QUFBTW9DQUFDQUFBQUFpZ1VBQUVvQUFBQ0VDUUFBTlFBQUFITURBQUNBQUFBQW5RVUFBRW9BQUFDZ0NRQUFQUUFBQUlFREFBQ0FBQUFBNndVQUFFc0FBQUErQ2dBQVJBQUFBSjREQUFDQUFBQUFUUVlBQUVzQUFBQ3FDZ0FBU3dBQUFMTURBQUNBQUFBQXdRWUFBRTBBQUFBZkRRQUFUUUFBQUZNRUFBQ0FBQUFBSXdnQUFGRUFBQUNtRHdBQVZBQUFBSmtFQUFDQUFBQUFTd2tBQUZjQUFBQ3hFZ0FBV0FBQUFOb0VBQUNBQUFBQWJ3a0FBRjBBQUFBakZBQUFWQUFBQUVVRkFBQ0FBQUFBVkFvQUFHb0FBQUNNRkFBQWFnQUFBSzhGQUFDQUFBQUFkZ2tBQUh3QUFBQk9FQUFBZkFBQUFOSUNBQUNBQUFBQVl3Y0FBSkVBQUFDUUJ3QUFrZ0FBQUFBQUFBQUJBQUFBQVFBQUFBVUFBQUFOQUFBQUhRQUFBRDBBQUFCOUFBQUEvUUFBQVAwQkFBRDlBd0FBL1FjQUFQMFBBQUQ5SHdBQS9UOEFBUDEvQUFEOS93QUEvZjhCQVAzL0F3RDkvd2NBL2Y4UEFQMy9Id0Q5L3o4QS9mOS9BUDMvL3dEOS8vOEIvZi8vQS8zLy93ZjkvLzhQL2YvL0gvMy8vei85Ly85L0FBQUFBQUVBQUFBQ0FBQUFBd0FBQUFRQUFBQUZBQUFBQmdBQUFBY0FBQUFJQUFBQUNRQUFBQW9BQUFBTEFBQUFEQUFBQUEwQUFBQU9BQUFBRHdBQUFCQUFBQUFSQUFBQUVnQUFBQk1BQUFBVUFBQUFGUUFBQUJZQUFBQVhBQUFBR0FBQUFCa0FBQUFhQUFBQUd3QUFBQndBQUFBZEFBQUFIZ0FBQUI4QUFBQURBQUFBQkFBQUFBVUFBQUFHQUFBQUJ3QUFBQWdBQUFBSkFBQUFDZ0FBQUFzQUFBQU1BQUFBRFFBQUFBNEFBQUFQQUFBQUVBQUFBQkVBQUFBU0FBQUFFd0FBQUJRQUFBQVZBQUFBRmdBQUFCY0FBQUFZQUFBQUdRQUFBQm9BQUFBYkFBQUFIQUFBQUIwQUFBQWVBQUFBSHdBQUFDQUFBQUFoQUFBQUlnQUFBQ01BQUFBbEFBQUFKd0FBQUNrQUFBQXJBQUFBTHdBQUFETUFBQUE3QUFBQVF3QUFBRk1BQUFCakFBQUFnd0FBQUFNQkFBQURBZ0FBQXdRQUFBTUlBQUFERUFBQUF5QUFBQU5BQUFBRGdBQUFBd0FCQUVIZ0R3dFJBUUFBQUFFQUFBQUJBQUFBQVFBQUFBSUFBQUFDQUFBQUF3QUFBQU1BQUFBRUFBQUFCQUFBQUFVQUFBQUhBQUFBQ0FBQUFBa0FBQUFLQUFBQUN3QUFBQXdBQUFBTkFBQUFEZ0FBQUE4QUFBQVFBRUhFRUF1TEFRRUFBQUFDQUFBQUF3QUFBQVFBQUFBRkFBQUFCZ0FBQUFjQUFBQUlBQUFBQ1FBQUFBb0FBQUFMQUFBQURBQUFBQTBBQUFBT0FBQUFEd0FBQUJBQUFBQVNBQUFBRkFBQUFCWUFBQUFZQUFBQUhBQUFBQ0FBQUFBb0FBQUFNQUFBQUVBQUFBQ0FBQUFBQUFFQUFBQUNBQUFBQkFBQUFBZ0FBQUFRQUFBQUlBQUFBRUFBQUFDQUFBQUFBQUVBUVpBU0MrWUVBUUFBQUFFQUFBQUJBQUFBQVFBQUFBSUFBQUFDQUFBQUF3QUFBQU1BQUFBRUFBQUFCZ0FBQUFjQUFBQUlBQUFBQ1FBQUFBb0FBQUFMQUFBQURBQUFBQTBBQUFBT0FBQUFEd0FBQUJBQUFBQUJBQUFBQkFBQUFBZ0FBQUFBQUFBQUFRQUJBUVlBQUFBQUFBQUVBQUFBQUJBQUFBUUFBQUFBSUFBQUJRRUFBQUFBQUFBRkF3QUFBQUFBQUFVRUFBQUFBQUFBQlFZQUFBQUFBQUFGQndBQUFBQUFBQVVKQUFBQUFBQUFCUW9BQUFBQUFBQUZEQUFBQUFBQUFBWU9BQUFBQUFBQkJSQUFBQUFBQUFFRkZBQUFBQUFBQVFVV0FBQUFBQUFDQlJ3QUFBQUFBQU1GSUFBQUFBQUFCQVV3QUFBQUlBQUdCVUFBQUFBQUFBY0ZnQUFBQUFBQUNBWUFBUUFBQUFBS0JnQUVBQUFBQUF3R0FCQUFBQ0FBQUFRQUFBQUFBQUFBQkFFQUFBQUFBQUFGQWdBQUFDQUFBQVVFQUFBQUFBQUFCUVVBQUFBZ0FBQUZCd0FBQUFBQUFBVUlBQUFBSUFBQUJRb0FBQUFBQUFBRkN3QUFBQUFBQUFZTkFBQUFJQUFCQlJBQUFBQUFBQUVGRWdBQUFDQUFBUVVXQUFBQUFBQUNCUmdBQUFBZ0FBTUZJQUFBQUFBQUF3VW9BQUFBQUFBR0JFQUFBQUFRQUFZRVFBQUFBQ0FBQndXQUFBQUFBQUFKQmdBQ0FBQUFBQXNHQUFnQUFEQUFBQVFBQUFBQUVBQUFCQUVBQUFBZ0FBQUZBZ0FBQUNBQUFBVURBQUFBSUFBQUJRVUFBQUFnQUFBRkJnQUFBQ0FBQUFVSUFBQUFJQUFBQlFrQUFBQWdBQUFGQ3dBQUFDQUFBQVVNQUFBQUFBQUFCZzhBQUFBZ0FBRUZFZ0FBQUNBQUFRVVVBQUFBSUFBQ0JSZ0FBQUFnQUFJRkhBQUFBQ0FBQXdVb0FBQUFJQUFFQlRBQUFBQUFBQkFHQUFBQkFBQUFEd1lBZ0FBQUFBQU9CZ0JBQUFBQUFBMEdBQ0FBUVlBWEM0Y0NBUUFCQVFVQUFBQUFBQUFGQUFBQUFBQUFCZ1E5QUFBQUFBQUpCZjBCQUFBQUFBOEYvWDhBQUFBQUZRWDkveDhBQUFBREJRVUFBQUFBQUFjRWZRQUFBQUFBREFYOUR3QUFBQUFTQmYzL0F3QUFBQmNGL2Y5L0FBQUFCUVVkQUFBQUFBQUlCUDBBQUFBQUFBNEYvVDhBQUFBQUZBWDkvdzhBQUFBQ0JRRUFBQUFRQUFjRWZRQUFBQUFBQ3dYOUJ3QUFBQUFSQmYzL0FRQUFBQllGL2Y4L0FBQUFCQVVOQUFBQUVBQUlCUDBBQUFBQUFBMEYvUjhBQUFBQUV3WDkvd2NBQUFBQkJRRUFBQUFRQUFZRVBRQUFBQUFBQ2dYOUF3QUFBQUFRQmYzL0FBQUFBQndGL2YvL0R3QUFHd1g5Ly84SEFBQWFCZjMvL3dNQUFCa0YvZi8vQVFBQUdBWDkvLzhBUVpBWkM0WUVBUUFCQVFZQUFBQUFBQUFHQXdBQUFBQUFBQVFFQUFBQUlBQUFCUVVBQUFBQUFBQUZCZ0FBQUFBQUFBVUlBQUFBQUFBQUJRa0FBQUFBQUFBRkN3QUFBQUFBQUFZTkFBQUFBQUFBQmhBQUFBQUFBQUFHRXdBQUFBQUFBQVlXQUFBQUFBQUFCaGtBQUFBQUFBQUdIQUFBQUFBQUFBWWZBQUFBQUFBQUJpSUFBQUFBQUFFR0pRQUFBQUFBQVFZcEFBQUFBQUFDQmk4QUFBQUFBQU1HT3dBQUFBQUFCQVpUQUFBQUFBQUhCb01BQUFBQUFBa0dBd0lBQUJBQUFBUUVBQUFBQUFBQUJBVUFBQUFnQUFBRkJnQUFBQUFBQUFVSEFBQUFJQUFBQlFrQUFBQUFBQUFGQ2dBQUFBQUFBQVlNQUFBQUFBQUFCZzhBQUFBQUFBQUdFZ0FBQUFBQUFBWVZBQUFBQUFBQUJoZ0FBQUFBQUFBR0d3QUFBQUFBQUFZZUFBQUFBQUFBQmlFQUFBQUFBQUVHSXdBQUFBQUFBUVluQUFBQUFBQUNCaXNBQUFBQUFBTUdNd0FBQUFBQUJBWkRBQUFBQUFBRkJtTUFBQUFBQUFnR0F3RUFBQ0FBQUFRRUFBQUFNQUFBQkFRQUFBQVFBQUFFQlFBQUFDQUFBQVVIQUFBQUlBQUFCUWdBQUFBZ0FBQUZDZ0FBQUNBQUFBVUxBQUFBQUFBQUJnNEFBQUFBQUFBR0VRQUFBQUFBQUFZVUFBQUFBQUFBQmhjQUFBQUFBQUFHR2dBQUFBQUFBQVlkQUFBQUFBQUFCaUFBQUFBQUFCQUdBd0FCQUFBQUR3WURnQUFBQUFBT0JnTkFBQUFBQUEwR0F5QUFBQUFBREFZREVBQUFBQUFMQmdNSUFBQUFBQW9HQXdRQVFhUWRDOWtCQVFBQUFBTUFBQUFIQUFBQUR3QUFBQjhBQUFBL0FBQUFmd0FBQVA4QUFBRC9BUUFBL3dNQUFQOEhBQUQvRHdBQS94OEFBUDgvQUFEL2Z3QUEvLzhBQVAvL0FRRC8vd01BLy84SEFQLy9Ed0QvL3g4QS8vOC9BUC8vZndELy8vOEEvLy8vQWYvLy93UC8vLzhILy8vL0QvLy8veC8vLy84Ly8vLy9md0FBQUFBQkFBQUFBZ0FBQUFRQUFBQUFBQUFBQWdBQUFBUUFBQUFJQUFBQUFBQUFBQUVBQUFBQ0FBQUFBUUFBQUFRQUFBQUVBQUFBQkFBQUFBUUFBQUFJQUFBQUNBQUFBQWdBQUFBSEFBQUFDQUFBQUFrQUFBQUtBQUFBQ3dCQmdCOExBNEFSQVE9PSI7dmFyIEl0PW5ldyBSQSxydD0hMTthc3luYyBmdW5jdGlvbiB5SShBLGUpe2xldCB0PW51bGw7dHlwZW9mIEEhPSJzdHJpbmciP3Q9QS5ocmVmOkEuc3RhcnRzV2l0aCgiaHR0cCIpP3Q9QTp0PWAke2V9LyR7QX1gLHQuZW5kc1dpdGgoIi5qcyIpJiYodD10LnN1YnN0cmluZygwLHQubGVuZ3RoLTMpKSx0LmVuZHNXaXRoKCIud2FzbSIpJiYodD10LnN1YnN0cmluZygwLHQubGVuZ3RoLTUpKTtsZXQgST1gJHt0fS53YXNtYCxyPWF3YWl0IE5BLmdldChgJHtJfS56c3RgLHtyZXNwb25zZVR5cGU6ImFycmF5YnVmZmVyIn0pO3J0fHwoYXdhaXQgSXQuaW5pdCgpLHJ0PSEwKTtsZXQgZz1JdC5kZWNvZGUobmV3IFVpbnQ4QXJyYXkoci5kYXRhKSkuYnVmZmVyO3JldHVybihhd2FpdCBpbXBvcnQoYCR7dH0uanNgKSkuZGVmYXVsdCh7d2FzbUJpbmFyeTpnfSl9dmFyIGl0PXlJO3ZhciBHQT1uZXcgTWFwO2FzeW5jIGZ1bmN0aW9uIHdJKEEsZSl7bGV0IHQ9QSxJPUEscj1udWxsO3JldHVybiB0eXBlb2YgQSE9InN0cmluZyImJih0PW5ldyBVUkwoQS5ocmVmKSxJPXQuaHJlZiksR0EuaGFzKEkpfHxHQS5zZXQoSSxhd2FpdCBpdCh0LGUpKSxyPUdBLmdldChJKSxyfXZhciBVPXdJO3ZhciBwST1uZXcgTWFwKFtbImltYWdlL2pwZWciLCJKUEVHSW1hZ2VJTyJdLFsiaW1hZ2UvcG5nIiwiUE5HSW1hZ2VJTyJdLFsiaW1hZ2UvdGlmZiIsIlRJRkZJbWFnZUlPIl0sWyJpbWFnZS94LW1zLWJtcCIsIkJNUEltYWdlSU8iXSxbImltYWdlL3gtYm1wIiwiQk1QSW1hZ2VJTyJdLFsiaW1hZ2UvYm1wIiwiQk1QSW1hZ2VJTyJdLFsiYXBwbGljYXRpb24vZGljb20iLCJHRENNSW1hZ2VJTyJdXSksZ2U9cEk7dmFyIEZJPW5ldyBNYXAoW1siYm1wIiwiQk1QSW1hZ2VJTyJdLFsiQk1QIiwiQk1QSW1hZ2VJTyJdLFsiZGNtIiwiR0RDTUltYWdlSU8iXSxbIkRDTSIsIkdEQ01JbWFnZUlPIl0sWyJnaXBsIiwiR2lwbEltYWdlSU8iXSxbImdpcGwuZ3oiLCJHaXBsSW1hZ2VJTyJdLFsiaGRmNSIsIkhERjVJbWFnZUlPIl0sWyJqcGciLCJKUEVHSW1hZ2VJTyJdLFsiSlBHIiwiSlBFR0ltYWdlSU8iXSxbImpwZWciLCJKUEVHSW1hZ2VJTyJdLFsiSlBFRyIsIkpQRUdJbWFnZUlPIl0sWyJpd2kiLCJXYXNtSW1hZ2VJTyJdLFsiaXdpLmNib3IiLCJXYXNtSW1hZ2VJTyJdLFsiaXdpLmNib3IuenN0IiwiV2FzbVpzdGRJbWFnZUlPIl0sWyJsc20iLCJMU01JbWFnZUlPIl0sWyJtbmMiLCJNSU5DSW1hZ2VJTyJdLFsiTU5DIiwiTUlOQ0ltYWdlSU8iXSxbIm1uYy5neiIsIk1JTkNJbWFnZUlPIl0sWyJNTkMuR1oiLCJNSU5DSW1hZ2VJTyJdLFsibW5jMiIsIk1JTkNJbWFnZUlPIl0sWyJNTkMyIiwiTUlOQ0ltYWdlSU8iXSxbIm1naCIsIk1HSEltYWdlSU8iXSxbIm1neiIsIk1HSEltYWdlSU8iXSxbIm1naC5neiIsIk1HSEltYWdlSU8iXSxbIm1oYSIsIk1ldGFJbWFnZUlPIl0sWyJtaGQiLCJNZXRhSW1hZ2VJTyJdLFsibXJjIiwiTVJDSW1hZ2VJTyJdLFsibmlhIiwiTmlmdGlJbWFnZUlPIl0sWyJuaWkiLCJOaWZ0aUltYWdlSU8iXSxbIm5paS5neiIsIk5pZnRpSW1hZ2VJTyJdLFsiaGRyIiwiTmlmdGlJbWFnZUlPIl0sWyJucnJkIiwiTnJyZEltYWdlSU8iXSxbIk5SUkQiLCJOcnJkSW1hZ2VJTyJdLFsibmhkciIsIk5ycmRJbWFnZUlPIl0sWyJOSERSIiwiTnJyZEltYWdlSU8iXSxbInBuZyIsIlBOR0ltYWdlSU8iXSxbIlBORyIsIlBOR0ltYWdlSU8iXSxbInBpYyIsIkJpb1JhZEltYWdlSU8iXSxbIlBJQyIsIkJpb1JhZEltYWdlSU8iXSxbInRpZiIsIlRJRkZJbWFnZUlPIl0sWyJUSUYiLCJUSUZGSW1hZ2VJTyJdLFsidGlmZiIsIlRJRkZJbWFnZUlPIl0sWyJUSUZGIiwiVElGRkltYWdlSU8iXSxbInZ0ayIsIlZUS0ltYWdlSU8iXSxbIlZUSyIsIlZUS0ltYWdlSU8iXSxbImlzcSIsIlNjYW5jb0ltYWdlSU8iXSxbIklTUSIsIlNjYW5jb0ltYWdlSU8iXSxbImZkZiIsIkZERkltYWdlSU8iXSxbIkZERiIsIkZERkltYWdlSU8iXV0pLG9lPUZJO2Z1bmN0aW9uIFNJKEEpe2xldCBlPUEuc2xpY2UoKEEubGFzdEluZGV4T2YoIi4iKS0xPj4+MCkrMik7aWYoZS50b0xvd2VyQ2FzZSgpPT09Imd6Iil7bGV0IHQ9QS5zbGljZSgwLC0zKS5sYXN0SW5kZXhPZigiLiIpO2U9QS5zbGljZSgodC0xPj4+MCkrMil9ZWxzZSBpZihlLnRvTG93ZXJDYXNlKCk9PT0iY2JvciIpe2xldCB0PUEuc2xpY2UoMCwtNSkubGFzdEluZGV4T2YoIi4iKTtlPUEuc2xpY2UoKHQtMT4+PjApKzIpfWVsc2UgaWYoZS50b0xvd2VyQ2FzZSgpPT09InpzdCIpe2xldCB0PUEuc2xpY2UoMCwtMTApLmxhc3RJbmRleE9mKCIuIik7ZT1BLnNsaWNlKCh0LTE+Pj4wKSsyKX1lbHNlIGlmKGUudG9Mb3dlckNhc2UoKT09PSJ6aXAiKXtsZXQgdD1BLnNsaWNlKDAsLTQpLmxhc3RJbmRleE9mKCIuIik7ZT1BLnNsaWNlKCh0LTE+Pj4wKSsyKX1yZXR1cm4gZX12YXIgVUE9U0k7dmFyIE5JPVsiUE5HSW1hZ2VJTyIsIk1ldGFJbWFnZUlPIiwiVElGRkltYWdlSU8iLCJOaWZ0aUltYWdlSU8iLCJKUEVHSW1hZ2VJTyIsIk5ycmRJbWFnZUlPIiwiVlRLSW1hZ2VJTyIsIkJNUEltYWdlSU8iLCJIREY1SW1hZ2VJTyIsIk1JTkNJbWFnZUlPIiwiTVJDSW1hZ2VJTyIsIkxTTUltYWdlSU8iLCJNR0hJbWFnZUlPIiwiQmlvUmFkSW1hZ2VJTyIsIkdpcGxJbWFnZUlPIiwiR0VBZHdJbWFnZUlPIiwiR0U0SW1hZ2VJTyIsIkdFNUltYWdlSU8iLCJHRENNSW1hZ2VJTyIsIlNjYW5jb0ltYWdlSU8iLCJGREZJbWFnZUlPIiwiV2FzbUltYWdlSU8iLCJXYXNtWnN0ZEltYWdlSU8iXSxrQT1OSTt2YXIgUkk9e1RleHRGaWxlOiJJbnRlcmZhY2VUZXh0RmlsZSIsQmluYXJ5RmlsZToiSW50ZXJmYWNlQmluYXJ5RmlsZSIsVGV4dFN0cmVhbToiSW50ZXJmYWNlVGV4dFN0cmVhbSIsQmluYXJ5U3RyZWFtOiJJbnRlcmZhY2VCaW5hcnlTdHJlYW0iLEltYWdlOiJJbnRlcmZhY2VJbWFnZSIsTWVzaDoiSW50ZXJmYWNlTWVzaCIsUG9seURhdGE6IkludGVyZmFjZVBvbHlEYXRhIixKc29uQ29tcGF0aWJsZToiSW50ZXJmYWNlSnNvbkNvbXBhdGlibGUifSx1PVJJO3ZhciBHST17VGV4dDoiVGV4dCIsQmluYXJ5OiJCaW5hcnkiLEltYWdlOiJJbWFnZSIsTWVzaDoiTWVzaCJ9LFM9R0k7dmFyIFVJPXtJbnQ4OiJpbnQ4IixVSW50ODoidWludDgiLEludDE2OiJpbnQxNiIsVUludDE2OiJ1aW50MTYiLEludDMyOiJpbnQzMiIsVUludDMyOiJ1aW50MzIiLEludDY0OiJpbnQ2NCIsVUludDY0OiJ1aW50NjQiLFNpemVWYWx1ZVR5cGU6InVpbnQ2NCIsSWRlbnRpZmllclR5cGU6InVpbnQ2NCIsSW5kZXhWYWx1ZVR5cGU6ImludDY0IixPZmZzZXRWYWx1ZVR5cGU6ImludDY0In0scD1VSTt2YXIga0k9e0Zsb2F0MzI6ImZsb2F0MzIiLEZsb2F0NjQ6ImZsb2F0NjQiLFNwYWNlUHJlY2lzaW9uVHlwZToiZmxvYXQ2NCJ9LFQ9a0k7ZnVuY3Rpb24gTEkoQSxlKXtsZXQgdD1udWxsO3N3aXRjaChBKXtjYXNlIHAuVUludDg6e3Q9bmV3IFVpbnQ4QXJyYXkoZSk7YnJlYWt9Y2FzZSBwLkludDg6e3Q9bmV3IEludDhBcnJheShlKTticmVha31jYXNlIHAuVUludDE2Ont0PW5ldyBVaW50MTZBcnJheShlKTticmVha31jYXNlIHAuSW50MTY6e3Q9bmV3IEludDE2QXJyYXkoZSk7YnJlYWt9Y2FzZSBwLlVJbnQzMjp7dD1uZXcgVWludDMyQXJyYXkoZSk7YnJlYWt9Y2FzZSBwLkludDMyOnt0PW5ldyBJbnQzMkFycmF5KGUpO2JyZWFrfWNhc2UgcC5VSW50NjQ6e3R5cGVvZiBnbG9iYWxUaGlzLkJpZ1VpbnQ2NEFycmF5PT0iZnVuY3Rpb24iP3Q9bmV3IEJpZ1VpbnQ2NEFycmF5KGUpOnQ9bmV3IFVpbnQ4QXJyYXkoZSk7YnJlYWt9Y2FzZSBwLkludDY0Ont0eXBlb2YgZ2xvYmFsVGhpcy5CaWdJbnQ2NEFycmF5PT0iZnVuY3Rpb24iP3Q9bmV3IEJpZ0ludDY0QXJyYXkoZSk6dD1uZXcgVWludDhBcnJheShlKTticmVha31jYXNlIFQuRmxvYXQzMjp7dD1uZXcgRmxvYXQzMkFycmF5KGUpO2JyZWFrfWNhc2UgVC5GbG9hdDY0Ont0PW5ldyBGbG9hdDY0QXJyYXkoZSk7YnJlYWt9Y2FzZSJudWxsIjp7dD1udWxsO2JyZWFrfWNhc2UgbnVsbDp7dD1udWxsO2JyZWFrfWRlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJUeXBlIGlzIG5vdCBzdXBwb3J0ZWQgYXMgYSBUeXBlZEFycmF5Iil9cmV0dXJuIHR9dmFyIG09TEk7dmFyIG50PXR5cGVvZiBnbG9iYWxUaGlzLlNoYXJlZEFycmF5QnVmZmVyPT0iZnVuY3Rpb24iLGd0PW5ldyBUZXh0RW5jb2RlcixvdD1uZXcgVGV4dERlY29kZXIoInV0Zi04Iik7ZnVuY3Rpb24gSChBLGUpe2xldCB0PXtmbGFnczoiciIsZW5jb2Rpbmc6ImJpbmFyeSJ9LEk9QS5mc19vcGVuKGUsdC5mbGFncyksaT1BLmZzX3N0YXQoZSkuc2l6ZSxnPW51bGw7bnQ/Zz1uZXcgU2hhcmVkQXJyYXlCdWZmZXIoaSk6Zz1uZXcgQXJyYXlCdWZmZXIoaSk7bGV0IG49bmV3IFVpbnQ4QXJyYXkoZyk7cmV0dXJuIEEuZnNfcmVhZChJLG4sMCxpLDApLEEuZnNfY2xvc2UoSSksbn1mdW5jdGlvbiBhdChBLGUsdCl7bGV0IEk9bnVsbDtudD9JPW5ldyBTaGFyZWRBcnJheUJ1ZmZlcih0KTpJPW5ldyBBcnJheUJ1ZmZlcih0KTtsZXQgcj1uZXcgVWludDhBcnJheShJKSxpPW5ldyBVaW50OEFycmF5KEEuSEVBUFU4LmJ1ZmZlcixlLHQpO3JldHVybiByLnNldChpKSxyfWZ1bmN0aW9uIHkoQSxlLHQsSSl7bGV0IHI9MDtyZXR1cm4gZSE9PW51bGwmJihyPUEuY2NhbGwoIml0a193YXNtX2lucHV0X2FycmF5X2FsbG9jIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLHQsSSxlLmJ1ZmZlci5ieXRlTGVuZ3RoXSksQS5IRUFQVTguc2V0KG5ldyBVaW50OEFycmF5KGUuYnVmZmVyKSxyKSkscn1mdW5jdGlvbiBWKEEsZSx0KXtsZXQgST1KU09OLnN0cmluZ2lmeShlKSxyPUEuY2NhbGwoIml0a193YXNtX2lucHV0X2pzb25fYWxsb2MiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsdCxJLmxlbmd0aF0pO0Eud3JpdGVBc2NpaVRvTWVtb3J5KEksciwhMSl9ZnVuY3Rpb24gTihBLGUsdCxJKXtsZXQgcj1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfYWRkcmVzcyIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxlLHRdKSxpPUEuY2NhbGwoIml0a193YXNtX291dHB1dF9hcnJheV9zaXplIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLGUsdF0pLGc9YXQoQSxyLGkpO3JldHVybiBtKEksZy5idWZmZXIpfWZ1bmN0aW9uIG5lKEEsZSl7bGV0IHQ9QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2pzb25fYWRkcmVzcyIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiXSxbMCxlXSksST1BLkFzY2lpVG9TdHJpbmcodCk7cmV0dXJuIEpTT04ucGFyc2UoSSl9ZnVuY3Rpb24gT0koQSxlLHQsSSl7SSE9bnVsbCYmSS5sZW5ndGg+MCYmSS5mb3JFYWNoKGZ1bmN0aW9uKEMsbyl7dmFyIGM7c3dpdGNoKEMudHlwZSl7Y2FzZSB1LlRleHRTdHJlYW06e2xldCBhPWd0LmVuY29kZShDLmRhdGEuZGF0YSksQj15KEEsYSxvLDApLFE9e3NpemU6YS5idWZmZXIuYnl0ZUxlbmd0aCxkYXRhOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7Qn1gfTtWKEEsUSxvKTticmVha31jYXNlIHUuSnNvbkNvbXBhdGlibGU6e2xldCBhPWd0LmVuY29kZShKU09OLnN0cmluZ2lmeShDLmRhdGEpKSxCPXkoQSxhLG8sMCksUT17c2l6ZTphLmJ1ZmZlci5ieXRlTGVuZ3RoLGRhdGE6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtCfWB9O1YoQSxRLG8pO2JyZWFrfWNhc2UgdS5CaW5hcnlTdHJlYW06e2xldCBhPUMuZGF0YS5kYXRhLEI9eShBLGEsbywwKSxRPXtzaXplOmEuYnVmZmVyLmJ5dGVMZW5ndGgsZGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke0J9YH07VihBLFEsbyk7YnJlYWt9Y2FzZSB1LlRleHRGaWxlOntBLmZzX3dyaXRlRmlsZShDLmRhdGEucGF0aCxDLmRhdGEuZGF0YSk7YnJlYWt9Y2FzZSB1LkJpbmFyeUZpbGU6e0EuZnNfd3JpdGVGaWxlKEMuZGF0YS5wYXRoLEMuZGF0YS5kYXRhKTticmVha31jYXNlIHUuSW1hZ2U6e2xldCBhPUMuZGF0YSxCPXkoQSxhLmRhdGEsbywwKSxRPXkoQSxhLmRpcmVjdGlvbixvLDEpLGY9dHlwZW9mKChjPWEubWV0YWRhdGEpPT09bnVsbHx8Yz09PXZvaWQgMD92b2lkIDA6Yy5lbnRyaWVzKTwidSI/SlNPTi5zdHJpbmdpZnkoQXJyYXkuZnJvbShhLm1ldGFkYXRhLmVudHJpZXMoKSkpOiJbXSIsZD17aW1hZ2VUeXBlOmEuaW1hZ2VUeXBlLG5hbWU6YS5uYW1lLG9yaWdpbjphLm9yaWdpbixzcGFjaW5nOmEuc3BhY2luZyxkaXJlY3Rpb246YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtRfWAsc2l6ZTphLnNpemUsZGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke0J9YCxtZXRhZGF0YTpmfTtWKEEsZCxvKTticmVha31jYXNlIHUuTWVzaDp7bGV0IGE9Qy5kYXRhLEI9eShBLGEucG9pbnRzLG8sMCksUT15KEEsYS5jZWxscyxvLDEpLGY9eShBLGEucG9pbnREYXRhLG8sMiksZD15KEEsYS5jZWxsRGF0YSxvLDMpLEY9e21lc2hUeXBlOmEubWVzaFR5cGUsbmFtZTphLm5hbWUsbnVtYmVyT2ZQb2ludHM6YS5udW1iZXJPZlBvaW50cyxwb2ludHM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtCfWAsbnVtYmVyT2ZDZWxsczphLm51bWJlck9mQ2VsbHMsY2VsbHM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtRfWAsY2VsbEJ1ZmZlclNpemU6YS5jZWxsQnVmZmVyU2l6ZSxudW1iZXJPZlBvaW50UGl4ZWxzOmEubnVtYmVyT2ZQb2ludFBpeGVscyxwb2ludERhdGE6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtmfWAsbnVtYmVyT2ZDZWxsUGl4ZWxzOmEubnVtYmVyT2ZDZWxsUGl4ZWxzLGNlbGxEYXRhOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7ZH1gfTtWKEEsRixvKTticmVha31jYXNlIHUuUG9seURhdGE6e2xldCBhPUMuZGF0YSxCPXkoQSxhLnBvaW50cyxvLDApLFE9eShBLGEudmVydGljZXMsbywxKSxmPXkoQSxhLmxpbmVzLG8sMiksZD15KEEsYS5wb2x5Z29ucyxvLDMpLEY9eShBLGEudHJpYW5nbGVTdHJpcHMsbyw0KSxSPXkoQSxhLnBvaW50RGF0YSxvLDUpLEs9eShBLGEucG9pbnREYXRhLG8sNiksT0E9e3BvbHlEYXRhVHlwZTphLnBvbHlEYXRhVHlwZSxuYW1lOmEubmFtZSxudW1iZXJPZlBvaW50czphLm51bWJlck9mUG9pbnRzLHBvaW50czpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke0J9YCx2ZXJ0aWNlc0J1ZmZlclNpemU6YS52ZXJ0aWNlc0J1ZmZlclNpemUsdmVydGljZXM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtRfWAsbGluZXNCdWZmZXJTaXplOmEubGluZXNCdWZmZXJTaXplLGxpbmVzOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7Zn1gLHBvbHlnb25zQnVmZmVyU2l6ZTphLnBvbHlnb25zQnVmZmVyU2l6ZSxwb2x5Z29uczpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke2R9YCx0cmlhbmdsZVN0cmlwc0J1ZmZlclNpemU6YS50cmlhbmdsZVN0cmlwc0J1ZmZlclNpemUsdHJpYW5nbGVTdHJpcHM6YGRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5hZGRyZXNzLDA6JHtGfWAsbnVtYmVyT2ZQb2ludFBpeGVsczphLm51bWJlck9mUG9pbnRQaXhlbHMscG9pbnREYXRhOmBkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsuYWRkcmVzcywwOiR7Un1gLG51bWJlck9mQ2VsbFBpeGVsczphLm51bWJlck9mQ2VsbFBpeGVscyxjZWxsRGF0YTpgZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLmFkZHJlc3MsMDoke0t9YH07VihBLE9BLG8pO2JyZWFrfWNhc2UgUy5UZXh0OntBLmZzX3dyaXRlRmlsZShDLnBhdGgsQy5kYXRhKTticmVha31jYXNlIFMuQmluYXJ5OntBLmZzX3dyaXRlRmlsZShDLnBhdGgsQy5kYXRhKTticmVha31jYXNlIFMuSW1hZ2U6e2xldCBhPUMuZGF0YSxCPXtpbWFnZVR5cGU6YS5pbWFnZVR5cGUsbmFtZTphLm5hbWUsb3JpZ2luOmEub3JpZ2luLHNwYWNpbmc6YS5zcGFjaW5nLGRpcmVjdGlvbjoiZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLnBhdGgsZGF0YS9kaXJlY3Rpb24ucmF3IixzaXplOmEuc2l6ZSxkYXRhOiJkYXRhOmFwcGxpY2F0aW9uL3ZuZC5pdGsucGF0aCxkYXRhL2RhdGEucmF3In07aWYoQS5mc19ta2RpcnMoYCR7Qy5wYXRofS9kYXRhYCksQS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9pbmRleC5qc29uYCxKU09OLnN0cmluZ2lmeShCKSksYS5kYXRhPT09bnVsbCl0aHJvdyBFcnJvcigiaW1hZ2UuZGF0YSBpcyBudWxsIik7QS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9kYXRhL2RhdGEucmF3YCxuZXcgVWludDhBcnJheShhLmRhdGEuYnVmZmVyKSksQS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9kYXRhL2RpcmVjdGlvbi5yYXdgLG5ldyBVaW50OEFycmF5KGEuZGlyZWN0aW9uLmJ1ZmZlcikpO2JyZWFrfWNhc2UgUy5NZXNoOntsZXQgYT1DLmRhdGEsQj17bWVzaFR5cGU6YS5tZXNoVHlwZSxuYW1lOmEubmFtZSxudW1iZXJPZlBvaW50czphLm51bWJlck9mUG9pbnRzLHBvaW50czoiZGF0YTphcHBsaWNhdGlvbi92bmQuaXRrLnBhdGgsZGF0YS9wb2ludHMucmF3IixudW1iZXJPZlBvaW50UGl4ZWxzOmEubnVtYmVyT2ZQb2ludFBpeGVscyxwb2ludERhdGE6ImRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5wYXRoLGRhdGEvcG9pbnREYXRhLnJhdyIsbnVtYmVyT2ZDZWxsczphLm51bWJlck9mQ2VsbHMsY2VsbHM6ImRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5wYXRoLGRhdGEvY2VsbHMucmF3IixudW1iZXJPZkNlbGxQaXhlbHM6YS5udW1iZXJPZkNlbGxQaXhlbHMsY2VsbERhdGE6ImRhdGE6YXBwbGljYXRpb24vdm5kLml0ay5wYXRoLGRhdGEvY2VsbERhdGEucmF3IixjZWxsQnVmZmVyU2l6ZTphLmNlbGxCdWZmZXJTaXplfTtpZihBLmZzX21rZGlycyhgJHtDLnBhdGh9L2RhdGFgKSxBLmZzX3dyaXRlRmlsZShgJHtDLnBhdGh9L2luZGV4Lmpzb25gLEpTT04uc3RyaW5naWZ5KEIpKSxCLm51bWJlck9mUG9pbnRzPjApe2lmKGEucG9pbnRzPT09bnVsbCl0aHJvdyBFcnJvcigibWVzaC5wb2ludHMgaXMgbnVsbCIpO0EuZnNfd3JpdGVGaWxlKGAke0MucGF0aH0vZGF0YS9wb2ludHMucmF3YCxuZXcgVWludDhBcnJheShhLnBvaW50cy5idWZmZXIpKX1pZihCLm51bWJlck9mUG9pbnRQaXhlbHM+MCl7aWYoYS5wb2ludERhdGE9PT1udWxsKXRocm93IEVycm9yKCJtZXNoLnBvaW50RGF0YSBpcyBudWxsIik7QS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9kYXRhL3BvaW50RGF0YS5yYXdgLG5ldyBVaW50OEFycmF5KGEucG9pbnREYXRhLmJ1ZmZlcikpfWlmKEIubnVtYmVyT2ZDZWxscz4wKXtpZihhLmNlbGxzPT09bnVsbCl0aHJvdyBFcnJvcigibWVzaC5jZWxscyBpcyBudWxsIik7QS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9kYXRhL2NlbGxzLnJhd2AsbmV3IFVpbnQ4QXJyYXkoYS5jZWxscy5idWZmZXIpKX1pZihCLm51bWJlck9mQ2VsbFBpeGVscz4wKXtpZihhLmNlbGxEYXRhPT09bnVsbCl0aHJvdyBFcnJvcigibWVzaC5jZWxsRGF0YSBpcyBudWxsIik7QS5mc193cml0ZUZpbGUoYCR7Qy5wYXRofS9kYXRhL2NlbGxEYXRhLnJhd2AsbmV3IFVpbnQ4QXJyYXkoYS5jZWxsRGF0YS5idWZmZXIpKX1icmVha31kZWZhdWx0OnRocm93IEVycm9yKCJVbnN1cHBvcnRlZCBpbnB1dCBJbnRlcmZhY2VUeXBlIil9fSksQS5yZXNldE1vZHVsZVN0ZG91dCgpLEEucmVzZXRNb2R1bGVTdGRlcnIoKTtsZXQgcj1BLnN0YWNrU2F2ZSgpLGk9MDt0cnl7aT1BLmNhbGxNYWluKGUuc2xpY2UoKSl9Y2F0Y2goQyl7dGhyb3cgdHlwZW9mIEM9PSJudW1iZXIiJiYoY29uc29sZS5sb2coIkV4Y2VwdGlvbiB3aGlsZSBydW5uaW5nIHBpcGVsaW5lOiIpLGNvbnNvbGUubG9nKCJzdGRvdXQ6IixBLmdldE1vZHVsZVN0ZG91dCgpKSxjb25zb2xlLmVycm9yKCJzdGRlcnI6IixBLmdldE1vZHVsZVN0ZGVycigpKSx0eXBlb2YgQS5nZXRFeGNlcHRpb25NZXNzYWdlPCJ1Ij9jb25zb2xlLmVycm9yKCJleGNlcHRpb246IixBLmdldEV4Y2VwdGlvbk1lc3NhZ2UoQykpOmNvbnNvbGUuZXJyb3IoIkJ1aWxkIG1vZHVsZSBpbiBEZWJ1ZyBtb2RlIGZvciBleGNlcHRpb24gbWVzc2FnZSBpbmZvcm1hdGlvbi4iKSksQ31maW5hbGx5e0Euc3RhY2tSZXN0b3JlKHIpfWxldCBnPUEuZ2V0TW9kdWxlU3Rkb3V0KCksbj1BLmdldE1vZHVsZVN0ZGVycigpLEU9W107cmV0dXJuIHQhPW51bGwmJnQubGVuZ3RoPjAmJmk9PT0wJiZ0LmZvckVhY2goZnVuY3Rpb24oQyxvKXtsZXQgYz1udWxsO3N3aXRjaChDLnR5cGUpe2Nhc2UgdS5UZXh0U3RyZWFtOntsZXQgQj1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfYWRkcmVzcyIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxvLDBdKSxRPUEuY2NhbGwoIml0a193YXNtX291dHB1dF9hcnJheV9zaXplIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLG8sMF0pLGY9bmV3IFVpbnQ4QXJyYXkoQS5IRUFQVTguYnVmZmVyLEIsUSk7Yz17ZGF0YTpvdC5kZWNvZGUoZil9O2JyZWFrfWNhc2UgdS5Kc29uQ29tcGF0aWJsZTp7bGV0IEI9QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2FycmF5X2FkZHJlc3MiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsbywwXSksUT1BLmNjYWxsKCJpdGtfd2FzbV9vdXRwdXRfYXJyYXlfc2l6ZSIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJudW1iZXIiXSxbMCxvLDBdKSxmPW5ldyBVaW50OEFycmF5KEEuSEVBUFU4LmJ1ZmZlcixCLFEpO2M9SlNPTi5wYXJzZShvdC5kZWNvZGUoZikpO2JyZWFrfWNhc2UgdS5CaW5hcnlTdHJlYW06e2xldCBCPUEuY2NhbGwoIml0a193YXNtX291dHB1dF9hcnJheV9hZGRyZXNzIiwibnVtYmVyIixbIm51bWJlciIsIm51bWJlciIsIm51bWJlciJdLFswLG8sMF0pLFE9QS5jY2FsbCgiaXRrX3dhc21fb3V0cHV0X2FycmF5X3NpemUiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIl0sWzAsbywwXSk7Yz17ZGF0YTphdChBLEIsUSl9O2JyZWFrfWNhc2UgdS5UZXh0RmlsZTp7Yz17cGF0aDpDLmRhdGEucGF0aCxkYXRhOkEuZnNfcmVhZEZpbGUoQy5kYXRhLnBhdGgse2VuY29kaW5nOiJ1dGY4In0pfTticmVha31jYXNlIHUuQmluYXJ5RmlsZTp7Yz17cGF0aDpDLmRhdGEucGF0aCxkYXRhOkgoQSxDLmRhdGEucGF0aCl9O2JyZWFrfWNhc2UgdS5JbWFnZTp7bGV0IEI9bmUoQSxvKTtCLmRhdGE9TihBLG8sMCxCLmltYWdlVHlwZS5jb21wb25lbnRUeXBlKSxCLmRpcmVjdGlvbj1OKEEsbywxLFQuRmxvYXQ2NCksQi5tZXRhZGF0YT1uZXcgTWFwKEIubWV0YWRhdGEpLGM9QjticmVha31jYXNlIHUuTWVzaDp7bGV0IEI9bmUoQSxvKTtCLm51bWJlck9mUG9pbnRzPjA/Qi5wb2ludHM9TihBLG8sMCxCLm1lc2hUeXBlLnBvaW50Q29tcG9uZW50VHlwZSk6Qi5wb2ludHM9bShCLm1lc2hUeXBlLnBvaW50Q29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpLEIubnVtYmVyT2ZDZWxscz4wP0IuY2VsbHM9TihBLG8sMSxCLm1lc2hUeXBlLmNlbGxDb21wb25lbnRUeXBlKTpCLmNlbGxzPW0oQi5tZXNoVHlwZS5jZWxsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpLEIubnVtYmVyT2ZQb2ludFBpeGVscz4wP0IucG9pbnREYXRhPU4oQSxvLDIsQi5tZXNoVHlwZS5wb2ludFBpeGVsQ29tcG9uZW50VHlwZSk6Qi5wb2ludERhdGE9bShCLm1lc2hUeXBlLnBvaW50UGl4ZWxDb21wb25lbnRUeXBlLG5ldyBBcnJheUJ1ZmZlcigwKSksQi5udW1iZXJPZkNlbGxQaXhlbHM+MD9CLmNlbGxEYXRhPU4oQSxvLDMsQi5tZXNoVHlwZS5jZWxsUGl4ZWxDb21wb25lbnRUeXBlKTpCLmNlbGxEYXRhPW0oQi5tZXNoVHlwZS5jZWxsUGl4ZWxDb21wb25lbnRUeXBlLG5ldyBBcnJheUJ1ZmZlcigwKSksYz1CO2JyZWFrfWNhc2UgdS5Qb2x5RGF0YTp7bGV0IEI9bmUoQSxvKTtCLm51bWJlck9mUG9pbnRzPjA/Qi5wb2ludHM9TihBLG8sMCxULkZsb2F0MzIpOkIucG9pbnRzPW5ldyBGbG9hdDMyQXJyYXksQi52ZXJ0aWNlc0J1ZmZlclNpemU+MD9CLnZlcnRpY2VzPU4oQSxvLDEscC5VSW50MzIpOkIudmVydGljZXM9bmV3IFVpbnQzMkFycmF5LEIubGluZXNCdWZmZXJTaXplPjA/Qi5saW5lcz1OKEEsbywyLHAuVUludDMyKTpCLmxpbmVzPW5ldyBVaW50MzJBcnJheSxCLnBvbHlnb25zQnVmZmVyU2l6ZT4wP0IucG9seWdvbnM9TihBLG8sMyxwLlVJbnQzMik6Qi5wb2x5Z29ucz1uZXcgVWludDMyQXJyYXksQi50cmlhbmdsZVN0cmlwc0J1ZmZlclNpemU+MD9CLnRyaWFuZ2xlU3RyaXBzPU4oQSxvLDQscC5VSW50MzIpOkIudHJpYW5nbGVTdHJpcHM9bmV3IFVpbnQzMkFycmF5LEIubnVtYmVyT2ZQb2ludFBpeGVscz4wP0IucG9pbnREYXRhPU4oQSxvLDUsQi5wb2x5RGF0YVR5cGUucG9pbnRQaXhlbENvbXBvbmVudFR5cGUpOkIucG9pbnREYXRhPW0oQi5wb2x5RGF0YVR5cGUucG9pbnRQaXhlbENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKSxCLm51bWJlck9mQ2VsbFBpeGVscz4wP0IuY2VsbERhdGE9TihBLG8sNixCLnBvbHlEYXRhVHlwZS5jZWxsUGl4ZWxDb21wb25lbnRUeXBlKTpCLmNlbGxEYXRhPW0oQi5wb2x5RGF0YVR5cGUuY2VsbFBpeGVsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpLGM9QjticmVha31jYXNlIFMuVGV4dDp7aWYodHlwZW9mIEMucGF0aD4idSIpdGhyb3cgbmV3IEVycm9yKCJvdXRwdXQucGF0aCBub3QgZGVmaW5lZCIpO2M9QS5mc19yZWFkRmlsZShDLnBhdGgse2VuY29kaW5nOiJ1dGY4In0pO2JyZWFrfWNhc2UgUy5CaW5hcnk6e2lmKHR5cGVvZiBDLnBhdGg+InUiKXRocm93IG5ldyBFcnJvcigib3V0cHV0LnBhdGggbm90IGRlZmluZWQiKTtjPUgoQSxDLnBhdGgpO2JyZWFrfWNhc2UgUy5JbWFnZTp7aWYodHlwZW9mIEMucGF0aD4idSIpdGhyb3cgbmV3IEVycm9yKCJvdXRwdXQucGF0aCBub3QgZGVmaW5lZCIpO2xldCBCPUEuZnNfcmVhZEZpbGUoYCR7Qy5wYXRofS9pbmRleC5qc29uYCx7ZW5jb2Rpbmc6InV0ZjgifSksUT1KU09OLnBhcnNlKEIpLGY9SChBLGAke0MucGF0aH0vZGF0YS9kYXRhLnJhd2ApO1EuZGF0YT1tKFEuaW1hZ2VUeXBlLmNvbXBvbmVudFR5cGUsZi5idWZmZXIpO2xldCBkPUgoQSxgJHtDLnBhdGh9L2RhdGEvZGlyZWN0aW9uLnJhd2ApO1EuZGlyZWN0aW9uPW0oVC5GbG9hdDY0LGQuYnVmZmVyKSxjPVE7YnJlYWt9Y2FzZSBTLk1lc2g6e2lmKHR5cGVvZiBDLnBhdGg+InUiKXRocm93IG5ldyBFcnJvcigib3V0cHV0LnBhdGggbm90IGRlZmluZWQiKTtsZXQgQj1BLmZzX3JlYWRGaWxlKGAke0MucGF0aH0vaW5kZXguanNvbmAse2VuY29kaW5nOiJ1dGY4In0pLFE9SlNPTi5wYXJzZShCKTtpZihRLm51bWJlck9mUG9pbnRzPjApe2xldCBmPUgoQSxgJHtDLnBhdGh9L2RhdGEvcG9pbnRzLnJhd2ApO1EucG9pbnRzPW0oUS5tZXNoVHlwZS5wb2ludENvbXBvbmVudFR5cGUsZi5idWZmZXIpfWVsc2UgUS5wb2ludHM9bShRLm1lc2hUeXBlLnBvaW50Q29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpO2lmKFEubnVtYmVyT2ZQb2ludFBpeGVscz4wKXtsZXQgZj1IKEEsYCR7Qy5wYXRofS9kYXRhL3BvaW50RGF0YS5yYXdgKTtRLnBvaW50RGF0YT1tKFEubWVzaFR5cGUucG9pbnRQaXhlbENvbXBvbmVudFR5cGUsZi5idWZmZXIpfWVsc2UgUS5wb2ludERhdGE9bShRLm1lc2hUeXBlLnBvaW50UGl4ZWxDb21wb25lbnRUeXBlLG5ldyBBcnJheUJ1ZmZlcigwKSk7aWYoUS5udW1iZXJPZkNlbGxzPjApe2xldCBmPUgoQSxgJHtDLnBhdGh9L2RhdGEvY2VsbHMucmF3YCk7US5jZWxscz1tKFEubWVzaFR5cGUuY2VsbENvbXBvbmVudFR5cGUsZi5idWZmZXIpfWVsc2UgUS5jZWxscz1tKFEubWVzaFR5cGUuY2VsbENvbXBvbmVudFR5cGUsbmV3IEFycmF5QnVmZmVyKDApKTtpZihRLm51bWJlck9mQ2VsbFBpeGVscz4wKXtsZXQgZj1IKEEsYCR7Qy5wYXRofS9kYXRhL2NlbGxEYXRhLnJhd2ApO1EuY2VsbERhdGE9bShRLm1lc2hUeXBlLmNlbGxQaXhlbENvbXBvbmVudFR5cGUsZi5idWZmZXIpfWVsc2UgUS5jZWxsRGF0YT1tKFEubWVzaFR5cGUuY2VsbFBpeGVsQ29tcG9uZW50VHlwZSxuZXcgQXJyYXlCdWZmZXIoMCkpO2M9UTticmVha31kZWZhdWx0OnRocm93IEVycm9yKCJVbnN1cHBvcnRlZCBvdXRwdXQgSW50ZXJmYWNlVHlwZSIpfWxldCBhPXt0eXBlOkMudHlwZSxkYXRhOmN9O0UucHVzaChhKX0pLHtyZXR1cm5WYWx1ZTppLHN0ZG91dDpnLHN0ZGVycjpuLG91dHB1dHM6RX19dmFyIHo9T0k7dmFyIG9BPWZ1bmN0aW9uKEEpe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygb0E/KHRoaXMudj1BLHRoaXMpOm5ldyBvQShBKX0sSkk9ZnVuY3Rpb24oQSxlLHQpe2lmKCFTeW1ib2wuYXN5bmNJdGVyYXRvcil0aHJvdyBuZXcgVHlwZUVycm9yKCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC4iKTt2YXIgST10LmFwcGx5KEEsZXx8W10pLHIsaT1bXTtyZXR1cm4gcj17fSxnKCJuZXh0IiksZygidGhyb3ciKSxnKCJyZXR1cm4iKSxyW1N5bWJvbC5hc3luY0l0ZXJhdG9yXT1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxyO2Z1bmN0aW9uIGcoYSl7SVthXSYmKHJbYV09ZnVuY3Rpb24oQil7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKFEsZil7aS5wdXNoKFthLEIsUSxmXSk+MXx8bihhLEIpfSl9KX1mdW5jdGlvbiBuKGEsQil7dHJ5e0UoSVthXShCKSl9Y2F0Y2goUSl7YyhpWzBdWzNdLFEpfX1mdW5jdGlvbiBFKGEpe2EudmFsdWUgaW5zdGFuY2VvZiBvQT9Qcm9taXNlLnJlc29sdmUoYS52YWx1ZS52KS50aGVuKEMsbyk6YyhpWzBdWzJdLGEpfWZ1bmN0aW9uIEMoYSl7bigibmV4dCIsYSl9ZnVuY3Rpb24gbyhhKXtuKCJ0aHJvdyIsYSl9ZnVuY3Rpb24gYyhhLEIpe2EoQiksaS5zaGlmdCgpLGkubGVuZ3RoJiZuKGlbMF1bMF0saVswXVsxXSl9fSxNST1mdW5jdGlvbihBKXtpZighU3ltYm9sLmFzeW5jSXRlcmF0b3IpdGhyb3cgbmV3IFR5cGVFcnJvcigiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIik7dmFyIGU9QVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0sdDtyZXR1cm4gZT9lLmNhbGwoQSk6KEE9dHlwZW9mIF9fdmFsdWVzPT0iZnVuY3Rpb24iP19fdmFsdWVzKEEpOkFbU3ltYm9sLml0ZXJhdG9yXSgpLHQ9e30sSSgibmV4dCIpLEkoInRocm93IiksSSgicmV0dXJuIiksdFtTeW1ib2wuYXN5bmNJdGVyYXRvcl09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30sdCk7ZnVuY3Rpb24gSShpKXt0W2ldPUFbaV0mJmZ1bmN0aW9uKGcpe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihuLEUpe2c9QVtpXShnKSxyKG4sRSxnLmRvbmUsZy52YWx1ZSl9KX19ZnVuY3Rpb24gcihpLGcsbixFKXtQcm9taXNlLnJlc29sdmUoRSkudGhlbihmdW5jdGlvbihDKXtpKHt2YWx1ZTpDLGRvbmU6bn0pfSxnKX19O2Z1bmN0aW9uIGJJKEEpe3JldHVybiBKSSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbiooKXtmb3IobGV0IHQ9MDt0PGtBLmxlbmd0aDt0Kyspe2xldCBJPWtBW3RdKyItcmVhZC1pbWFnZSIscj15aWVsZCBvQShVKEksQS5jb25maWcuaW1hZ2VJT1VybCkpO3lpZWxkIHlpZWxkIG9BKHIpfX0pfWFzeW5jIGZ1bmN0aW9uIEhJKEEsZSl7dmFyIHQsSTtpZihBLm1pbWVUeXBlJiZnZS5oYXMoQS5taW1lVHlwZSkpe2xldCBuPWdlLmdldChBLm1pbWVUeXBlKStlO3JldHVybiBhd2FpdCBVKG4sQS5jb25maWcuaW1hZ2VJT1VybCl9bGV0IHI9VUEoQS5maWxlTmFtZSk7aWYob2UuaGFzKHIpKXtsZXQgbj1vZS5nZXQocikrZTtyZXR1cm4gYXdhaXQgVShuLEEuY29uZmlnLmltYWdlSU9VcmwpfWZvcihsZXQgbj0wO248a0EubGVuZ3RoOysrbil7bGV0IEU9MDt0cnl7Zm9yKHZhciBpPSh0PXZvaWQgMCxNSShiSShBKSkpLGc7Zz1hd2FpdCBpLm5leHQoKSwhZy5kb25lOyl7bGV0IEM9Zy52YWx1ZTt0cnl7bGV0e3JldHVyblZhbHVlOm8sb3V0cHV0czpjfT1hd2FpdCB6KEMsQS5hcmdzLEEub3V0cHV0cyxBLmlucHV0cyk7aWYobz09PTApcmV0dXJuIEN9Y2F0Y2h7fUUrK319Y2F0Y2goQyl7dD17ZXJyb3I6Q319ZmluYWxseXt0cnl7ZyYmIWcuZG9uZSYmKEk9aS5yZXR1cm4pJiZhd2FpdCBJLmNhbGwoaSl9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fX10aHJvdyBFcnJvcihgQ291bGQgbm90IGZpbmQgSU8gZm9yOiAke0EuZmlsZU5hbWV9YCl9dmFyIGFlPUhJO3ZhciBZST1uZXcgTWFwKFtdKSxzZT1ZSTt2YXIgcUk9bmV3IE1hcChbWyJ2dGsiLCJWVEtQb2x5RGF0YU1lc2hJTyJdLFsiVlRLIiwiVlRLUG9seURhdGFNZXNoSU8iXSxbImJ5dSIsIkJZVU1lc2hJTyJdLFsiQllVIiwiQllVTWVzaElPIl0sWyJmc2EiLCJGcmVlU3VyZmVyQXNjaWlNZXNoSU8iXSxbIkZTQSIsIkZyZWVTdXJmZXJBc2NpaU1lc2hJTyJdLFsiZnNiIiwiRnJlZVN1cmZlckJpbmFyeU1lc2hJTyJdLFsiRlNCIiwiRnJlZVN1cmZlckJpbmFyeU1lc2hJTyJdLFsib2JqIiwiT0JKTWVzaElPIl0sWyJPQkoiLCJPQkpNZXNoSU8iXSxbIm9mZiIsIk9GRk1lc2hJTyJdLFsiT0ZGIiwiT0ZGTWVzaElPIl0sWyJzdGwiLCJTVExNZXNoSU8iXSxbIlNUTCIsIlNUTE1lc2hJTyJdLFsic3djIiwiU1dDTWVzaElPIl0sWyJTV0MiLCJTV0NNZXNoSU8iXSxbIml3bSIsIldhc21NZXNoSU8iXSxbIml3bS5jYm9yIiwiV2FzbU1lc2hJTyJdLFsiaXdtLmNib3IuenN0IiwiV2FzbVpzdGRNZXNoSU8iXV0pLENlPXFJO3ZhciBUST1bIkJZVU1lc2hJTyIsIkZyZWVTdXJmZXJBc2NpaU1lc2hJTyIsIkZyZWVTdXJmZXJCaW5hcnlNZXNoSU8iLCJPQkpNZXNoSU8iLCJPRkZNZXNoSU8iLCJTVExNZXNoSU8iLCJTV0NNZXNoSU8iLCJWVEtQb2x5RGF0YU1lc2hJTyIsIldhc21NZXNoSU8iLCJXYXNtWnN0ZE1lc2hJTyJdLExBPVRJO3ZhciBuQT1mdW5jdGlvbihBKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIG5BPyh0aGlzLnY9QSx0aGlzKTpuZXcgbkEoQSl9LEtJPWZ1bmN0aW9uKEEsZSx0KXtpZighU3ltYm9sLmFzeW5jSXRlcmF0b3IpdGhyb3cgbmV3IFR5cGVFcnJvcigiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIik7dmFyIEk9dC5hcHBseShBLGV8fFtdKSxyLGk9W107cmV0dXJuIHI9e30sZygibmV4dCIpLGcoInRocm93IiksZygicmV0dXJuIikscltTeW1ib2wuYXN5bmNJdGVyYXRvcl09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30scjtmdW5jdGlvbiBnKGEpe0lbYV0mJihyW2FdPWZ1bmN0aW9uKEIpe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihRLGYpe2kucHVzaChbYSxCLFEsZl0pPjF8fG4oYSxCKX0pfSl9ZnVuY3Rpb24gbihhLEIpe3RyeXtFKElbYV0oQikpfWNhdGNoKFEpe2MoaVswXVszXSxRKX19ZnVuY3Rpb24gRShhKXthLnZhbHVlIGluc3RhbmNlb2YgbkE/UHJvbWlzZS5yZXNvbHZlKGEudmFsdWUudikudGhlbihDLG8pOmMoaVswXVsyXSxhKX1mdW5jdGlvbiBDKGEpe24oIm5leHQiLGEpfWZ1bmN0aW9uIG8oYSl7bigidGhyb3ciLGEpfWZ1bmN0aW9uIGMoYSxCKXthKEIpLGkuc2hpZnQoKSxpLmxlbmd0aCYmbihpWzBdWzBdLGlbMF1bMV0pfX0seEk9ZnVuY3Rpb24oQSl7aWYoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKXRocm93IG5ldyBUeXBlRXJyb3IoIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpO3ZhciBlPUFbU3ltYm9sLmFzeW5jSXRlcmF0b3JdLHQ7cmV0dXJuIGU/ZS5jYWxsKEEpOihBPXR5cGVvZiBfX3ZhbHVlcz09ImZ1bmN0aW9uIj9fX3ZhbHVlcyhBKTpBW1N5bWJvbC5pdGVyYXRvcl0oKSx0PXt9LEkoIm5leHQiKSxJKCJ0aHJvdyIpLEkoInJldHVybiIpLHRbU3ltYm9sLmFzeW5jSXRlcmF0b3JdPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LHQpO2Z1bmN0aW9uIEkoaSl7dFtpXT1BW2ldJiZmdW5jdGlvbihnKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24obixFKXtnPUFbaV0oZykscihuLEUsZy5kb25lLGcudmFsdWUpfSl9fWZ1bmN0aW9uIHIoaSxnLG4sRSl7UHJvbWlzZS5yZXNvbHZlKEUpLnRoZW4oZnVuY3Rpb24oQyl7aSh7dmFsdWU6Qyxkb25lOm59KX0sZyl9fTtmdW5jdGlvbiBQSShBKXtyZXR1cm4gS0kodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24qKCl7Zm9yKGxldCB0PTA7dDxMQS5sZW5ndGg7dCsrKXtsZXQgST1MQVt0XSsiLXJlYWQtbWVzaCIscj15aWVsZCBuQShVKEksQS5jb25maWcubWVzaElPVXJsKSk7eWllbGQgeWllbGQgbkEocil9fSl9YXN5bmMgZnVuY3Rpb24gV0koQSxlKXt2YXIgdCxJO2lmKEEubWltZVR5cGUmJnNlLmhhcyhBLm1pbWVUeXBlKSl7bGV0IG49c2UuZ2V0KEEubWltZVR5cGUpK2U7cmV0dXJuIGF3YWl0IFUobixBLmNvbmZpZy5tZXNoSU9VcmwpfWxldCByPVVBKEEuZmlsZU5hbWUpO2lmKENlLmhhcyhyKSl7bGV0IG49Q2UuZ2V0KHIpK2U7cmV0dXJuIGF3YWl0IFUobixBLmNvbmZpZy5tZXNoSU9VcmwpfWZvcihsZXQgbj0wO248TEEubGVuZ3RoOysrbil7bGV0IEU9MDt0cnl7Zm9yKHZhciBpPSh0PXZvaWQgMCx4SShQSShBKSkpLGc7Zz1hd2FpdCBpLm5leHQoKSwhZy5kb25lOyl7bGV0IEM9Zy52YWx1ZTt0cnl7bGV0e3JldHVyblZhbHVlOm8sb3V0cHV0czpjfT1hd2FpdCB6KEMsQS5hcmdzLEEub3V0cHV0cyxBLmlucHV0cyk7aWYobz09PTApcmV0dXJuIEN9Y2F0Y2h7fUUrK319Y2F0Y2goQyl7dD17ZXJyb3I6Q319ZmluYWxseXt0cnl7ZyYmIWcuZG9uZSYmKEk9aS5yZXR1cm4pJiZhd2FpdCBJLmNhbGwoaSl9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fX10aHJvdyBFcnJvcihgQ291bGQgbm90IGZpbmQgSU8gZm9yOiAke0EuZmlsZU5hbWV9YCl9dmFyIEJlPVdJO3ZhciBqST10eXBlb2YgZ2xvYmFsVGhpcy5TaGFyZWRBcnJheUJ1ZmZlcjwidSI7ZnVuY3Rpb24gWkkoQSl7aWYoQT09bnVsbClyZXR1cm5bXTtsZXQgZT1bXTtmb3IobGV0IHQ9MDt0PEEubGVuZ3RoO3QrKyl7bGV0IEk9X0koQVt0XSk7SSE9PW51bGwmJmUucHVzaChJKX1yZXR1cm4gZX1mdW5jdGlvbiBfSShBKXtpZihBPT1udWxsKXJldHVybiBudWxsO2xldCBlPW51bGw7cmV0dXJuIEEuYnVmZmVyIT09dm9pZCAwP2U9QS5idWZmZXI6QS5ieXRlTGVuZ3RoIT09dm9pZCAwJiYoZT1BKSxqSSYmZSBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyP251bGw6ZX12YXIgc3Q9Wkk7ZnVuY3Rpb24gVkkoQSl7cmV0dXJuW0EuZGF0YSxBLmRpcmVjdGlvbl19dmFyIFFlPVZJO2Z1bmN0aW9uIHpJKEEpe3JldHVybltBLnBvaW50cyxBLnBvaW50RGF0YSxBLmNlbGxzLEEuY2VsbERhdGFdfXZhciBFZT16STtmdW5jdGlvbiBYSShBKXtyZXR1cm5bQS5wb2ludHMsQS52ZXJ0aWNlcyxBLmxpbmVzLEEucG9seWdvbnMsQS50cmlhbmdsZVN0cmlwcyxBLnBvaW50RGF0YSxBLmNlbGxEYXRhXX12YXIgQ3Q9WEk7YXN5bmMgZnVuY3Rpb24gdkkoQSxlLHQsSSl7bGV0IHI9eihBLGUsdCxJKSxpPVtdO3JldHVybiByLm91dHB1dHMmJnIub3V0cHV0cy5mb3JFYWNoKGZ1bmN0aW9uKGcpe2lmKGcudHlwZT09PXUuQmluYXJ5U3RyZWFtfHxnLnR5cGU9PT11LkJpbmFyeUZpbGUpe2xldCBuPWcuZGF0YTtpLnB1c2gobil9ZWxzZSBpZihnLnR5cGU9PT11LkltYWdlKXtsZXQgbj1nLmRhdGE7aS5wdXNoKC4uLlFlKG4pKX1lbHNlIGlmKGcudHlwZT09PXUuTWVzaCl7bGV0IG49Zy5kYXRhO2kucHVzaCguLi5FZShuKSl9ZWxzZSBpZihnLnR5cGU9PT11LlBvbHlEYXRhKXtsZXQgbj1nLmRhdGE7aS5wdXNoKC4uLkN0KG4pKX1lbHNlIGlmKGcudHlwZT09PVMuQmluYXJ5KXtsZXQgbj1nLmRhdGE7aS5wdXNoKG4pfWVsc2UgaWYoZy50eXBlPT09Uy5JbWFnZSl7bGV0IG49Zy5kYXRhO2kucHVzaCguLi5RZShuKSl9ZWxzZSBpZihnLnR5cGU9PT1TLk1lc2gpe2xldCBuPWcuZGF0YTtpLnB1c2goLi4uRWUobikpfX0pLGJBKHIsc3QoaSkpfXZhciBZPXZJO3ZhciAkST17bWVzaFRvUG9seURhdGE6YXN5bmMgZnVuY3Rpb24oQSxlLHQsSSl7bGV0IHI9YXdhaXQgVSgibWVzaC10by1wb2x5ZGF0YSIsQS5tZXNoSU9VcmwpO3JldHVybiBZKHIsZSx0LEkpfSxwb2x5RGF0YVRvTWVzaDphc3luYyBmdW5jdGlvbihBLGUsdCxJKXtsZXQgcj1hd2FpdCBVKCJwb2x5ZGF0YS10by1tZXNoIixBLm1lc2hJT1VybCk7cmV0dXJuIFkocixlLHQsSSl9LHJlYWRJbWFnZTphc3luYyBmdW5jdGlvbihBLGUsdCxJLHIsaSl7bGV0IGc9YXdhaXQgYWUoe2ZpbGVOYW1lOnQsbWltZVR5cGU6ZSxjb25maWc6QSxhcmdzOkksb3V0cHV0czpyLGlucHV0czppfSwiLXJlYWQtaW1hZ2UiKTtyZXR1cm4gWShnLEkscixpKX0sd3JpdGVJbWFnZTphc3luYyBmdW5jdGlvbihBLGUsdCxJLHIsaSl7bGV0IGc9YXdhaXQgYWUoe2ZpbGVOYW1lOnQsbWltZVR5cGU6ZSxjb25maWc6QSxhcmdzOkksb3V0cHV0czpyLGlucHV0czppfSwiLXdyaXRlLWltYWdlIik7cmV0dXJuIFkoZyxJLHIsaSl9LHJlYWRNZXNoOmFzeW5jIGZ1bmN0aW9uKEEsZSx0LEkscixpKXtsZXQgZz1hd2FpdCBCZSh7ZmlsZU5hbWU6dCxtaW1lVHlwZTplLGNvbmZpZzpBLGFyZ3M6SSxvdXRwdXRzOnIsaW5wdXRzOml9LCItcmVhZC1tZXNoIik7cmV0dXJuIFkoZyxJLHIsaSl9LHdyaXRlTWVzaDphc3luYyBmdW5jdGlvbihBLGUsdCxJLHIsaSl7bGV0IGc9YXdhaXQgQmUoe2ZpbGVOYW1lOnQsbWltZVR5cGU6ZSxjb25maWc6QSxhcmdzOkksb3V0cHV0czpyLGlucHV0czppfSwiLXdyaXRlLW1lc2giKTtyZXR1cm4gWShnLEkscixpKX0scnVuUGlwZWxpbmU6YXN5bmMgZnVuY3Rpb24oQSxlLHQsSSxyLGkpe2xldCBnPXR5cGVvZiBBW3RdPiJ1Ij90OkFbdF0sbj1hd2FpdCBVKGUsZyk7cmV0dXJuIFkobixJLHIsaSl9fTtFQSgkSSk7JTBBLyohIEJ1bmRsZWQgbGljZW5zZSBpbmZvcm1hdGlvbjolMEElMEFjb21saW5rL2Rpc3QvZXNtL2NvbWxpbmsubWpzOiUwQSAgKCoqJTBBICAgKiBAbGljZW5zZSUwQSAgICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQyUwQSAgICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAlMEEgICAqKSUwQSovJTBBJztVdChOdCk7ZXhwb3J0e2hlIGFzIGJ5dVJlYWRNZXNoLHllIGFzIGJ5dVdyaXRlTWVzaCx3ZSBhcyBmcmVlU3VyZmVyQXNjaWlSZWFkTWVzaCxEZSBhcyBmcmVlU3VyZmVyQXNjaWlXcml0ZU1lc2gsYmUgYXMgZnJlZVN1cmZlckJpbmFyeVJlYWRNZXNoLEZlIGFzIGZyZWVTdXJmZXJCaW5hcnlXcml0ZU1lc2gsUSBhcyBnZXRQaXBlbGluZVdvcmtlclVybCxFIGFzIGdldFBpcGVsaW5lc0Jhc2VVcmwsbGUgYXMgb2JqUmVhZE1lc2gsZ2UgYXMgb2JqV3JpdGVNZXNoLHBlIGFzIG9mZlJlYWRNZXNoLGNlIGFzIG9mZldyaXRlTWVzaCxHaSBhcyByZWFkTWVzaCxVdCBhcyBzZXRQaXBlbGluZVdvcmtlclVybCxQcyBhcyBzZXRQaXBlbGluZXNCYXNlVXJsLHVlIGFzIHN0bFJlYWRNZXNoLGZlIGFzIHN0bFdyaXRlTWVzaCxFZSBhcyBzd2NSZWFkTWVzaCxRZSBhcyBzd2NXcml0ZU1lc2gsc2UgYXMgdnRrUG9seURhdGFSZWFkTWVzaCxJZSBhcyB2dGtQb2x5RGF0YVdyaXRlTWVzaCxCZSBhcyB3YXNtUmVhZE1lc2gsQ2UgYXMgd2FzbVdyaXRlTWVzaCxtZSBhcyB3YXNtWnN0ZFJlYWRNZXNoLGRlIGFzIHdhc21ac3RkV3JpdGVNZXNoLEhpIGFzIHdhc21adGRSZWFkTWVzaCxxaSBhcyB3YXNtWnRkV3JpdGVNZXNoLExpIGFzIHdyaXRlTWVzaH07Ci8qISBCdW5kbGVkIGxpY2Vuc2UgaW5mb3JtYXRpb246Cgpjb21saW5rL2Rpc3QvZXNtL2NvbWxpbmsubWpzOgogICgqKgogICAqIEBsaWNlbnNlCiAgICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQwogICAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wCiAgICopCiovCg==""" +default_config = JsPackageConfig(default_js_module) +js_package = JsPackage(default_config) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_read_mesh_async.py new file mode 100644 index 000000000..2fa547304 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def obj_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.objReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_write_mesh_async.py new file mode 100644 index 000000000..433e9fbcb --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/obj_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def obj_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.objWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_read_mesh_async.py new file mode 100644 index 000000000..3b2c38f39 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def off_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.offReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_write_mesh_async.py new file mode 100644 index 000000000..e20bd0de1 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/off_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def off_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.offWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_read_mesh_async.py new file mode 100644 index 000000000..0cdd11fff --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def stl_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.stlReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_write_mesh_async.py new file mode 100644 index 000000000..35d77f8c6 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/stl_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def stl_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.stlWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_read_mesh_async.py new file mode 100644 index 000000000..62e898315 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def swc_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.swcReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_write_mesh_async.py new file mode 100644 index 000000000..d10b28af7 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/swc_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def swc_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.swcWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_read_mesh_async.py new file mode 100644 index 000000000..927c36bd0 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def vtk_poly_data_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.vtkPolyDataReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_write_mesh_async.py new file mode 100644 index 000000000..5fe9631e1 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/vtk_poly_data_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def vtk_poly_data_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.vtkPolyDataWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_read_mesh_async.py new file mode 100644 index 000000000..c60af46e3 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def wasm_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.wasmReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_write_mesh_async.py new file mode 100644 index 000000000..da3f40d4f --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def wasm_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.wasmWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_read_mesh_async.py new file mode 100644 index 000000000..6bf589bf8 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def wasm_zstd_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.wasmZstdReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_write_mesh_async.py new file mode 100644 index 000000000..4c5ab0f6a --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_zstd_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def wasm_zstd_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.wasmZstdWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_read_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_read_mesh_async.py new file mode 100644 index 000000000..4b9ffd3e4 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_read_mesh_async.py @@ -0,0 +1,60 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + BinaryFile, + Mesh, +) + +async def wasm_ztd_read_mesh_async( + serialized_mesh: os.PathLike, + information_only: bool = False, +) -> Tuple[Any, Mesh]: + """Read a mesh file format and convert it to the itk-wasm file format + + :param serialized_mesh: Input mesh serialized in the file format + :type serialized_mesh: os.PathLike + + :param information_only: Only read image metadata -- do not read pixel data. + :type information_only: bool + + :return: Whether the input could be read. If false, the output mesh is not valid. + :rtype: Any + + :return: Output mesh + :rtype: Mesh + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + + outputs = await js_module.wasmZtdReadMesh(web_worker, to_js(BinaryFile(serialized_mesh)), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_write_mesh_async.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_write_mesh_async.py new file mode 100644 index 000000000..3b6344878 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/itkwasm_mesh_io_emscripten/wasm_ztd_write_mesh_async.py @@ -0,0 +1,73 @@ +# Generated file. To retain edits, remove this comment. + +from pathlib import Path +import os +from typing import Dict, Tuple, Optional, List, Any + +from .js_package import js_package + +from itkwasm.pyodide import ( + to_js, + to_py, + js_resources +) +from itkwasm import ( + InterfaceTypes, + Mesh, + BinaryFile, +) + +async def wasm_ztd_write_mesh_async( + mesh: Mesh, + serialized_mesh: str, + information_only: bool = False, + use_compression: bool = False, + binary_file_type: bool = False, +) -> Tuple[Any]: + """Write an itk-wasm file format converted to an mesh file format + + :param mesh: Input mesh + :type mesh: Mesh + + :param serialized_mesh: Output mesh + :type serialized_mesh: str + + :param information_only: Only write image metadata -- do not write pixel data. + :type information_only: bool + + :param use_compression: Use compression in the written file, if supported + :type use_compression: bool + + :param binary_file_type: Use a binary file type in the written file, if supported + :type binary_file_type: bool + + :return: Whether the input could be written. If false, the output mesh is not valid. + :rtype: Any + """ + js_module = await js_package.js_module + web_worker = js_resources.web_worker + + kwargs = {} + if information_only: + kwargs["informationOnly"] = to_js(information_only) + if use_compression: + kwargs["useCompression"] = to_js(use_compression) + if binary_file_type: + kwargs["binaryFileType"] = to_js(binary_file_type) + + outputs = await js_module.wasmZtdWriteMesh(web_worker, to_js(mesh), to_js(serialized_mesh), **kwargs) + + output_web_worker = None + output_list = [] + outputs_object_map = outputs.as_object_map() + for output_name in outputs.object_keys(): + if output_name == 'webWorker': + output_web_worker = outputs_object_map[output_name] + else: + output_list.append(to_py(outputs_object_map[output_name])) + + js_resources.web_worker = output_web_worker + + if len(output_list) == 1: + return output_list[0] + return tuple(output_list) diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/pyproject.toml b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/pyproject.toml new file mode 100644 index 000000000..1e7d7ccbc --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/pyproject.toml @@ -0,0 +1,73 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "itkwasm-mesh-io-emscripten" +readme = "README.md" +license = "Apache-2.0" +dynamic = ["version"] +description = "Input and output for scientific and medical image file formats." +classifiers = [ + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: C++", + "Environment :: WebAssembly", + "Environment :: WebAssembly :: Emscripten", + "Environment :: WebAssembly :: WASI", + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +keywords = [ + "itkwasm", + "webassembly", + "emscripten", +] + +requires-python = ">=3.8" +dependencies = [ + "itkwasm >= 1.0.b145", +] + +[tool.hatch.version] +path = "itkwasm_mesh_io_emscripten/_version.py" + +[tool.hatch.envs.default] +dependencies = [ + "pytest", + "pytest-pyodide", +] + +[project.urls] +Home = "https://github.com/InsightSoftwareConsortium/itk-wasm" +Source = "https://github.com/InsightSoftwareConsortium/itk-wasm" + +[tool.hatch.envs.default.scripts] +test = [ + "hatch build -t wheel", + "pytest --dist-dir=./dist --rt=chrome", +] +download-pyodide = [ + "curl -L https://github.com/pyodide/pyodide/releases/download/0.24.1/pyodide-0.24.1.tar.bz2 -o pyodide.tar.bz2", + "tar xjf pyodide.tar.bz2", + "rm -rf dist pyodide.tar.bz2", + "mv pyodide dist", +] +serve = [ + "hatch build -t wheel", + 'echo "\nVisit http://localhost:8877/console.html\n"', + "python -m http.server --directory=./dist 8877", +] + + +[tool.hatch.build] +exclude = [ + "/examples", +] diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/__init__.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/fixtures.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/fixtures.py new file mode 100644 index 000000000..b54af232e --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/fixtures.py @@ -0,0 +1,28 @@ +import pytest +import sys + +if sys.version_info < (3,10): + pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True) + +from pytest_pyodide import run_in_pyodide + +from itkwasm_image_io_emscripten import __version__ as test_package_version + +@pytest.fixture +def package_wheel(): + return f"itkwasm_image_io_emscripten-{test_package_version}-py3-none-any.whl" + +@pytest.fixture +def input_data(): + from pathlib import Path + input_base_path = Path('..', '..', 'test', 'data') + test_files = [ + Path('input') / 'cthead1.png', + Path('input') / 'biorad.pic', + Path('input') / 'brainweb165a10f17.mha', + ] + data = {} + for f in test_files: + with open(input_base_path / f, 'rb') as fp: + data[str(f.name)] = fp.read() + return data \ No newline at end of file diff --git a/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/test_itkwasm_mesh_io.py b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/test_itkwasm_mesh_io.py new file mode 100644 index 000000000..094b4b8c9 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-emscripten/test/test_itkwasm_mesh_io.py @@ -0,0 +1,20 @@ +import pytest +import sys + +if sys.version_info < (3,10): + pytest.skip("Skipping pyodide tests on older Python", allow_module_level=True) + +from pytest_pyodide import run_in_pyodide + +from itkwasm_mesh_io_emscripten import __version__ as test_package_version + +@pytest.fixture +def package_wheel(): + return f"itkwasm_mesh_io_emscripten-{test_package_version}-py3-none-any.whl" + +@run_in_pyodide(packages=['micropip']) +async def test_example(selenium, package_wheel): + import micropip + await micropip.install(package_wheel) + + # Write your test code here diff --git a/packages/mesh-io/python/itkwasm-mesh-io-wasi/.gitignore b/packages/mesh-io/python/itkwasm-mesh-io-wasi/.gitignore new file mode 100644 index 000000000..123166809 --- /dev/null +++ b/packages/mesh-io/python/itkwasm-mesh-io-wasi/.gitignore @@ -0,0 +1 @@ +itkwasm_mesh_io_wasi/wasm_modules/