diff --git a/README.md b/README.md index 96394cb1e2457054e8e2018760eb1c701f015d0b..899f32e5c0c2b67774c6c36eb16211f12b15e698 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,10 @@ mstt包括精度工具(msprobe)和性能工具(msprof-analyze),分析 MindStudio一站式在线监控工具。 -## [Tensorboard](./plugins/tensorboard-plugins/tb_plugin) +## [Tensorboard](./plugins/tensorboard-plugins/tb_graph_ascend) +Tensorboard 支持模型结构进行分级可视化展示的插件 tb-graph-ascend。 -Tensorboard 支持 NPU 性能数据可视化插件 PyTorch Profiler TensorBoard NPU Plugin。 - -支持将 Ascend 平台采集、解析的 PyTorch Profiling 数据可视化呈现,也兼容 GPU 数据采集、解析可视化。 +可将模型的层级关系、精度数据进行可视化,并支持将调试模型和标杆模型进行分视图展示和关联比对,方便用户快速定位精度问题。 ## 分支维护策略 diff --git a/debug/accuracy_tools/msprobe/core/data_dump/data_collector.py b/debug/accuracy_tools/msprobe/core/data_dump/data_collector.py index 5a79ef34cb98c988b81c07f32216b4ba685557f2..42a8d8e9cf8d4813fdb58fc6ee6f533806f2dcdd 100644 --- a/debug/accuracy_tools/msprobe/core/data_dump/data_collector.py +++ b/debug/accuracy_tools/msprobe/core/data_dump/data_collector.py @@ -118,6 +118,7 @@ class DataCollector: self.set_is_recomputable(data_info, is_recompute) if self.config.level == Const.LEVEL_L2: return + self.call_stack_collect(name) self.handle_data(name, data_info, flush=self.data_processor.is_terminated) except Exception: @@ -139,7 +140,6 @@ class DataCollector: self.set_is_recomputable(data_info, is_recompute) if self.config.level == Const.LEVEL_L2: return - self.call_stack_collect(name) self.handle_data(name, data_info, flush=self.data_processor.is_terminated) except Exception: diff --git a/debug/accuracy_tools/msprobe/core/hook_manager.py b/debug/accuracy_tools/msprobe/core/hook_manager.py index fe256defcd997feed216147b22c60162612451c1..5226a7b2e222b03dfaef1cda52eb37363f049005 100644 --- a/debug/accuracy_tools/msprobe/core/hook_manager.py +++ b/debug/accuracy_tools/msprobe/core/hook_manager.py @@ -120,6 +120,8 @@ class BaseHookManager(ABC): def _should_execute_hook(self, hook_type, module, is_forward, tid): is_module_hook = hook_type == Const.MODULE + if hasattr(module, 'async_op_dump_flag') and getattr(module, 'async_op_dump_flag'): + return False if is_module_hook and not Runtime.is_running: return False elif not is_module_hook and is_forward and not Runtime.is_running: diff --git a/debug/accuracy_tools/msprobe/docs/01.installation.md b/debug/accuracy_tools/msprobe/docs/01.installation.md index 2610852e2c00c3f53635e9431e65ef6428e980d1..d247400026d57d9e86d4f877a170659a32739d58 100644 --- a/debug/accuracy_tools/msprobe/docs/01.installation.md +++ b/debug/accuracy_tools/msprobe/docs/01.installation.md @@ -38,8 +38,8 @@ sha256sum {name}.whl # 验证whl包,若校验码一致,则whl包在下载中 ```bash pip install ./mindstudio_probe-{version}-py3-none-any.whl # 安装whl包 ``` - -若覆盖安装,请在命令行末尾添加 `--force-reinstall` 参数。 +若覆盖安装,请在命令行末尾添加 `--force-reinstall` 参数。 +上面提供的whl包链接不包含adump功能,如果需要使用adump功能,请参考[从源码安装](#3-从源码安装)下载源码编译whl包。 ## 3 从源码安装 diff --git a/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md b/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md index db745f42058c00069057e010337cf7a4c55752f7..e152710cafd875951ed68e72d8f8aca1fdbb74e2 100644 --- a/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md +++ b/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md @@ -238,6 +238,8 @@ save(variable, name, save_backward=True) | name | 指定的名称 | str | 是 | | save_backward | 是否保存反向数据 | boolean | 否 | +具体使用样例可参考:[单点保存工具使用介绍](./28.debugger_save_instruction.md)。 + ### 1.10 set_init_step **功能说明**:设置起始step数,step数默认从0开始计数,使用该接口后step从指定值开始计数。该函数需要写在训练迭代的循环开始前,不能写在循环内。 diff --git a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md index 4019c87acfb516366d71ef7962e94e58139cfdf7..fa0a3e891a68c93d4f7add65e6d628d002198f27 100644 --- a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md +++ b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md @@ -153,6 +153,7 @@ save(variable, name, save_backward=True) | name | 指定的名称 | str | 是 | | save_backward | 是否保存反向数据 | boolean | 否 | +具体使用样例可参考:[单点保存工具使用介绍](./28.debugger_save_instruction.md)。 #### 6.1.6 set_init_step diff --git a/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md b/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md index db4b20d24e3100833625d74c853bf3bdca1709cb..3b85320fa35f7ce151889e14f9d2b934b725ffa5 100644 --- a/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md +++ b/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md @@ -79,12 +79,72 @@ for data, label in data_loader: ``` -调用保存接口 +调用保存接口示例(以PyTorch代码为例,MindSpore使用方法相同) ```python -# 训练过程中被调用py文件 +import torch +import torch.nn as nn +import torch.nn.functional as F + +from msprobe.pytorch import PrecisionDebugger, seed_all +# 在模型训练开始前实例化PrecisionDebugger +debugger = PrecisionDebugger(dump_path="dump_path", level="debug") + +# 定义网络 +class ModuleOP(nn.Module): + def __init__(self) -> None: + super().__init__() + self.linear_1 = nn.Linear(in_features=8, out_features=4) + self.linear_2 = nn.Linear(in_features=4, out_features=2) + + def forward(self, x): + x1 = self.linear_1(x) + x2 = self.linear_2(x1) + debugger.save(x2, "x2", save_backward=True) # 调用save接口 + r1 = F.relu(x2) + return r1 + +if __name__ == "__main__": + module = ModuleOP() + + x = torch.randn(10, 8) + out = module(x) + loss = out.sum() + loss.backward() +``` + +分step保存数据(以PyTorch代码为例,MindSpore使用方法相同) +```python +import torch +import torch.nn as nn +import torch.nn.functional as F + from msprobe.pytorch import PrecisionDebugger -dict_variable = {"key1": "value1", "key2": [1, 2]} -PrecisionDebugger.save(dict_variable, "dict_variable", save_backward=False) +# 在模型训练开始前实例化PrecisionDebugger +debugger = PrecisionDebugger(dump_path="dump_path", level="debug") + +# 定义网络 +class ModuleOP(nn.Module): + def __init__(self) -> None: + super().__init__() + self.linear_1 = nn.Linear(in_features=8, out_features=4) + self.linear_2 = nn.Linear(in_features=4, out_features=2) + + def forward(self, x): + x1 = self.linear_1(x) + x2 = self.linear_2(x1) + debugger.save(x2, "x2", save_backward=True) # 调用save接口 + r1 = F.relu(x2) + return r1 + +if __name__ == "__main__": + module = ModuleOP() + train_iter = 10 + for i in range(train_iter): + x = torch.randn(10, 8) + out = module(x) + loss = out.sum() + loss.backward() + debugger.step() # 调用debugger.step用于区分step保存 ``` diff --git a/debug/accuracy_tools/msprobe/mindspore/debugger/precision_debugger.py b/debug/accuracy_tools/msprobe/mindspore/debugger/precision_debugger.py index 6d7ee60b5c8969531084cfcdc1c2b4ecf9f08823..420f15470c4d1ac0d58e64f5e30c49fed0841ee7 100644 --- a/debug/accuracy_tools/msprobe/mindspore/debugger/precision_debugger.py +++ b/debug/accuracy_tools/msprobe/mindspore/debugger/precision_debugger.py @@ -87,7 +87,7 @@ class PrecisionDebugger(BasePrecisionDebugger): Runtime.step_count = 0 Runtime.is_running = False - if enable_dynamic_kbyk_dump: + if enable_dynamic_kbyk_dump and self.config.level_ori == Const.LEVEL_L2: _dump_set_dynamic() @staticmethod diff --git a/debug/accuracy_tools/msprobe/nan_analyze/graph.py b/debug/accuracy_tools/msprobe/nan_analyze/graph.py index 5a4f8fb87296a39796b5124854ba7060be71d53a..37989cfa67b7984f6e7af0ed4be23c835355cd0d 100644 --- a/debug/accuracy_tools/msprobe/nan_analyze/graph.py +++ b/debug/accuracy_tools/msprobe/nan_analyze/graph.py @@ -18,6 +18,7 @@ from msprobe.core.common.const import Const from msprobe.core.common.log import logger from msprobe.core.common.exceptions import MsprobeException from msprobe.nan_analyze.utils import FileCache, RankPath, is_ignore_op, check_item_anomaly, NanAnalyseConst +from msprobe.core.common.exceptions import MsprobeException @dataclass diff --git a/debug/accuracy_tools/msprobe/pytorch/hook_module/api_register.py b/debug/accuracy_tools/msprobe/pytorch/hook_module/api_register.py index 9bb4c3c8aafeb2984f8d4acfbdafd4b2fb929489..552a62a7a57562bb2fc3ca65a3748d3d59eb2a79 100644 --- a/debug/accuracy_tools/msprobe/pytorch/hook_module/api_register.py +++ b/debug/accuracy_tools/msprobe/pytorch/hook_module/api_register.py @@ -44,6 +44,8 @@ torch_version_above_2 = torch.__version__.split('+')[0] > '2.0' _inner_used_api = {} _supported_api_list_path = (os.path.join(os.path.dirname(os.path.realpath(__file__)), Const.SUPPORT_API_FILE_NAME),) _cuda_func_mapping = {"npu_fusion_attention": "gpu_fusion_attention"} +dist_data_collect_func = {} +origin_wait = getattr(dist.Work, 'wait') _api_types = { Const.PT_FRAMEWORK: { @@ -94,16 +96,35 @@ def dist_module_forward(module, *args, **kwargs): use_async_op_flag = False logger.warning(f"fail to get dist api's func signature because {e}, no wait") - if use_async_op_flag or module.api_name in ["isend", "irecv"]: - if handle and hasattr(handle, 'wait'): - handle.wait() - if module.api_name == "batch_isend_irecv": + def create_async_callback_func(catch_func): + def store_data(): + module.async_op_dump_flag = False + catch_func(module, args, kwargs, handle) + return store_data + + if len(module._forward_hooks.values()) == 0: + return handle + if use_async_op_flag or module.api_name in ['isend', 'irecv']: + module.async_op_dump_flag = True + dist_data_collect_func[handle] = create_async_callback_func(list(module._forward_hooks.values())[0]) + if module.api_name == 'batch_isend_irecv': if isinstance(handle, list): for req in handle: - req.wait() + dist_data_collect_func[req] = create_async_callback_func(list(module._forward_hooks.values())[0]) return handle +def redirect_wait(): + def wrapped_wait(work): + def wrapped_wait(*args, **kwargs): + origin_wait(*args, **kwargs) + if args[0] in dist_data_collect_func: + store_func = dist_data_collect_func.pop(args[0]) + store_func() + return wrapped_wait + dist.Work.wait = wrapped_wait(dist.Work) + + def npu_module_forward(module, *args, **kwargs): if not module.need_hook: if module.api_name not in npu_custom_functions: @@ -130,6 +151,7 @@ class ApiTemplate(HOOKModule): self.prefix_api_name = prefix + Const.SEP + str(api_name.split(Const.SEP)[-1]) + Const.SEP self.need_hook = need_hook self.device = device + self.async_op_dump_flag = False if self.need_hook: super().__init__(hook_build_func) if prefix == Const.DIST_API_TYPE_PREFIX: diff --git a/debug/accuracy_tools/msprobe/pytorch/pytorch_service.py b/debug/accuracy_tools/msprobe/pytorch/pytorch_service.py index aad49a90d95ae7bccc56576f8c34a98de7f55ca6..1368e4341d20f26933aabc1fa4b915fe0f9b60ea 100644 --- a/debug/accuracy_tools/msprobe/pytorch/pytorch_service.py +++ b/debug/accuracy_tools/msprobe/pytorch/pytorch_service.py @@ -19,7 +19,7 @@ from msprobe.pytorch.attl_manager import ATTLManager from msprobe.pytorch.common.log import logger from msprobe.pytorch.common.utils import get_rank_if_initialized, torch_version_above_or_equal_2 from msprobe.pytorch.dump.module_dump.module_processer import ModuleProcesser -from msprobe.pytorch.hook_module.api_register import get_api_register, ApiTemplate +from msprobe.pytorch.hook_module.api_register import get_api_register, ApiTemplate, redirect_wait from msprobe.pytorch.hook_module.hook_module import HOOKModule from msprobe.pytorch.hook_module.jit_script_wrapper import wrap_jit_script_func from msprobe.pytorch.hook_module.pt_hook_manager import PytorchHookManager @@ -57,6 +57,7 @@ class PytorchService(BaseService): def _register_api_hook(self): super()._register_api_hook() wrap_jit_script_func() + redirect_wait() def _register_module_hook(self): ModuleProcesser.enable_module_dump = True diff --git a/debug/accuracy_tools/msprobe/test/core_ut/data_dump/test_data_collector.py b/debug/accuracy_tools/msprobe/test/core_ut/data_dump/test_data_collector.py index b93a122ac6d57a848ac27bce449a78f41c48ba22..67ea481a9b6c983c29f80913820deb07e0b2219c 100644 --- a/debug/accuracy_tools/msprobe/test/core_ut/data_dump/test_data_collector.py +++ b/debug/accuracy_tools/msprobe/test/core_ut/data_dump/test_data_collector.py @@ -384,7 +384,6 @@ class TestForwardDataCollect(unittest.TestCase): mock_data = {"key": "value"} self.data_collector.data_processor.analyze_forward_output.return_value = mock_data self.data_collector.forward_output_data_collect("test", "module", 123, "data", True) - self.data_collector.call_stack_collect.assert_called_once_with("test") self.data_collector.handle_data.assert_called_once_with( "test", mock_data, diff --git a/debug/accuracy_tools/msprobe/test/core_ut/test_hook_manager.py b/debug/accuracy_tools/msprobe/test/core_ut/test_hook_manager.py index f03a7d889645539d8a935454a6033aae23e62d0e..acab05db44dc02c3626fb69569ed1385f8ceaf17 100644 --- a/debug/accuracy_tools/msprobe/test/core_ut/test_hook_manager.py +++ b/debug/accuracy_tools/msprobe/test/core_ut/test_hook_manager.py @@ -73,6 +73,7 @@ class TestBaseHookManager(unittest.TestCase): def test_should_execute_hook_conditions(self): module = MagicMock() module.forward_data_collected = True + module.async_op_dump_flag = False Runtime.is_running = True self.mock_data_collector.data_processor.is_terminated = False self.assertTrue(self.manager._should_execute_hook(Const.MODULE, module, True, threading.get_ident())) diff --git a/debug/accuracy_tools/msprobe/test/pytorch_ut/hook_module/test_pt_api_register.py b/debug/accuracy_tools/msprobe/test/pytorch_ut/hook_module/test_pt_api_register.py index bb2091c342b7d2036a96c1ccabeb1f81a49b65b2..da6e21049bf76e0389795aa816dbee8218bc87be 100644 --- a/debug/accuracy_tools/msprobe/test/pytorch_ut/hook_module/test_pt_api_register.py +++ b/debug/accuracy_tools/msprobe/test/pytorch_ut/hook_module/test_pt_api_register.py @@ -53,18 +53,6 @@ class TestAPIRegister(unittest.TestCase): self.assertEqual(result, "test_handle") mock_logger.assert_not_called() - def test_dist_module_forward_with_batch_op(self): - mock_reqs = [MagicMock(), MagicMock()] - mock_module = MagicMock() - mock_module.api_func.return_value = mock_reqs - mock_module.api_name = "batch_isend_irecv" - - result = dist_module_forward(mock_module) - - for req in mock_reqs: - req.wait.assert_called_once() - self.assertEqual(result, mock_reqs) - @patch('msprobe.pytorch.hook_module.api_register.ApiRegistry') def test_get_api_register_with_new_obj(self, mock_api_registry): get_api_register(return_new=True) diff --git a/msmonitor/dynolog_npu/cli/Cargo.toml b/msmonitor/dynolog_npu/cli/Cargo.toml index 2f9703700622a0c31750ee900d2922efa4663ed8..65b8d94af52eaa9188ad107732060c4e6e727f0f 100644 --- a/msmonitor/dynolog_npu/cli/Cargo.toml +++ b/msmonitor/dynolog_npu/cli/Cargo.toml @@ -17,4 +17,3 @@ chrono = "0.4" num-bigint = "0.4" openssl = { version = "0.10", features = ["vendored"] } rpassword = "7.2.0" - diff --git a/msmonitor/dynolog_npu/cli/src/main.rs b/msmonitor/dynolog_npu/cli/src/main.rs index d1dd1dd4919b25362948c05be0a2a55e6f2cc617..7ee9d1be02657e711a2984c3a69ca78b02b34845 100644 --- a/msmonitor/dynolog_npu/cli/src/main.rs +++ b/msmonitor/dynolog_npu/cli/src/main.rs @@ -518,6 +518,20 @@ fn create_dyno_client_with_no_certs( Ok(DynoClient::Insecure(stream)) } +// 安全清除密码的函数 +fn secure_clear_password(password: &mut Vec) { + if !password.is_empty() { + // 使用零覆盖密码数据 + for byte in password.iter_mut() { + *byte = 0; + } + // 清空向量 + password.clear(); + // 收缩向量容量,释放内存 + password.shrink_to_fit(); + } +} + fn create_dyno_client_with_certs( host: &str, port: u16, @@ -597,12 +611,12 @@ fn create_dyno_client_with_certs( // 根据是否加密来加载私钥 let keys = if is_encrypted { // 如果私钥是加密的,请求用户输入密码 - let mut password = prompt_password("Please enter the certificate password: ")?; - let pkey = PKey::private_key_from_pem_passphrase(&key_data, password.as_bytes()) + let mut password = prompt_password("Please enter the certificate password: ")?.into_bytes(); + let pkey = PKey::private_key_from_pem_passphrase(&key_data, &password) .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("Failed to decrypt private key: {}", e)))?; - // 清除密码 - password.clear(); + // 手动清除密码 + secure_clear_password(&mut password); // 返回私钥 vec![pkey.private_key_to_der() diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/README.md b/plugins/tensorboard-plugins/tb_graph_ascend/README.md index 3c92c12c2453da71aad14988719d63c326f5d354..737292598ecfdf0fb39d676ce3352fb4b246076e 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/README.md +++ b/plugins/tensorboard-plugins/tb_graph_ascend/README.md @@ -121,7 +121,10 @@ ![输入图片说明](./doc/images/vis_unmatch_info.png) ### 3.6 手动选择节点匹配 可通过浏览器界面,通过鼠标选择两个待匹配的灰色节点进行匹配。当前暂不支持真实数据模式。
-点击匹配后会将两个节点的子节点按照Module名称依次匹配,取消匹配后会将子节点的匹配关系清除。
+如果选中"操作选中节点及其子节点":
+点击匹配后会将两个节点及其子节点按照Module名称依次匹配,取消匹配后会将子节点的匹配关系清除。
+否则:
+点击匹配后只会将两个节点进行匹配,取消匹配后会将节点的匹配关系清除 注意:匹配结束之后,需要点击保存才能持久化到源文件里面 ![输入图片说明](./doc/images/vis_match_info.png) @@ -140,6 +143,10 @@ #### 4.1.1 免责声明 本工具为基于 TensorBoard 底座开发的插件,使用本插件需要基于 TensorBoard 运行,请自行关注 TensorBoard 相关安全配置和安全风险。 + +打开本工具时,本工具会对logdir目录下的vis文件以及其父目录进行安全检查,如果存在安全风险,本工具会展示如下提示信息,询问用户是否继续执行,用户选择继续执行后,可以操作未通过安全检查的文件和目录,用户需要自行承担操作风险。如果用户选择不继续执行,则用户只能操作通过安全检查的文件。 + +![输入图片说明](./doc/images/saFe_warning.png) #### 4.1.2 TensorBoard版本说明 满足[相关依赖](#1-相关依赖)中要求的 TensorBoard 版本皆可正常使用本插件功能,但为 TensorBoard 本身安全风险考虑,建议使用最新版本 TensorBoard 。 #### 4.1.3 远程查看数据 diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/safe_warning.png b/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/safe_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..15b14eab1fd7a5710cc540e1126c346f5291fb8a Binary files /dev/null and b/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/safe_warning.png differ diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/vis_match_info.png b/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/vis_match_info.png index 71e7d74991303036f02529c47dee545022647379..5785c81a2f308a4fb87db1c8528262e3b1821932 100644 Binary files a/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/vis_match_info.png and b/plugins/tensorboard-plugins/tb_graph_ascend/doc/images/vis_match_info.png differ diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/fe/package-lock.json b/plugins/tensorboard-plugins/tb_graph_ascend/fe/package-lock.json index 15f1931fe9b6ac4de59e7abf2ef953aac12ab9ed..bf84218031fe0e5fc1de5fd7f2ea4d1ffebda948 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/fe/package-lock.json +++ b/plugins/tensorboard-plugins/tb_graph_ascend/fe/package-lock.json @@ -29,7 +29,9 @@ "@polymer/polymer": "^3.5.1", "@types/lodash": "^4.17.1", "@vaadin/button": "24.6.5", + "@vaadin/checkbox": "24.6.5", "@vaadin/combo-box": "24.6.5", + "@vaadin/confirm-dialog": "24.6.5", "@vaadin/context-menu": "24.6.5", "@vaadin/details": "24.6.5", "@vaadin/grid": "24.6.5", @@ -1217,14 +1219,14 @@ } }, "node_modules/@vaadin/a11y-base": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/a11y-base/-/a11y-base-24.6.7.tgz", - "integrity": "sha512-CJYYTWPBEEaVt4AvBE8RzEn3hqUZbGUGLzqs6NGBFTw0c5cfkqoO2ZMkKhz5Z52QF+2mCXpEtyg6s+t0h171Qg==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/a11y-base/-/a11y-base-24.6.11.tgz", + "integrity": "sha512-yBZ0QGPngbItIJQx3FRIa9IXDW2Ftf6SFFPGhbdAZafJPBlFi6FElP9cVtL3qjJlI5KKBp/UXEcC8ehPK207gw==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.6.7", + "@vaadin/component-base": "~24.6.11", "lit": "^3.0.0" } }, @@ -1245,19 +1247,19 @@ } }, "node_modules/@vaadin/checkbox": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/checkbox/-/checkbox-24.6.7.tgz", - "integrity": "sha512-/Vl5codokNdN5ku1l/iAkdjUmYTUZGKyAleHjM7V3ZFpwkK2IoWN4HrbWyhPuf1gL3T85bKMLSPuYoOX/ymrFw==", + "version": "24.6.5", + "resolved": "https://registry.npmmirror.com/@vaadin/checkbox/-/checkbox-24.6.5.tgz", + "integrity": "sha512-XYhiEr9PMnonyMot7y8PIK/9GlNNCxupFg7ZFsrGvsDpfD5fCfpsnv+c3kUwVN6yFze3NVQEXOyp/UGoZNoNmQ==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.6.7", - "@vaadin/component-base": "~24.6.7", - "@vaadin/field-base": "~24.6.7", - "@vaadin/vaadin-lumo-styles": "~24.6.7", - "@vaadin/vaadin-material-styles": "~24.6.7", - "@vaadin/vaadin-themable-mixin": "~24.6.7", + "@vaadin/a11y-base": "~24.6.5", + "@vaadin/component-base": "~24.6.5", + "@vaadin/field-base": "~24.6.5", + "@vaadin/vaadin-lumo-styles": "~24.6.5", + "@vaadin/vaadin-material-styles": "~24.6.5", + "@vaadin/vaadin-themable-mixin": "~24.6.5", "lit": "^3.0.0" } }, @@ -1283,9 +1285,9 @@ } }, "node_modules/@vaadin/component-base": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/component-base/-/component-base-24.6.7.tgz", - "integrity": "sha512-LcZQZEwouPDHBoXfXRREb1mRScsPSPeKTUZdgrXh180Piy57VzpNzslIMrdfVFSye9lLMs2/g2o8HCUDgnY/OQ==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/component-base/-/component-base-24.6.11.tgz", + "integrity": "sha512-7jR6vcJeCBgY2CNbAPLOcUTsxYspqdkA0slUGk3GwfgsRDD5FLkzqQDSM5+yE6O2+4Wah2Tk+kG/GsKGtlUlwg==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -1295,6 +1297,24 @@ "lit": "^3.0.0" } }, + "node_modules/@vaadin/confirm-dialog": { + "version": "24.6.5", + "resolved": "https://registry.npmmirror.com/@vaadin/confirm-dialog/-/confirm-dialog-24.6.5.tgz", + "integrity": "sha512-YkEFCj4psD/+K50fpqoJIUYRvdyzoRfWdC3ZDaDcliWND7m50cNZBxj1psZ+iOP32MVK+4Ke16fFbEY0tKoyWg==", + "license": "Apache-2.0", + "dependencies": { + "@open-wc/dedupe-mixin": "^1.3.0", + "@polymer/polymer": "^3.0.0", + "@vaadin/button": "~24.6.5", + "@vaadin/component-base": "~24.6.5", + "@vaadin/dialog": "~24.6.5", + "@vaadin/overlay": "~24.6.5", + "@vaadin/vaadin-lumo-styles": "~24.6.5", + "@vaadin/vaadin-material-styles": "~24.6.5", + "@vaadin/vaadin-themable-mixin": "~24.6.5", + "lit": "^3.0.0" + } + }, "node_modules/@vaadin/context-menu": { "version": "24.6.5", "resolved": "https://registry.npmmirror.com/@vaadin/context-menu/-/context-menu-24.6.5.tgz", @@ -1332,16 +1352,33 @@ "lit": "^3.0.0" } }, + "node_modules/@vaadin/dialog": { + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/dialog/-/dialog-24.6.11.tgz", + "integrity": "sha512-EWMkf8yH6sFEG4e9zTpPW20sL8vTz5TpBvJmD4rUUqvxEphHCUI+uO0N05/XFa2k7xZS6q8G38hc1BcCYr5Syw==", + "license": "Apache-2.0", + "dependencies": { + "@open-wc/dedupe-mixin": "^1.3.0", + "@polymer/polymer": "^3.0.0", + "@vaadin/component-base": "~24.6.11", + "@vaadin/lit-renderer": "~24.6.11", + "@vaadin/overlay": "~24.6.11", + "@vaadin/vaadin-lumo-styles": "~24.6.11", + "@vaadin/vaadin-material-styles": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11", + "lit": "^3.0.0" + } + }, "node_modules/@vaadin/field-base": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/field-base/-/field-base-24.6.7.tgz", - "integrity": "sha512-5MXpAQGZA15/hRdnZrJK5q5Mv8rgOraSyBpC/gjRJ1W1IQ5DrCcb3ltvPATguv0K3vpJwunXGXrGqm/+SGEk0w==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/field-base/-/field-base-24.6.11.tgz", + "integrity": "sha512-dRjxKzbW3xQAau1xuO8uZepVWaImS2wEyKDK9Oh+y8iiu4smYEmo9e4aqMqQN/sOHU6OSa4YtbyJZlvD1sBXrA==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.6.7", - "@vaadin/component-base": "~24.6.7", + "@vaadin/a11y-base": "~24.6.11", + "@vaadin/component-base": "~24.6.11", "lit": "^3.0.0" } }, @@ -1364,6 +1401,23 @@ "lit": "^3.0.0" } }, + "node_modules/@vaadin/grid/node_modules/@vaadin/checkbox": { + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/checkbox/-/checkbox-24.6.11.tgz", + "integrity": "sha512-Uvd6gZ3xQQrZTtCJL6f4uLbg6mXsAKjiZto7Je39yJwUHz8r5MIQr+4mLF4zc6mYVSH/Ihj/a4n9FOuTwSEuQw==", + "license": "Apache-2.0", + "dependencies": { + "@open-wc/dedupe-mixin": "^1.3.0", + "@polymer/polymer": "^3.0.0", + "@vaadin/a11y-base": "~24.6.11", + "@vaadin/component-base": "~24.6.11", + "@vaadin/field-base": "~24.6.11", + "@vaadin/vaadin-lumo-styles": "~24.6.11", + "@vaadin/vaadin-material-styles": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11", + "lit": "^3.0.0" + } + }, "node_modules/@vaadin/icon": { "version": "24.6.5", "resolved": "https://registry.npmmirror.com/@vaadin/icon/-/icon-24.6.5.tgz", @@ -1436,9 +1490,9 @@ } }, "node_modules/@vaadin/lit-renderer": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/lit-renderer/-/lit-renderer-24.6.7.tgz", - "integrity": "sha512-S9daJnGW/X+HBhOriENRYNf8hCFYABmea756onaLS0QoWLkaU3QVPKrhHjZtzNVf/15UcIeAx4C5JlIas2osFA==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/lit-renderer/-/lit-renderer-24.6.11.tgz", + "integrity": "sha512-JugFumbBQP4r28+HcbdDUVVGs5VRsqanLsifjkVrz/xb4saWv460lEYco5ES+StH+xZ2IuJZmEjEFUBSrVR/tA==", "license": "Apache-2.0", "dependencies": { "lit": "^3.0.0" @@ -1462,18 +1516,18 @@ } }, "node_modules/@vaadin/overlay": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/overlay/-/overlay-24.6.7.tgz", - "integrity": "sha512-3HZ2+Ld/ktOzFt3Ug3EoZeMqX//uKh9rsXd1d3lQl18bwVtSvG81lY7NI6tEQ2dSuniM0yy2tM+mVnV4lZq9Gw==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/overlay/-/overlay-24.6.11.tgz", + "integrity": "sha512-RrN16YWKpg2pxAu6RxlUxBbovf+1+RYRmVvUk0WKBuaA4EBli0mN1vkZbK0XEsPvC2bGHPMWWqwmUzaIXv+1bw==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.6.7", - "@vaadin/component-base": "~24.6.7", - "@vaadin/vaadin-lumo-styles": "~24.6.7", - "@vaadin/vaadin-material-styles": "~24.6.7", - "@vaadin/vaadin-themable-mixin": "~24.6.7", + "@vaadin/a11y-base": "~24.6.11", + "@vaadin/component-base": "~24.6.11", + "@vaadin/vaadin-lumo-styles": "~24.6.11", + "@vaadin/vaadin-material-styles": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11", "lit": "^3.0.0" } }, @@ -1625,46 +1679,46 @@ "license": "Apache-2.0" }, "node_modules/@vaadin/vaadin-lumo-styles": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.6.7.tgz", - "integrity": "sha512-DNamU8cVxbaVn3HfRm3pN8ul95xvaem92ByVeEQwdvKaHwLI4m7AdSWKEA+13ST9TdBtCeDW6DjmtGcoEqbqiw==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.6.11.tgz", + "integrity": "sha512-WRluczao8lZgImdtl66v09YjFULb1iLAhcU48aiR9igAT7h6aLeHYBvRH3AA/gBlUNwHd4xlBSl89p4HP2GGog==", "license": "Apache-2.0", "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.6.7", - "@vaadin/icon": "~24.6.7", - "@vaadin/vaadin-themable-mixin": "~24.6.7" + "@vaadin/component-base": "~24.6.11", + "@vaadin/icon": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11" } }, "node_modules/@vaadin/vaadin-lumo-styles/node_modules/@vaadin/icon": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/icon/-/icon-24.6.7.tgz", - "integrity": "sha512-+Cv3hLyFSXJAhnuGuPQ+hQcv9/ijZpIprJ6rqWeChvFk+bQOoPgUPx/tj67mOiTcrmV5hYt+dYs4QM7JZ//dGg==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/icon/-/icon-24.6.11.tgz", + "integrity": "sha512-CKOh+I84+GZRfMHrhtATtrw3bSW5eUArgGT4cKsOY3asoCZXUdTObPD/PqKfP4e2uAA1bgLl27kOc+W8dmibJA==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.6.7", - "@vaadin/vaadin-lumo-styles": "~24.6.7", - "@vaadin/vaadin-themable-mixin": "~24.6.7", + "@vaadin/component-base": "~24.6.11", + "@vaadin/vaadin-lumo-styles": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11", "lit": "^3.0.0" } }, "node_modules/@vaadin/vaadin-material-styles": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.6.7.tgz", - "integrity": "sha512-7ecHOEZrFEbUz5UVSGapOt/uC7lSYV05RADCNhG16c+WsuN+oxkGIIaThMMCdBcclg5ej/BeTxZlZha8JoNO3g==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.6.11.tgz", + "integrity": "sha512-tDumwlaDp/s9u++MPi64I1o2ls/drWOZf4xVPhztUjt3NwYJUeVXtwu39q0wBRIeRM7UBrs06kug2CVT72U4qQ==", "license": "Apache-2.0", "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.6.7", - "@vaadin/vaadin-themable-mixin": "~24.6.7" + "@vaadin/component-base": "~24.6.11", + "@vaadin/vaadin-themable-mixin": "~24.6.11" } }, "node_modules/@vaadin/vaadin-themable-mixin": { - "version": "24.6.7", - "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.6.7.tgz", - "integrity": "sha512-fiVBvJWInNBq/oXeE0UAQmzadQ7UJE3ns768D1taKOwTMOxiio1UMoUXcVGwni9ASzXrd96S7F6c4aIaVqNx6A==", + "version": "24.6.11", + "resolved": "https://registry.npmmirror.com/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.6.11.tgz", + "integrity": "sha512-xCmn3X+2C7nI9LQn2OqLLkLw7VeJOCo99DlHwnxeLZpJJ/s8bjDXcIWflS+IOChzHixgEFkDSoLcNYoCR1RvYg==", "license": "Apache-2.0", "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -6569,4 +6623,4 @@ } } } -} \ No newline at end of file +} diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/fe/package.json b/plugins/tensorboard-plugins/tb_graph_ascend/fe/package.json index d5bf7321825ef2b085828176392addd974620162..fb9c1d48f45c89c57c4c9bc821db640bfc328178 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/fe/package.json +++ b/plugins/tensorboard-plugins/tb_graph_ascend/fe/package.json @@ -50,7 +50,9 @@ "@polymer/polymer": "^3.5.1", "@types/lodash": "^4.17.1", "@vaadin/button": "24.6.5", + "@vaadin/checkbox": "24.6.5", "@vaadin/combo-box": "24.6.5", + "@vaadin/confirm-dialog": "24.6.5", "@vaadin/context-menu": "24.6.5", "@vaadin/details": "24.6.5", "@vaadin/grid": "24.6.5", @@ -73,4 +75,4 @@ "prettier": "^3.4.2", "style-loader": "^4.0.0" } -} +} \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/graph_ascend/index.ts b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/graph_ascend/index.ts index 8a3cff935c05614cd66ba101409e7ee05823be01..a0f6a8653759ee8b210a4b4c1255f8f0fbfb5555 100644 --- a/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/graph_ascend/index.ts +++ b/plugins/tensorboard-plugins/tb_graph_ascend/fe/src/graph_ascend/index.ts @@ -17,12 +17,17 @@ import { customElement, observe, property } from '@polymer/decorators'; import { html, PolymerElement } from '@polymer/polymer'; import { LegacyElementMixin } from '../polymer/legacy_element_mixin'; +import { LoadGraphFileInfoListType } from './type'; import useGraphAscend from './useGraphAscend'; import { formatBytes, safeJSONParse } from '../utils'; +import { isEmpty } from 'lodash'; import '../graph_board/index'; import '../graph_info_board/index'; import '../graph_controls_board/index'; import '../common/graph-board-layout'; +import '@vaadin/confirm-dialog' +import { Notification } from '@vaadin/notification'; + import type { SelectionType, ProgressType, GraphConfigType, GraphAllNodeType, NodeListType, UnmatchedNodeType } from './type'; @customElement('graph-ascend') @@ -82,7 +87,26 @@ class TfGraphDashboard extends LegacyElementMixin(PolymerElement) { - + +
+

如果您仍坚持继续,请知悉以下风险:

+
非授权路径访问可能存在信息泄露和文件内容篡改。 文件过大或格式异常,可能导致性能问题或服务中断。路径中存在软链接或权限不当,可能存在越权访问和数据篡改风险。
+

继续操作将由您自行承担相关后果。如非明确知晓风险,请取消操作并联系管理员处理。

+
+ +
+
+
- - - - - - - diff --git a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_script.js b/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_script.js deleted file mode 100644 index 039aef359e030dbace4161538dd1191cc6fa1ab9..0000000000000000000000000000000000000000 --- a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_script.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ -// @version 0.7.24 -!function () { window.WebComponents = window.WebComponents || { flags: {} }; var e = "webcomponents.js", t = document.querySelector('script[src*="' + e + '"]'), n = {}; if (!n.noOpts) { if (location.search.slice(1).split("&").forEach(function (e) { var t, r = e.split("="); r[0] && (t = r[0].match(/wc-(.+)/)) && (n[t[1]] = r[1] || !0) }), t) for (var r, o = 0; r = t.attributes[o]; o++)"src" !== r.name && (n[r.name] = r.value || !0); if (n.log && n.log.split) { var i = n.log.split(","); n.log = {}, i.forEach(function (e) { n.log[e] = !0 }) } else n.log = {} } n.shadow = n.shadow || n.shadowdom || n.polyfill, "native" === n.shadow ? n.shadow = !1 : n.shadow = n.shadow || !HTMLElement.prototype.createShadowRoot, n.register && (window.CustomElements = window.CustomElements || { flags: {} }, window.CustomElements.flags.register = n.register), WebComponents.flags = n }(), WebComponents.flags.shadow && ("undefined" == typeof WeakMap && !function () { var e = Object.defineProperty, t = Date.now() % 1e9, n = function () { this.name = "__st" + (1e9 * Math.random() >>> 0) + (t++ + "__") }; n.prototype = { set: function (t, n) { var r = t[this.name]; return r && r[0] === t ? r[1] = n : e(t, this.name, { value: [t, n], writable: !0 }), this }, get: function (e) { var t; return (t = e[this.name]) && t[0] === e ? t[1] : void 0 }, "delete": function (e) { var t = e[this.name]; return !(!t || t[0] !== e) && (t[0] = t[1] = void 0, !0) }, has: function (e) { var t = e[this.name]; return !!t && t[0] === e } }, window.WeakMap = n }(), window.ShadowDOMPolyfill = {}, function (e) { "use strict"; function t() { if ("undefined" != typeof chrome && chrome.app && chrome.app.runtime) return !1; if (navigator.getDeviceStorage) return !1; try { var e = new Function("return true;"); return e() } catch (t) { return !1 } } function n(e) { if (!e) throw new Error("Assertion failed") } function r(e, t) { for (var n = W(t), r = 0; r < n.length; r++) { var o = n[r]; A(e, o, F(t, o)) } return e } function o(e, t) { for (var n = W(t), r = 0; r < n.length; r++) { var o = n[r]; switch (o) { case "arguments": case "caller": case "length": case "name": case "prototype": case "toString": continue }A(e, o, F(t, o)) } return e } function i(e, t) { for (var n = 0; n < t.length; n++)if (t[n] in e) return t[n] } function a(e, t, n) { U.value = n, A(e, t, U) } function s(e, t) { var n = e.__proto__ || Object.getPrototypeOf(e); if (q) try { W(n) } catch (r) { n = n.__proto__ } var o = R.get(n); if (o) return o; var i = s(n), a = E(i); return g(n, a, t), a } function c(e, t) { w(e, t, !0) } function l(e, t) { w(t, e, !1) } function u(e) { return /^on[a-z]+$/.test(e) } function d(e) { return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(e) } function p(e) { return k && d(e) ? new Function("return this.__impl4cf1e782hg__." + e) : function () { return this.__impl4cf1e782hg__[e] } } function h(e) { return k && d(e) ? new Function("v", "this.__impl4cf1e782hg__." + e + " = v") : function (t) { this.__impl4cf1e782hg__[e] = t } } function f(e) { return k && d(e) ? new Function("return this.__impl4cf1e782hg__." + e + ".apply(this.__impl4cf1e782hg__, arguments)") : function () { return this.__impl4cf1e782hg__[e].apply(this.__impl4cf1e782hg__, arguments) } } function m(e, t) { try { return e === window && "showModalDialog" === t ? B : Object.getOwnPropertyDescriptor(e, t) } catch (n) { return B } } function w(t, n, r, o) { for (var i = W(t), a = 0; a < i.length; a++) { var s = i[a]; if ("polymerBlackList_" !== s && !(s in n || t.polymerBlackList_ && t.polymerBlackList_[s])) { q && t.__lookupGetter__(s); var c, l, d = m(t, s); if ("function" != typeof d.value) { var w = u(s); c = w ? e.getEventHandlerGetter(s) : p(s), (d.writable || d.set || V) && (l = w ? e.getEventHandlerSetter(s) : h(s)); var v = V || d.configurable; A(n, s, { get: c, set: l, configurable: v, enumerable: d.enumerable }) } else r && (n[s] = f(s)) } } } function v(e, t, n) { if (null != e) { var r = e.prototype; g(r, t, n), o(t, e) } } function g(e, t, r) { var o = t.prototype; n(void 0 === R.get(e)), R.set(e, t), I.set(o, e), c(e, o), r && l(o, r), a(o, "constructor", t), t.prototype = o } function b(e, t) { return R.get(t.prototype) === e } function y(e) { var t = Object.getPrototypeOf(e), n = s(t), r = E(n); return g(t, r, e), r } function E(e) { function t(t) { e.call(this, t) } var n = Object.create(e.prototype); return n.constructor = t, t.prototype = n, t } function _(e) { return e && e.__impl4cf1e782hg__ } function S(e) { return !_(e) } function T(e) { if (null === e) return null; n(S(e)); var t = e.__wrapper8e3dd93a60__; return null != t ? t : e.__wrapper8e3dd93a60__ = new (s(e, e))(e) } function M(e) { return null === e ? null : (n(_(e)), e.__impl4cf1e782hg__) } function O(e) { return e.__impl4cf1e782hg__ } function L(e, t) { t.__impl4cf1e782hg__ = e, e.__wrapper8e3dd93a60__ = t } function N(e) { return e && _(e) ? M(e) : e } function C(e) { return e && !_(e) ? T(e) : e } function j(e, t) { null !== t && (n(S(e)), n(void 0 === t || _(t)), e.__wrapper8e3dd93a60__ = t) } function D(e, t, n) { G.get = n, A(e.prototype, t, G) } function H(e, t) { D(e, t, function () { return T(this.__impl4cf1e782hg__[t]) }) } function x(e, t) { e.forEach(function (e) { t.forEach(function (t) { e.prototype[t] = function () { var e = C(this); return e[t].apply(e, arguments) } }) }) } var R = new WeakMap, I = new WeakMap, P = Object.create(null), k = t(), A = Object.defineProperty, W = Object.getOwnPropertyNames, F = Object.getOwnPropertyDescriptor, U = { value: void 0, configurable: !0, enumerable: !1, writable: !0 }; W(window); var q = /Firefox/.test(navigator.userAgent), B = { get: function () { }, set: function (e) { }, configurable: !0, enumerable: !0 }, V = function () { var e = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType"); return e && !e.get && !e.set }(), G = { get: void 0, configurable: !0, enumerable: !0 }; e.addForwardingProperties = c, e.assert = n, e.constructorTable = R, e.defineGetter = D, e.defineWrapGetter = H, e.forwardMethodsToWrapper = x, e.isIdentifierName = d, e.isWrapper = _, e.isWrapperFor = b, e.mixin = r, e.nativePrototypeTable = I, e.oneOf = i, e.registerObject = y, e.registerWrapper = v, e.rewrap = j, e.setWrapper = L, e.unsafeUnwrap = O, e.unwrap = M, e.unwrapIfNeeded = N, e.wrap = T, e.wrapIfNeeded = C, e.wrappers = P }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e, t, n) { return { index: e, removed: t, addedCount: n } } function n() { } var r = 0, o = 1, i = 2, a = 3; n.prototype = { calcEditDistances: function (e, t, n, r, o, i) { for (var a = i - o + 1, s = n - t + 1, c = new Array(a), l = 0; l < a; l++)c[l] = new Array(s), c[l][0] = l; for (var u = 0; u < s; u++)c[0][u] = u; for (var l = 1; l < a; l++)for (var u = 1; u < s; u++)if (this.equals(e[t + u - 1], r[o + l - 1])) c[l][u] = c[l - 1][u - 1]; else { var d = c[l - 1][u] + 1, p = c[l][u - 1] + 1; c[l][u] = d < p ? d : p } return c }, spliceOperationsFromEditDistances: function (e) { for (var t = e.length - 1, n = e[0].length - 1, s = e[t][n], c = []; t > 0 || n > 0;)if (0 != t) if (0 != n) { var l, u = e[t - 1][n - 1], d = e[t - 1][n], p = e[t][n - 1]; l = d < p ? d < u ? d : u : p < u ? p : u, l == u ? (u == s ? c.push(r) : (c.push(o), s = u), t--, n--) : l == d ? (c.push(a), t--, s = d) : (c.push(i), n--, s = p) } else c.push(a), t--; else c.push(i), n--; return c.reverse(), c }, calcSplices: function (e, n, s, c, l, u) { var d = 0, p = 0, h = Math.min(s - n, u - l); if (0 == n && 0 == l && (d = this.sharedPrefix(e, c, h)), s == e.length && u == c.length && (p = this.sharedSuffix(e, c, h - d)), n += d, l += d, s -= p, u -= p, s - n == 0 && u - l == 0) return []; if (n == s) { for (var f = t(n, [], 0); l < u;)f.removed.push(c[l++]); return [f] } if (l == u) return [t(n, [], s - n)]; for (var m = this.spliceOperationsFromEditDistances(this.calcEditDistances(e, n, s, c, l, u)), f = void 0, w = [], v = n, g = l, b = 0; b < m.length; b++)switch (m[b]) { case r: f && (w.push(f), f = void 0), v++, g++; break; case o: f || (f = t(v, [], 0)), f.addedCount++, v++, f.removed.push(c[g]), g++; break; case i: f || (f = t(v, [], 0)), f.addedCount++, v++; break; case a: f || (f = t(v, [], 0)), f.removed.push(c[g]), g++ }return f && w.push(f), w }, sharedPrefix: function (e, t, n) { for (var r = 0; r < n; r++)if (!this.equals(e[r], t[r])) return r; return n }, sharedSuffix: function (e, t, n) { for (var r = e.length, o = t.length, i = 0; i < n && this.equals(e[--r], t[--o]);)i++; return i }, calculateSplices: function (e, t) { return this.calcSplices(e, 0, e.length, t, 0, t.length) }, equals: function (e, t) { return e === t } }, e.ArraySplice = n }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t() { a = !1; var e = i.slice(0); i = []; for (var t = 0; t < e.length; t++)(0, e[t])() } function n(e) { i.push(e), a || (a = !0, r(t, 0)) } var r, o = window.MutationObserver, i = [], a = !1; if (o) { var s = 1, c = new o(t), l = document.createTextNode(s); c.observe(l, { characterData: !0 }), r = function () { s = (s + 1) % 2, l.data = s } } else r = window.setTimeout; e.setEndOfMicrotask = n }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { e.scheduled_ || (e.scheduled_ = !0, f.push(e), m || (u(n), m = !0)) } function n() { for (m = !1; f.length;) { var e = f; f = [], e.sort(function (e, t) { return e.uid_ - t.uid_ }); for (var t = 0; t < e.length; t++) { var n = e[t]; n.scheduled_ = !1; var r = n.takeRecords(); i(n), r.length && n.callback_(r, n) } } } function r(e, t) { this.type = e, this.target = t, this.addedNodes = new p.NodeList, this.removedNodes = new p.NodeList, this.previousSibling = null, this.nextSibling = null, this.attributeName = null, this.attributeNamespace = null, this.oldValue = null } function o(e, t) { for (; e; e = e.parentNode) { var n = h.get(e); if (n) for (var r = 0; r < n.length; r++) { var o = n[r]; o.options.subtree && o.addTransientObserver(t) } } } function i(e) { for (var t = 0; t < e.nodes_.length; t++) { var n = e.nodes_[t], r = h.get(n); if (!r) return; for (var o = 0; o < r.length; o++) { var i = r[o]; i.observer === e && i.removeTransientObservers() } } } function a(e, n, o) { for (var i = Object.create(null), a = Object.create(null), s = e; s; s = s.parentNode) { var c = h.get(s); if (c) for (var l = 0; l < c.length; l++) { var u = c[l], d = u.options; if ((s === e || d.subtree) && ("attributes" !== n || d.attributes) && ("attributes" !== n || !d.attributeFilter || null === o.namespace && d.attributeFilter.indexOf(o.name) !== -1) && ("characterData" !== n || d.characterData) && ("childList" !== n || d.childList)) { var p = u.observer; i[p.uid_] = p, ("attributes" === n && d.attributeOldValue || "characterData" === n && d.characterDataOldValue) && (a[p.uid_] = o.oldValue) } } } for (var f in i) { var p = i[f], m = new r(n, e); "name" in o && "namespace" in o && (m.attributeName = o.name, m.attributeNamespace = o.namespace), o.addedNodes && (m.addedNodes = o.addedNodes), o.removedNodes && (m.removedNodes = o.removedNodes), o.previousSibling && (m.previousSibling = o.previousSibling), o.nextSibling && (m.nextSibling = o.nextSibling), void 0 !== a[f] && (m.oldValue = a[f]), t(p), p.records_.push(m) } } function s(e) { if (this.childList = !!e.childList, this.subtree = !!e.subtree, "attributes" in e || !("attributeOldValue" in e || "attributeFilter" in e) ? this.attributes = !!e.attributes : this.attributes = !0, "characterDataOldValue" in e && !("characterData" in e) ? this.characterData = !0 : this.characterData = !!e.characterData, !this.attributes && (e.attributeOldValue || "attributeFilter" in e) || !this.characterData && e.characterDataOldValue) throw new TypeError; if (this.characterData = !!e.characterData, this.attributeOldValue = !!e.attributeOldValue, this.characterDataOldValue = !!e.characterDataOldValue, "attributeFilter" in e) { if (null == e.attributeFilter || "object" != typeof e.attributeFilter) throw new TypeError; this.attributeFilter = w.call(e.attributeFilter) } else this.attributeFilter = null } function c(e) { this.callback_ = e, this.nodes_ = [], this.records_ = [], this.uid_ = ++v, this.scheduled_ = !1 } function l(e, t, n) { this.observer = e, this.target = t, this.options = n, this.transientObservedNodes = [] } var u = e.setEndOfMicrotask, d = e.wrapIfNeeded, p = e.wrappers, h = new WeakMap, f = [], m = !1, w = Array.prototype.slice, v = 0; c.prototype = { constructor: c, observe: function (e, t) { e = d(e); var n, r = new s(t), o = h.get(e); o || h.set(e, o = []); for (var i = 0; i < o.length; i++)o[i].observer === this && (n = o[i], n.removeTransientObservers(), n.options = r); n || (n = new l(this, e, r), o.push(n), this.nodes_.push(e)) }, disconnect: function () { this.nodes_.forEach(function (e) { for (var t = h.get(e), n = 0; n < t.length; n++) { var r = t[n]; if (r.observer === this) { t.splice(n, 1); break } } }, this), this.records_ = [] }, takeRecords: function () { var e = this.records_; return this.records_ = [], e } }, l.prototype = { addTransientObserver: function (e) { if (e !== this.target) { t(this.observer), this.transientObservedNodes.push(e); var n = h.get(e); n || h.set(e, n = []), n.push(this) } }, removeTransientObservers: function () { var e = this.transientObservedNodes; this.transientObservedNodes = []; for (var t = 0; t < e.length; t++)for (var n = e[t], r = h.get(n), o = 0; o < r.length; o++)if (r[o] === this) { r.splice(o, 1); break } } }, e.enqueueMutation = a, e.registerTransientObservers = o, e.wrappers.MutationObserver = c, e.wrappers.MutationRecord = r }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e, t) { this.root = e, this.parent = t } function n(e, t) { if (e.treeScope_ !== t) { e.treeScope_ = t; for (var r = e.shadowRoot; r; r = r.olderShadowRoot)r.treeScope_.parent = t; for (var o = e.firstChild; o; o = o.nextSibling)n(o, t) } } function r(n) { if (n instanceof e.wrappers.Window, n.treeScope_) return n.treeScope_; var o, i = n.parentNode; return o = i ? r(i) : new t(n, null), n.treeScope_ = o } t.prototype = { get renderer() { return this.root instanceof e.wrappers.ShadowRoot ? e.getRendererForHost(this.root.host) : null }, contains: function (e) { for (; e; e = e.parent)if (e === this) return !0; return !1 } }, e.TreeScope = t, e.getTreeScope = r, e.setTreeScope = n }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { return e instanceof G.ShadowRoot } function n(e) { return A(e).root } function r(e, r) { var s = [], c = e; for (s.push(c); c;) { var l = a(c); if (l && l.length > 0) { for (var u = 0; u < l.length; u++) { var p = l[u]; if (i(p)) { var h = n(p), f = h.olderShadowRoot; f && s.push(f) } s.push(p) } c = l[l.length - 1] } else if (t(c)) { if (d(e, c) && o(r)) break; c = c.host, s.push(c) } else c = c.parentNode, c && s.push(c) } return s } function o(e) { if (!e) return !1; switch (e.type) { case "abort": case "error": case "select": case "change": case "load": case "reset": case "resize": case "scroll": case "selectstart": return !0 }return !1 } function i(e) { return e instanceof HTMLShadowElement } function a(t) { return e.getDestinationInsertionPoints(t) } function s(e, t) { if (0 === e.length) return t; t instanceof G.Window && (t = t.document); for (var n = A(t), r = e[0], o = A(r), i = l(n, o), a = 0; a < e.length; a++) { var s = e[a]; if (A(s) === i) return s } return e[e.length - 1] } function c(e) { for (var t = []; e; e = e.parent)t.push(e); return t } function l(e, t) { for (var n = c(e), r = c(t), o = null; n.length > 0 && r.length > 0;) { var i = n.pop(), a = r.pop(); if (i !== a) break; o = i } return o } function u(e, t, n) { t instanceof G.Window && (t = t.document); var o, i = A(t), a = A(n), s = r(n, e), o = l(i, a); o || (o = a.root); for (var c = o; c; c = c.parent)for (var u = 0; u < s.length; u++) { var d = s[u]; if (A(d) === c) return d } return null } function d(e, t) { return A(e) === A(t) } function p(e) { if (!K.get(e) && (K.set(e, !0), f(V(e), V(e.target)), P)) { var t = P; throw P = null, t } } function h(e) { switch (e.type) { case "load": case "beforeunload": case "unload": return !0 }return !1 } function f(t, n) { if ($.get(t)) throw new Error("InvalidStateError"); $.set(t, !0), e.renderAllPending(); var o, i, a; if (h(t) && !t.bubbles) { var s = n; s instanceof G.Document && (a = s.defaultView) && (i = s, o = []) } if (!o) if (n instanceof G.Window) a = n, o = []; else if (o = r(n, t), !h(t)) { var s = o[o.length - 1]; s instanceof G.Document && (a = s.defaultView) } return ne.set(t, o), m(t, o, a, i) && w(t, o, a, i) && v(t, o, a, i), J.set(t, re), Y["delete"](t, null), $["delete"](t), t.defaultPrevented } function m(e, t, n, r) { var o = oe; if (n && !g(n, e, o, t, r)) return !1; for (var i = t.length - 1; i > 0; i--)if (!g(t[i], e, o, t, r)) return !1; return !0 } function w(e, t, n, r) { var o = ie, i = t[0] || n; return g(i, e, o, t, r) } function v(e, t, n, r) { for (var o = ae, i = 1; i < t.length; i++)if (!g(t[i], e, o, t, r)) return; n && t.length > 0 && g(n, e, o, t, r) } function g(e, t, n, r, o) { var i = z.get(e); if (!i) return !0; var a = o || s(r, e); if (a === e) { if (n === oe) return !0; n === ae && (n = ie) } else if (n === ae && !t.bubbles) return !0; if ("relatedTarget" in t) { var c = B(t), l = c.relatedTarget; if (l) { if (l instanceof Object && l.addEventListener) { var d = V(l), p = u(t, e, d); if (p === a) return !0 } else p = null; Z.set(t, p) } } J.set(t, n); var h = t.type, f = !1; X.set(t, a), Y.set(t, e), i.depth++; for (var m = 0, w = i.length; m < w; m++) { var v = i[m]; if (v.removed) f = !0; else if (!(v.type !== h || !v.capture && n === oe || v.capture && n === ae)) try { if ("function" == typeof v.handler ? v.handler.call(e, t) : v.handler.handleEvent(t), ee.get(t)) return !1 } catch (g) { P || (P = g) } } if (i.depth--, f && 0 === i.depth) { var b = i.slice(); i.length = 0; for (var m = 0; m < b.length; m++)b[m].removed || i.push(b[m]) } return !Q.get(t) } function b(e, t, n) { this.type = e, this.handler = t, this.capture = Boolean(n) } function y(e, t) { if (!(e instanceof se)) return V(T(se, "Event", e, t)); var n = e; return be || "beforeunload" !== n.type || this instanceof M ? void U(n, this) : new M(n) } function E(e) { return e && e.relatedTarget ? Object.create(e, { relatedTarget: { value: B(e.relatedTarget) } }) : e } function _(e, t, n) { var r = window[e], o = function (t, n) { return t instanceof r ? void U(t, this) : V(T(r, e, t, n)) }; if (o.prototype = Object.create(t.prototype), n && W(o.prototype, n), r) try { F(r, o, new r("temp")) } catch (i) { F(r, o, document.createEvent(e)) } return o } function S(e, t) { return function () { arguments[t] = B(arguments[t]); var n = B(this); n[e].apply(n, arguments) } } function T(e, t, n, r) { if (ve) return new e(n, E(r)); var o = B(document.createEvent(t)), i = we[t], a = [n]; return Object.keys(i).forEach(function (e) { var t = null != r && e in r ? r[e] : i[e]; "relatedTarget" === e && (t = B(t)), a.push(t) }), o["init" + t].apply(o, a), o } function M(e) { y.call(this, e) } function O(e) { return "function" == typeof e || e && e.handleEvent } function L(e) { switch (e) { case "DOMAttrModified": case "DOMAttributeNameChanged": case "DOMCharacterDataModified": case "DOMElementNameChanged": case "DOMNodeInserted": case "DOMNodeInsertedIntoDocument": case "DOMNodeRemoved": case "DOMNodeRemovedFromDocument": case "DOMSubtreeModified": return !0 }return !1 } function N(e) { U(e, this) } function C(e) { return e instanceof G.ShadowRoot && (e = e.host), B(e) } function j(e, t) { var n = z.get(e); if (n) for (var r = 0; r < n.length; r++)if (!n[r].removed && n[r].type === t) return !0; return !1 } function D(e, t) { for (var n = B(e); n; n = n.parentNode)if (j(V(n), t)) return !0; return !1 } function H(e) { k(e, Ee) } function x(t, n, o, i) { e.renderAllPending(); var a = V(_e.call(q(n), o, i)); if (!a) return null; var c = r(a, null), l = c.lastIndexOf(t); return l == -1 ? null : (c = c.slice(0, l), s(c, t)) } function R(e) { return function () { var t = te.get(this); return t && t[e] && t[e].value || null } } function I(e) { var t = e.slice(2); return function (n) { var r = te.get(this); r || (r = Object.create(null), te.set(this, r)); var o = r[e]; if (o && this.removeEventListener(t, o.wrapped, !1), "function" == typeof n) { var i = function (t) { var r = n.call(this, t); r === !1 ? t.preventDefault() : "onbeforeunload" === e && "string" == typeof r && (t.returnValue = r) }; this.addEventListener(t, i, !1), r[e] = { value: n, wrapped: i } } } } var P, k = e.forwardMethodsToWrapper, A = e.getTreeScope, W = e.mixin, F = e.registerWrapper, U = e.setWrapper, q = e.unsafeUnwrap, B = e.unwrap, V = e.wrap, G = e.wrappers, z = (new WeakMap, new WeakMap), K = new WeakMap, $ = new WeakMap, X = new WeakMap, Y = new WeakMap, Z = new WeakMap, J = new WeakMap, Q = new WeakMap, ee = new WeakMap, te = new WeakMap, ne = new WeakMap, re = 0, oe = 1, ie = 2, ae = 3; b.prototype = { equals: function (e) { return this.handler === e.handler && this.type === e.type && this.capture === e.capture }, get removed() { return null === this.handler }, remove: function () { this.handler = null } }; var se = window.Event; se.prototype.polymerBlackList_ = { returnValue: !0, keyLocation: !0 }, y.prototype = { get target() { return X.get(this) }, get currentTarget() { return Y.get(this) }, get eventPhase() { return J.get(this) }, get path() { var e = ne.get(this); return e ? e.slice() : [] }, stopPropagation: function () { Q.set(this, !0) }, stopImmediatePropagation: function () { Q.set(this, !0), ee.set(this, !0) } }; var ce = function () { var e = document.createEvent("Event"); return e.initEvent("test", !0, !0), e.preventDefault(), e.defaultPrevented }(); ce || (y.prototype.preventDefault = function () { this.cancelable && (q(this).preventDefault(), Object.defineProperty(this, "defaultPrevented", { get: function () { return !0 }, configurable: !0 })) }), F(se, y, document.createEvent("Event")); var le = _("UIEvent", y), ue = _("CustomEvent", y), de = { get relatedTarget() { var e = Z.get(this); return void 0 !== e ? e : V(B(this).relatedTarget) } }, pe = W({ initMouseEvent: S("initMouseEvent", 14) }, de), he = W({ initFocusEvent: S("initFocusEvent", 5) }, de), fe = _("MouseEvent", le, pe), me = _("FocusEvent", le, he), we = Object.create(null), ve = function () { try { new window.FocusEvent("focus") } catch (e) { return !1 } return !0 }(); if (!ve) { var ge = function (e, t, n) { if (n) { var r = we[n]; t = W(W({}, r), t) } we[e] = t }; ge("Event", { bubbles: !1, cancelable: !1 }), ge("CustomEvent", { detail: null }, "Event"), ge("UIEvent", { view: null, detail: 0 }, "Event"), ge("MouseEvent", { screenX: 0, screenY: 0, clientX: 0, clientY: 0, ctrlKey: !1, altKey: !1, shiftKey: !1, metaKey: !1, button: 0, relatedTarget: null }, "UIEvent"), ge("FocusEvent", { relatedTarget: null }, "UIEvent") } var be = window.BeforeUnloadEvent; M.prototype = Object.create(y.prototype), W(M.prototype, { get returnValue() { return q(this).returnValue }, set returnValue(e) { q(this).returnValue = e } }), be && F(be, M); var ye = window.EventTarget, Ee = ["addEventListener", "removeEventListener", "dispatchEvent"];[Node, Window].forEach(function (e) { var t = e.prototype; Ee.forEach(function (e) { Object.defineProperty(t, e + "_", { value: t[e] }) }) }), N.prototype = { addEventListener: function (e, t, n) { if (O(t) && !L(e)) { var r = new b(e, t, n), o = z.get(this); if (o) { for (var i = 0; i < o.length; i++)if (r.equals(o[i])) return } else o = [], o.depth = 0, z.set(this, o); o.push(r); var a = C(this); a.addEventListener_(e, p, !0) } }, removeEventListener: function (e, t, n) { n = Boolean(n); var r = z.get(this); if (r) { for (var o = 0, i = !1, a = 0; a < r.length; a++)r[a].type === e && r[a].capture === n && (o++, r[a].handler === t && (i = !0, r[a].remove())); if (i && 1 === o) { var s = C(this); s.removeEventListener_(e, p, !0) } } }, dispatchEvent: function (t) { var n = B(t), r = n.type; K.set(n, !1), e.renderAllPending(); var o; D(this, r) || (o = function () { }, this.addEventListener(r, o, !0)); try { return B(this).dispatchEvent_(n) } finally { o && this.removeEventListener(r, o, !0) } } }, ye && F(ye, N); var _e = document.elementFromPoint; e.elementFromPoint = x, e.getEventHandlerGetter = R, e.getEventHandlerSetter = I, e.wrapEventTargetMethods = H, e.wrappers.BeforeUnloadEvent = M, e.wrappers.CustomEvent = ue, e.wrappers.Event = y, e.wrappers.EventTarget = N, e.wrappers.FocusEvent = me, e.wrappers.MouseEvent = fe, e.wrappers.UIEvent = le }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e, t) { Object.defineProperty(e, t, m) } function n(e) { l(e, this) } function r() { this.length = 0, t(this, "length") } function o(e) { for (var t = new r, o = 0; o < e.length; o++)t[o] = new n(e[o]); return t.length = o, t } function i(e) { a.call(this, e) } var a = e.wrappers.UIEvent, s = e.mixin, c = e.registerWrapper, l = e.setWrapper, u = e.unsafeUnwrap, d = e.wrap, p = window.TouchEvent; if (p) { var h; try { h = document.createEvent("TouchEvent") } catch (f) { return } var m = { enumerable: !1 }; n.prototype = { get target() { return d(u(this).target) } }; var w = { configurable: !0, enumerable: !0, get: null };["clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce"].forEach(function (e) { w.get = function () { return u(this)[e] }, Object.defineProperty(n.prototype, e, w) }), r.prototype = { item: function (e) { return this[e] } }, i.prototype = Object.create(a.prototype), s(i.prototype, { get touches() { return o(u(this).touches) }, get targetTouches() { return o(u(this).targetTouches) }, get changedTouches() { return o(u(this).changedTouches) }, initTouchEvent: function () { throw new Error("Not implemented") } }), c(p, i, h), e.wrappers.Touch = n, e.wrappers.TouchEvent = i, e.wrappers.TouchList = r } }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e, t) { Object.defineProperty(e, t, s) } function n() { this.length = 0, t(this, "length") } function r(e) { if (null == e) return e; for (var t = new n, r = 0, o = e.length; r < o; r++)t[r] = a(e[r]); return t.length = o, t } function o(e, t) { e.prototype[t] = function () { return r(i(this)[t].apply(i(this), arguments)) } } var i = e.unsafeUnwrap, a = e.wrap, s = { enumerable: !1 }; n.prototype = { item: function (e) { return this[e] } }, t(n.prototype, "item"), e.wrappers.NodeList = n, e.addWrapNodeListMethod = o, e.wrapNodeList = r }(window.ShadowDOMPolyfill), function (e) { "use strict"; e.wrapHTMLCollection = e.wrapNodeList, e.wrappers.HTMLCollection = e.wrappers.NodeList }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { O(e instanceof _) } function n(e) { var t = new T; return t[0] = e, t.length = 1, t } function r(e, t, n) { N(t, "childList", { removedNodes: n, previousSibling: e.previousSibling, nextSibling: e.nextSibling }) } function o(e, t) { N(e, "childList", { removedNodes: t }) } function i(e, t, r, o) { if (e instanceof DocumentFragment) { var i = s(e); U = !0; for (var a = i.length - 1; a >= 0; a--)e.removeChild(i[a]), i[a].parentNode_ = t; U = !1; for (var a = 0; a < i.length; a++)i[a].previousSibling_ = i[a - 1] || r, i[a].nextSibling_ = i[a + 1] || o; return r && (r.nextSibling_ = i[0]), o && (o.previousSibling_ = i[i.length - 1]), i } var i = n(e), c = e.parentNode; return c && c.removeChild(e), e.parentNode_ = t, e.previousSibling_ = r, e.nextSibling_ = o, r && (r.nextSibling_ = e), o && (o.previousSibling_ = e), i } function a(e) { if (e instanceof DocumentFragment) return s(e); var t = n(e), o = e.parentNode; return o && r(e, o, t), t } function s(e) { for (var t = new T, n = 0, r = e.firstChild; r; r = r.nextSibling)t[n++] = r; return t.length = n, o(e, t), t } function c(e) { return e } function l(e, t) { R(e, t), e.nodeIsInserted_() } function u(e, t) { for (var n = C(t), r = 0; r < e.length; r++)l(e[r], n) } function d(e) { R(e, new M(e, null)) } function p(e) { for (var t = 0; t < e.length; t++)d(e[t]) } function h(e, t) { var n = e.nodeType === _.DOCUMENT_NODE ? e : e.ownerDocument; n !== t.ownerDocument && n.adoptNode(t) } function f(t, n) { if (n.length) { var r = t.ownerDocument; if (r !== n[0].ownerDocument) for (var o = 0; o < n.length; o++)e.adoptNodeNoRemove(n[o], r) } } function m(e, t) { f(e, t); var n = t.length; if (1 === n) return P(t[0]); for (var r = P(e.ownerDocument.createDocumentFragment()), o = 0; o < n; o++)r.appendChild(P(t[o])); return r } function w(e) { if (void 0 !== e.firstChild_) for (var t = e.firstChild_; t;) { var n = t; t = t.nextSibling_, n.parentNode_ = n.previousSibling_ = n.nextSibling_ = void 0 } e.firstChild_ = e.lastChild_ = void 0 } function v(e) { if (e.invalidateShadowRenderer()) { for (var t = e.firstChild; t;) { O(t.parentNode === e); var n = t.nextSibling, r = P(t), o = r.parentNode; o && X.call(o, r), t.previousSibling_ = t.nextSibling_ = t.parentNode_ = null, t = n } e.firstChild_ = e.lastChild_ = null } else for (var n, i = P(e), a = i.firstChild; a;)n = a.nextSibling, X.call(i, a), a = n } function g(e) { var t = e.parentNode; return t && t.invalidateShadowRenderer() } function b(e) { for (var t, n = 0; n < e.length; n++)t = e[n], t.parentNode.removeChild(t) } function y(e, t, n) { var r; if (r = A(n ? q.call(n, I(e), !1) : B.call(I(e), !1)), t) { for (var o = e.firstChild; o; o = o.nextSibling)r.appendChild(y(o, !0, n)); if (e instanceof F.HTMLTemplateElement) for (var i = r.content, o = e.content.firstChild; o; o = o.nextSibling)i.appendChild(y(o, !0, n)) } return r } function E(e, t) { if (!t || C(e) !== C(t)) return !1; for (var n = t; n; n = n.parentNode)if (n === e) return !0; return !1 } function _(e) { O(e instanceof V), S.call(this, e), this.parentNode_ = void 0, this.firstChild_ = void 0, this.lastChild_ = void 0, this.nextSibling_ = void 0, this.previousSibling_ = void 0, this.treeScope_ = void 0 } var S = e.wrappers.EventTarget, T = e.wrappers.NodeList, M = e.TreeScope, O = e.assert, L = e.defineWrapGetter, N = e.enqueueMutation, C = e.getTreeScope, j = e.isWrapper, D = e.mixin, H = e.registerTransientObservers, x = e.registerWrapper, R = e.setTreeScope, I = e.unsafeUnwrap, P = e.unwrap, k = e.unwrapIfNeeded, A = e.wrap, W = e.wrapIfNeeded, F = e.wrappers, U = !1, q = document.importNode, B = window.Node.prototype.cloneNode, V = window.Node, G = window.DocumentFragment, z = (V.prototype.appendChild, V.prototype.compareDocumentPosition), K = V.prototype.isEqualNode, $ = V.prototype.insertBefore, X = V.prototype.removeChild, Y = V.prototype.replaceChild, Z = /Trident|Edge/.test(navigator.userAgent), J = Z ? function (e, t) { try { X.call(e, t) } catch (n) { if (!(e instanceof G)) throw n } } : function (e, t) { X.call(e, t) }; _.prototype = Object.create(S.prototype), D(_.prototype, { appendChild: function (e) { return this.insertBefore(e, null) }, insertBefore: function (e, n) { t(e); var r; n ? j(n) ? r = P(n) : (r = n, n = A(r)) : (n = null, r = null), n && O(n.parentNode === this); var o, s = n ? n.previousSibling : this.lastChild, c = !this.invalidateShadowRenderer() && !g(e); if (o = c ? a(e) : i(e, this, s, n), c) h(this, e), w(this), $.call(I(this), P(e), r); else { s || (this.firstChild_ = o[0]), n || (this.lastChild_ = o[o.length - 1], void 0 === this.firstChild_ && (this.firstChild_ = this.firstChild)); var l = r ? r.parentNode : I(this); l ? $.call(l, m(this, o), r) : f(this, o) } return N(this, "childList", { addedNodes: o, nextSibling: n, previousSibling: s }), u(o, this), e }, removeChild: function (e) { if (t(e), e.parentNode !== this) { for (var r = !1, o = (this.childNodes, this.firstChild); o; o = o.nextSibling)if (o === e) { r = !0; break } if (!r) throw new Error("NotFoundError") } var i = P(e), a = e.nextSibling, s = e.previousSibling; if (this.invalidateShadowRenderer()) { var c = this.firstChild, l = this.lastChild, u = i.parentNode; u && J(u, i), c === e && (this.firstChild_ = a), l === e && (this.lastChild_ = s), s && (s.nextSibling_ = a), a && (a.previousSibling_ = s), e.previousSibling_ = e.nextSibling_ = e.parentNode_ = void 0 } else w(this), J(I(this), i); return U || N(this, "childList", { removedNodes: n(e), nextSibling: a, previousSibling: s }), H(this, e), e }, replaceChild: function (e, r) { t(e); var o; if (j(r) ? o = P(r) : (o = r, r = A(o)), r.parentNode !== this) throw new Error("NotFoundError"); var s, c = r.nextSibling, l = r.previousSibling, p = !this.invalidateShadowRenderer() && !g(e); return p ? s = a(e) : (c === e && (c = e.nextSibling), s = i(e, this, l, c)), p ? (h(this, e), w(this), Y.call(I(this), P(e), o)) : (this.firstChild === r && (this.firstChild_ = s[0]), this.lastChild === r && (this.lastChild_ = s[s.length - 1]), r.previousSibling_ = r.nextSibling_ = r.parentNode_ = void 0, o.parentNode && Y.call(o.parentNode, m(this, s), o)), N(this, "childList", { addedNodes: s, removedNodes: n(r), nextSibling: c, previousSibling: l }), d(r), u(s, this), r }, nodeIsInserted_: function () { for (var e = this.firstChild; e; e = e.nextSibling)e.nodeIsInserted_() }, hasChildNodes: function () { return null !== this.firstChild }, get parentNode() { return void 0 !== this.parentNode_ ? this.parentNode_ : A(I(this).parentNode) }, get firstChild() { return void 0 !== this.firstChild_ ? this.firstChild_ : A(I(this).firstChild) }, get lastChild() { return void 0 !== this.lastChild_ ? this.lastChild_ : A(I(this).lastChild) }, get nextSibling() { return void 0 !== this.nextSibling_ ? this.nextSibling_ : A(I(this).nextSibling) }, get previousSibling() { return void 0 !== this.previousSibling_ ? this.previousSibling_ : A(I(this).previousSibling) }, get parentElement() { for (var e = this.parentNode; e && e.nodeType !== _.ELEMENT_NODE;)e = e.parentNode; return e }, get textContent() { for (var e = "", t = this.firstChild; t; t = t.nextSibling)t.nodeType != _.COMMENT_NODE && (e += t.textContent); return e }, set textContent(e) { null == e && (e = ""); var t = c(this.childNodes); if (this.invalidateShadowRenderer()) { if (v(this), "" !== e) { var n = I(this).ownerDocument.createTextNode(e); this.appendChild(n) } } else w(this), I(this).textContent = e; var r = c(this.childNodes); N(this, "childList", { addedNodes: r, removedNodes: t }), p(t), u(r, this) }, get childNodes() { for (var e = new T, t = 0, n = this.firstChild; n; n = n.nextSibling)e[t++] = n; return e.length = t, e }, cloneNode: function (e) { return y(this, e) }, contains: function (e) { return E(this, W(e)) }, compareDocumentPosition: function (e) { return z.call(I(this), k(e)) }, isEqualNode: function (e) { return K.call(I(this), k(e)) }, normalize: function () { for (var e, t, n = c(this.childNodes), r = [], o = "", i = 0; i < n.length; i++)t = n[i], t.nodeType === _.TEXT_NODE ? e || t.data.length ? e ? (o += t.data, r.push(t)) : e = t : this.removeChild(t) : (e && r.length && (e.data += o, b(r)), r = [], o = "", e = null, t.childNodes.length && t.normalize()); e && r.length && (e.data += o, b(r)) } }), L(_, "ownerDocument"), x(V, _, document.createDocumentFragment()), delete _.prototype.querySelector, delete _.prototype.querySelectorAll, _.prototype = D(Object.create(S.prototype), _.prototype), e.cloneNode = y, e.nodeWasAdded = l, e.nodeWasRemoved = d, e.nodesWereAdded = u, e.nodesWereRemoved = p, e.originalInsertBefore = $, e.originalRemoveChild = X, e.snapshotNodeList = c, e.wrappers.Node = _ }(window.ShadowDOMPolyfill), function (e) { - "use strict"; function t(t, n, r, o) { for (var i = null, a = null, s = 0, c = t.length; s < c; s++)i = b(t[s]), !o && (a = v(i).root) && a instanceof e.wrappers.ShadowRoot || (r[n++] = i); return n } function n(e) { return String(e).replace(/\/deep\/|::shadow|>>>/g, " ") } function r(e) { return String(e).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g, " ") } function o(e, t) { for (var n, r = e.firstElementChild; r;) { if (r.matches(t)) return r; if (n = o(r, t)) return n; r = r.nextElementSibling } return null } function i(e, t) { return e.matches(t) } function a(e, t, n) { var r = e.localName; return r === t || r === n && e.namespaceURI === j } function s() { return !0 } function c(e, t, n) { return e.localName === n } function l(e, t) { return e.namespaceURI === t } function u(e, t, n) { return e.namespaceURI === t && e.localName === n } function d(e, t, n, r, o, i) { for (var a = e.firstElementChild; a;)r(a, o, i) && (n[t++] = a), t = d(a, t, n, r, o, i), a = a.nextElementSibling; return t } function p(n, r, o, i, a) { var s, c = g(this), l = v(this).root; if (l instanceof e.wrappers.ShadowRoot) return d(this, r, o, n, i, null); if (c instanceof N) s = S.call(c, i); else { if (!(c instanceof C)) return d(this, r, o, n, i, null); s = _.call(c, i) } return t(s, r, o, a) } function h(n, r, o, i, a) { var s, c = g(this), l = v(this).root; if (l instanceof e.wrappers.ShadowRoot) return d(this, r, o, n, i, a); if (c instanceof N) s = M.call(c, i, a); else { if (!(c instanceof C)) return d(this, r, o, n, i, a); s = T.call(c, i, a) } return t(s, r, o, !1) } function f(n, r, o, i, a) { var s, c = g(this), l = v(this).root; if (l instanceof e.wrappers.ShadowRoot) return d(this, r, o, n, i, a); if (c instanceof N) s = L.call(c, i, a); else { if (!(c instanceof C)) return d(this, r, o, n, i, a); s = O.call(c, i, a) } return t(s, r, o, !1) } var m = e.wrappers.HTMLCollection, w = e.wrappers.NodeList, v = e.getTreeScope, g = e.unsafeUnwrap, b = e.wrap, y = document.querySelector, E = document.documentElement.querySelector, _ = document.querySelectorAll, S = document.documentElement.querySelectorAll, T = document.getElementsByTagName, M = document.documentElement.getElementsByTagName, O = document.getElementsByTagNameNS, L = document.documentElement.getElementsByTagNameNS, N = window.Element, C = window.HTMLDocument || window.Document, j = "http://www.w3.org/1999/xhtml", D = { - querySelector: function (t) { var r = n(t), i = r !== t; t = r; var a, s = g(this), c = v(this).root; if (c instanceof e.wrappers.ShadowRoot) return o(this, t); if (s instanceof N) a = b(E.call(s, t)); else { if (!(s instanceof C)) return o(this, t); a = b(y.call(s, t)) } return a && !i && (c = v(a).root) && c instanceof e.wrappers.ShadowRoot ? o(this, t) : a }, querySelectorAll: function (e) { var t = n(e), r = t !== e; e = t; var o = new w; return o.length = p.call(this, i, 0, o, e, r), o } - }, H = { matches: function (t) { return t = r(t), e.originalMatches.call(g(this), t) } }, x = { getElementsByTagName: function (e) { var t = new m, n = "*" === e ? s : a; return t.length = h.call(this, n, 0, t, e, e.toLowerCase()), t }, getElementsByClassName: function (e) { return this.querySelectorAll("." + e) }, getElementsByTagNameNS: function (e, t) { var n = new m, r = null; return r = "*" === e ? "*" === t ? s : c : "*" === t ? l : u, n.length = f.call(this, r, 0, n, e || null, t), n } }; e.GetElementsByInterface = x, e.SelectorsInterface = D, e.MatchesInterface = H -}(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { for (; e && e.nodeType !== Node.ELEMENT_NODE;)e = e.nextSibling; return e } function n(e) { for (; e && e.nodeType !== Node.ELEMENT_NODE;)e = e.previousSibling; return e } var r = e.wrappers.NodeList, o = { get firstElementChild() { return t(this.firstChild) }, get lastElementChild() { return n(this.lastChild) }, get childElementCount() { for (var e = 0, t = this.firstElementChild; t; t = t.nextElementSibling)e++; return e }, get children() { for (var e = new r, t = 0, n = this.firstElementChild; n; n = n.nextElementSibling)e[t++] = n; return e.length = t, e }, remove: function () { var e = this.parentNode; e && e.removeChild(this) } }, i = { get nextElementSibling() { return t(this.nextSibling) }, get previousElementSibling() { return n(this.previousSibling) } }, a = { getElementById: function (e) { return /[ \t\n\r\f]/.test(e) ? null : this.querySelector('[id="' + e + '"]') } }; e.ChildNodeInterface = i, e.NonElementParentNodeInterface = a, e.ParentNodeInterface = o }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { r.call(this, e) } var n = e.ChildNodeInterface, r = e.wrappers.Node, o = e.enqueueMutation, i = e.mixin, a = e.registerWrapper, s = e.unsafeUnwrap, c = window.CharacterData; t.prototype = Object.create(r.prototype), i(t.prototype, { get nodeValue() { return this.data }, set nodeValue(e) { this.data = e }, get textContent() { return this.data }, set textContent(e) { this.data = e }, get data() { return s(this).data }, set data(e) { var t = s(this).data; o(this, "characterData", { oldValue: t }), s(this).data = e } }), i(t.prototype, n), a(c, t, document.createTextNode("")), e.wrappers.CharacterData = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { return e >>> 0 } function n(e) { r.call(this, e) } var r = e.wrappers.CharacterData, o = (e.enqueueMutation, e.mixin), i = e.registerWrapper, a = window.Text; n.prototype = Object.create(r.prototype), o(n.prototype, { splitText: function (e) { e = t(e); var n = this.data; if (e > n.length) throw new Error("IndexSizeError"); var r = n.slice(0, e), o = n.slice(e); this.data = r; var i = this.ownerDocument.createTextNode(o); return this.parentNode && this.parentNode.insertBefore(i, this.nextSibling), i } }), i(a, n, document.createTextNode("")), e.wrappers.Text = n }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { return i(e).getAttribute("class") } function n(e, t) { a(e, "attributes", { name: "class", namespace: null, oldValue: t }) } function r(t) { e.invalidateRendererBasedOnAttribute(t, "class") } function o(e, o, i) { var a = e.ownerElement_; if (null == a) return o.apply(e, i); var s = t(a), c = o.apply(e, i); return t(a) !== s && (n(a, s), r(a)), c } if (!window.DOMTokenList) return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH."); var i = e.unsafeUnwrap, a = e.enqueueMutation, s = DOMTokenList.prototype.add; DOMTokenList.prototype.add = function () { o(this, s, arguments) }; var c = DOMTokenList.prototype.remove; DOMTokenList.prototype.remove = function () { o(this, c, arguments) }; var l = DOMTokenList.prototype.toggle; DOMTokenList.prototype.toggle = function () { return o(this, l, arguments) } }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(t, n) { var r = t.parentNode; if (r && r.shadowRoot) { var o = e.getRendererForHost(r); o.dependsOnAttribute(n) && o.invalidate() } } function n(e, t, n) { u(e, "attributes", { name: t, namespace: null, oldValue: n }) } function r(e) { a.call(this, e) } var o = e.ChildNodeInterface, i = e.GetElementsByInterface, a = e.wrappers.Node, s = e.ParentNodeInterface, c = e.SelectorsInterface, l = e.MatchesInterface, u = (e.addWrapNodeListMethod, e.enqueueMutation), d = e.mixin, p = (e.oneOf, e.registerWrapper), h = e.unsafeUnwrap, f = e.wrappers, m = window.Element, w = ["matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector"].filter(function (e) { return m.prototype[e] }), v = w[0], g = m.prototype[v], b = new WeakMap; r.prototype = Object.create(a.prototype), d(r.prototype, { createShadowRoot: function () { var t = new f.ShadowRoot(this); h(this).polymerShadowRoot_ = t; var n = e.getRendererForHost(this); return n.invalidate(), t }, get shadowRoot() { return h(this).polymerShadowRoot_ || null }, setAttribute: function (e, r) { var o = h(this).getAttribute(e); h(this).setAttribute(e, r), n(this, e, o), t(this, e) }, removeAttribute: function (e) { var r = h(this).getAttribute(e); h(this).removeAttribute(e), n(this, e, r), t(this, e) }, get classList() { var e = b.get(this); if (!e) { if (e = h(this).classList, !e) return; e.ownerElement_ = this, b.set(this, e) } return e }, get className() { return h(this).className }, set className(e) { this.setAttribute("class", e) }, get id() { return h(this).id }, set id(e) { this.setAttribute("id", e) } }), w.forEach(function (e) { "matches" !== e && (r.prototype[e] = function (e) { return this.matches(e) }) }), m.prototype.webkitCreateShadowRoot && (r.prototype.webkitCreateShadowRoot = r.prototype.createShadowRoot), d(r.prototype, o), d(r.prototype, i), d(r.prototype, s), d(r.prototype, c), d(r.prototype, l), p(m, r, document.createElementNS(null, "x")), e.invalidateRendererBasedOnAttribute = t, e.matchesNames = w, e.originalMatches = g, e.wrappers.Element = r }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { switch (e) { case "&": return "&"; case "<": return "<"; case ">": return ">"; case '"': return """; case " ": return " " } } function n(e) { return e.replace(L, t) } function r(e) { return e.replace(N, t) } function o(e) { for (var t = {}, n = 0; n < e.length; n++)t[e[n]] = !0; return t } function i(e) { if (e.namespaceURI !== D) return !0; var t = e.ownerDocument.doctype; return t && t.publicId && t.systemId } function a(e, t) { switch (e.nodeType) { case Node.ELEMENT_NODE: for (var o, a = e.tagName.toLowerCase(), c = "<" + a, l = e.attributes, u = 0; o = l[u]; u++)c += " " + o.name + '="' + n(o.value) + '"'; return C[a] ? (i(e) && (c += "/"), c + ">") : c + ">" + s(e) + ""; case Node.TEXT_NODE: var d = e.data; return t && j[t.localName] ? d : r(d); case Node.COMMENT_NODE: return ""; default: throw console.error(e), new Error("not implemented") } } function s(e) { e instanceof O.HTMLTemplateElement && (e = e.content); for (var t = "", n = e.firstChild; n; n = n.nextSibling)t += a(n, e); return t } function c(e, t, n) { var r = n || "div"; e.textContent = ""; var o = T(e.ownerDocument.createElement(r)); o.innerHTML = t; for (var i; i = o.firstChild;)e.appendChild(M(i)) } function l(e) { m.call(this, e) } function u(e, t) { var n = T(e.cloneNode(!1)); n.innerHTML = t; for (var r, o = T(document.createDocumentFragment()); r = n.firstChild;)o.appendChild(r); return M(o) } function d(t) { return function () { return e.renderAllPending(), S(this)[t] } } function p(e) { w(l, e, d(e)) } function h(t) { Object.defineProperty(l.prototype, t, { get: d(t), set: function (n) { e.renderAllPending(), S(this)[t] = n }, configurable: !0, enumerable: !0 }) } function f(t) { Object.defineProperty(l.prototype, t, { value: function () { return e.renderAllPending(), S(this)[t].apply(S(this), arguments) }, configurable: !0, enumerable: !0 }) } var m = e.wrappers.Element, w = e.defineGetter, v = e.enqueueMutation, g = e.mixin, b = e.nodesWereAdded, y = e.nodesWereRemoved, E = e.registerWrapper, _ = e.snapshotNodeList, S = e.unsafeUnwrap, T = e.unwrap, M = e.wrap, O = e.wrappers, L = /[&\u00A0"]/g, N = /[&\u00A0<>]/g, C = o(["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]), j = o(["style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript"]), D = "http://www.w3.org/1999/xhtml", H = /MSIE/.test(navigator.userAgent), x = window.HTMLElement, R = window.HTMLTemplateElement; l.prototype = Object.create(m.prototype), g(l.prototype, { get innerHTML() { return s(this) }, set innerHTML(e) { if (H && j[this.localName]) return void (this.textContent = e); var t = _(this.childNodes); this.invalidateShadowRenderer() ? this instanceof O.HTMLTemplateElement ? c(this.content, e) : c(this, e, this.tagName) : !R && this instanceof O.HTMLTemplateElement ? c(this.content, e) : S(this).innerHTML = e; var n = _(this.childNodes); v(this, "childList", { addedNodes: n, removedNodes: t }), y(t), b(n, this) }, get outerHTML() { return a(this, this.parentNode) }, set outerHTML(e) { var t = this.parentNode; if (t) { t.invalidateShadowRenderer(); var n = u(t, e); t.replaceChild(n, this) } }, insertAdjacentHTML: function (e, t) { var n, r; switch (String(e).toLowerCase()) { case "beforebegin": n = this.parentNode, r = this; break; case "afterend": n = this.parentNode, r = this.nextSibling; break; case "afterbegin": n = this, r = this.firstChild; break; case "beforeend": n = this, r = null; break; default: return }var o = u(n, t); n.insertBefore(o, r) }, get hidden() { return this.hasAttribute("hidden") }, set hidden(e) { e ? this.setAttribute("hidden", "") : this.removeAttribute("hidden") } }), ["clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth"].forEach(p), ["scrollLeft", "scrollTop"].forEach(h), ["focus", "getBoundingClientRect", "getClientRects", "scrollIntoView"].forEach(f), E(x, l, document.createElement("b")), e.wrappers.HTMLElement = l, e.getInnerHTML = s, e.setInnerHTML = c }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.unsafeUnwrap, a = e.wrap, s = window.HTMLCanvasElement; t.prototype = Object.create(n.prototype), r(t.prototype, { getContext: function () { var e = i(this).getContext.apply(i(this), arguments); return e && a(e) } }), o(s, t, document.createElement("canvas")), e.wrappers.HTMLCanvasElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = window.HTMLContentElement; t.prototype = Object.create(n.prototype), r(t.prototype, { constructor: t, get select() { return this.getAttribute("select") }, set select(e) { this.setAttribute("select", e) }, setAttribute: function (e, t) { n.prototype.setAttribute.call(this, e, t), "select" === String(e).toLowerCase() && this.invalidateShadowRenderer(!0) } }), i && o(i, t), e.wrappers.HTMLContentElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.wrapHTMLCollection, a = e.unwrap, s = window.HTMLFormElement; t.prototype = Object.create(n.prototype), r(t.prototype, { get elements() { return i(a(this).elements) } }), o(s, t, document.createElement("form")), e.wrappers.HTMLFormElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { r.call(this, e) } function n(e, t) { if (!(this instanceof n)) throw new TypeError("DOM object constructor cannot be called as a function."); var o = i(document.createElement("img")); r.call(this, o), a(o, this), void 0 !== e && (o.width = e), void 0 !== t && (o.height = t) } var r = e.wrappers.HTMLElement, o = e.registerWrapper, i = e.unwrap, a = e.rewrap, s = window.HTMLImageElement; t.prototype = Object.create(r.prototype), o(s, t, document.createElement("img")), n.prototype = t.prototype, e.wrappers.HTMLImageElement = t, e.wrappers.Image = n }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = (e.mixin, e.wrappers.NodeList, e.registerWrapper), o = window.HTMLShadowElement; t.prototype = Object.create(n.prototype), t.prototype.constructor = t, o && r(o, t), e.wrappers.HTMLShadowElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { if (!e.defaultView) return e; var t = d.get(e); if (!t) { for (t = e.implementation.createHTMLDocument(""); t.lastChild;)t.removeChild(t.lastChild); d.set(e, t) } return t } function n(e) { for (var n, r = t(e.ownerDocument), o = c(r.createDocumentFragment()); n = e.firstChild;)o.appendChild(n); return o } function r(e) { if (o.call(this, e), !p) { var t = n(e); u.set(this, l(t)) } } var o = e.wrappers.HTMLElement, i = e.mixin, a = e.registerWrapper, s = e.unsafeUnwrap, c = e.unwrap, l = e.wrap, u = new WeakMap, d = new WeakMap, p = window.HTMLTemplateElement; r.prototype = Object.create(o.prototype), i(r.prototype, { constructor: r, get content() { return p ? l(s(this).content) : u.get(this) } }), p && a(p, r), e.wrappers.HTMLTemplateElement = r }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.registerWrapper, o = window.HTMLMediaElement; o && (t.prototype = Object.create(n.prototype), r(o, t, document.createElement("audio")), e.wrappers.HTMLMediaElement = t) }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { r.call(this, e) } function n(e) { if (!(this instanceof n)) throw new TypeError("DOM object constructor cannot be called as a function."); var t = i(document.createElement("audio")); r.call(this, t), a(t, this), t.setAttribute("preload", "auto"), void 0 !== e && t.setAttribute("src", e) } var r = e.wrappers.HTMLMediaElement, o = e.registerWrapper, i = e.unwrap, a = e.rewrap, s = window.HTMLAudioElement; s && (t.prototype = Object.create(r.prototype), o(s, t, document.createElement("audio")), n.prototype = t.prototype, e.wrappers.HTMLAudioElement = t, e.wrappers.Audio = n) }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { return e.replace(/\s+/g, " ").trim() } function n(e) { o.call(this, e) } function r(e, t, n, i) { if (!(this instanceof r)) throw new TypeError("DOM object constructor cannot be called as a function."); var a = c(document.createElement("option")); o.call(this, a), s(a, this), void 0 !== e && (a.text = e), void 0 !== t && a.setAttribute("value", t), n === !0 && a.setAttribute("selected", ""), a.selected = i === !0 } var o = e.wrappers.HTMLElement, i = e.mixin, a = e.registerWrapper, s = e.rewrap, c = e.unwrap, l = e.wrap, u = window.HTMLOptionElement; n.prototype = Object.create(o.prototype), i(n.prototype, { get text() { return t(this.textContent) }, set text(e) { this.textContent = t(String(e)) }, get form() { return l(c(this).form) } }), a(u, n, document.createElement("option")), r.prototype = n.prototype, e.wrappers.HTMLOptionElement = n, e.wrappers.Option = r }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.unwrap, a = e.wrap, s = window.HTMLSelectElement; t.prototype = Object.create(n.prototype), r(t.prototype, { add: function (e, t) { "object" == typeof t && (t = i(t)), i(this).add(i(e), t) }, remove: function (e) { return void 0 === e ? void n.prototype.remove.call(this) : ("object" == typeof e && (e = i(e)), void i(this).remove(e)) }, get form() { return a(i(this).form) } }), o(s, t, document.createElement("select")), e.wrappers.HTMLSelectElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.unwrap, a = e.wrap, s = e.wrapHTMLCollection, c = window.HTMLTableElement; t.prototype = Object.create(n.prototype), r(t.prototype, { get caption() { return a(i(this).caption) }, createCaption: function () { return a(i(this).createCaption()) }, get tHead() { return a(i(this).tHead) }, createTHead: function () { return a(i(this).createTHead()) }, createTFoot: function () { return a(i(this).createTFoot()) }, get tFoot() { return a(i(this).tFoot) }, get tBodies() { return s(i(this).tBodies) }, createTBody: function () { return a(i(this).createTBody()) }, get rows() { return s(i(this).rows) }, insertRow: function (e) { return a(i(this).insertRow(e)) } }), o(c, t, document.createElement("table")), e.wrappers.HTMLTableElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.wrapHTMLCollection, a = e.unwrap, s = e.wrap, c = window.HTMLTableSectionElement; t.prototype = Object.create(n.prototype), r(t.prototype, { constructor: t, get rows() { return i(a(this).rows) }, insertRow: function (e) { return s(a(this).insertRow(e)) } }), o(c, t, document.createElement("thead")), e.wrappers.HTMLTableSectionElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.HTMLElement, r = e.mixin, o = e.registerWrapper, i = e.wrapHTMLCollection, a = e.unwrap, s = e.wrap, c = window.HTMLTableRowElement; t.prototype = Object.create(n.prototype), r(t.prototype, { get cells() { return i(a(this).cells) }, insertCell: function (e) { return s(a(this).insertCell(e)) } }), o(c, t, document.createElement("tr")), e.wrappers.HTMLTableRowElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { switch (e.localName) { case "content": return new n(e); case "shadow": return new o(e); case "template": return new i(e) }r.call(this, e) } var n = e.wrappers.HTMLContentElement, r = e.wrappers.HTMLElement, o = e.wrappers.HTMLShadowElement, i = e.wrappers.HTMLTemplateElement, a = (e.mixin, e.registerWrapper), s = window.HTMLUnknownElement; t.prototype = Object.create(r.prototype), a(s, t), e.wrappers.HTMLUnknownElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.Element, r = e.wrappers.HTMLElement, o = e.registerWrapper, i = (e.defineWrapGetter, e.unsafeUnwrap), a = e.wrap, s = e.mixin, c = "http://www.w3.org/2000/svg", l = window.SVGElement, u = document.createElementNS(c, "title"); if (!("classList" in u)) { var d = Object.getOwnPropertyDescriptor(n.prototype, "classList"); Object.defineProperty(r.prototype, "classList", d), delete n.prototype.classList } t.prototype = Object.create(n.prototype), s(t.prototype, { get ownerSVGElement() { return a(i(this).ownerSVGElement) } }), o(l, t, document.createElementNS(c, "title")), e.wrappers.SVGElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { p.call(this, e) } var n = e.mixin, r = e.registerWrapper, o = e.unwrap, i = e.wrap, a = window.SVGUseElement, s = "http://www.w3.org/2000/svg", c = i(document.createElementNS(s, "g")), l = document.createElementNS(s, "use"), u = c.constructor, d = Object.getPrototypeOf(u.prototype), p = d.constructor; t.prototype = Object.create(d), "instanceRoot" in l && n(t.prototype, { get instanceRoot() { return i(o(this).instanceRoot) }, get animatedInstanceRoot() { return i(o(this).animatedInstanceRoot) } }), r(a, t, l), e.wrappers.SVGUseElement = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.EventTarget, r = e.mixin, o = e.registerWrapper, i = e.unsafeUnwrap, a = e.wrap, s = window.SVGElementInstance; s && (t.prototype = Object.create(n.prototype), r(t.prototype, { get correspondingElement() { return a(i(this).correspondingElement) }, get correspondingUseElement() { return a(i(this).correspondingUseElement) }, get parentNode() { return a(i(this).parentNode) }, get childNodes() { throw new Error("Not implemented") }, get firstChild() { return a(i(this).firstChild) }, get lastChild() { return a(i(this).lastChild) }, get previousSibling() { return a(i(this).previousSibling) }, get nextSibling() { return a(i(this).nextSibling) } }), o(s, t), e.wrappers.SVGElementInstance = t) }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { o(e, this) } var n = e.mixin, r = e.registerWrapper, o = e.setWrapper, i = e.unsafeUnwrap, a = e.unwrap, s = e.unwrapIfNeeded, c = e.wrap, l = window.CanvasRenderingContext2D; n(t.prototype, { get canvas() { return c(i(this).canvas) }, drawImage: function () { arguments[0] = s(arguments[0]), i(this).drawImage.apply(i(this), arguments) }, createPattern: function () { return arguments[0] = a(arguments[0]), i(this).createPattern.apply(i(this), arguments) } }), r(l, t, document.createElement("canvas").getContext("2d")), e.wrappers.CanvasRenderingContext2D = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { i(e, this) } var n = e.addForwardingProperties, r = e.mixin, o = e.registerWrapper, i = e.setWrapper, a = e.unsafeUnwrap, s = e.unwrapIfNeeded, c = e.wrap, l = window.WebGLRenderingContext; if (l) { r(t.prototype, { get canvas() { return c(a(this).canvas) }, texImage2D: function () { arguments[5] = s(arguments[5]), a(this).texImage2D.apply(a(this), arguments) }, texSubImage2D: function () { arguments[6] = s(arguments[6]), a(this).texSubImage2D.apply(a(this), arguments) } }); var u = Object.getPrototypeOf(l.prototype); u !== Object.prototype && n(u, t.prototype); var d = /WebKit/.test(navigator.userAgent) ? { drawingBufferHeight: null, drawingBufferWidth: null } : {}; o(l, t, d), e.wrappers.WebGLRenderingContext = t } }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.Node, r = e.GetElementsByInterface, o = e.NonElementParentNodeInterface, i = e.ParentNodeInterface, a = e.SelectorsInterface, s = e.mixin, c = e.registerObject, l = e.registerWrapper, u = window.DocumentFragment; t.prototype = Object.create(n.prototype), s(t.prototype, i), s(t.prototype, a), s(t.prototype, r), s(t.prototype, o), l(u, t, document.createDocumentFragment()), e.wrappers.DocumentFragment = t; var d = c(document.createComment("")); e.wrappers.Comment = d }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { var t = d(u(e).ownerDocument.createDocumentFragment()); n.call(this, t), c(t, this); var o = e.shadowRoot; f.set(this, o), this.treeScope_ = new r(this, a(o || e)), h.set(this, e) } var n = e.wrappers.DocumentFragment, r = e.TreeScope, o = e.elementFromPoint, i = e.getInnerHTML, a = e.getTreeScope, s = e.mixin, c = e.rewrap, l = e.setInnerHTML, u = e.unsafeUnwrap, d = e.unwrap, p = e.wrap, h = new WeakMap, f = new WeakMap; t.prototype = Object.create(n.prototype), s(t.prototype, { constructor: t, get innerHTML() { return i(this) }, set innerHTML(e) { l(this, e), this.invalidateShadowRenderer() }, get olderShadowRoot() { return f.get(this) || null }, get host() { return h.get(this) || null }, invalidateShadowRenderer: function () { return h.get(this).invalidateShadowRenderer() }, elementFromPoint: function (e, t) { return o(this, this.ownerDocument, e, t) }, getSelection: function () { return document.getSelection() }, get activeElement() { var e = d(this).ownerDocument.activeElement; if (!e || !e.nodeType) return null; for (var t = p(e); !this.contains(t);) { for (; t.parentNode;)t = t.parentNode; if (!t.host) return null; t = t.host } return t } }), e.wrappers.ShadowRoot = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { var t = d(e).root; return t instanceof h ? t.host : null } function n(t, n) { if (t.shadowRoot) { n = Math.min(t.childNodes.length - 1, n); var r = t.childNodes[n]; if (r) { var o = e.getDestinationInsertionPoints(r); if (o.length > 0) { var i = o[0].parentNode; i.nodeType == Node.ELEMENT_NODE && (t = i) } } } return t } function r(e) { return e = u(e), t(e) || e } function o(e) { a(e, this) } var i = e.registerWrapper, a = e.setWrapper, s = e.unsafeUnwrap, c = e.unwrap, l = e.unwrapIfNeeded, u = e.wrap, d = e.getTreeScope, p = window.Range, h = e.wrappers.ShadowRoot; o.prototype = { get startContainer() { return r(s(this).startContainer) }, get endContainer() { return r(s(this).endContainer) }, get commonAncestorContainer() { return r(s(this).commonAncestorContainer) }, setStart: function (e, t) { e = n(e, t), s(this).setStart(l(e), t) }, setEnd: function (e, t) { e = n(e, t), s(this).setEnd(l(e), t) }, setStartBefore: function (e) { s(this).setStartBefore(l(e)) }, setStartAfter: function (e) { s(this).setStartAfter(l(e)) }, setEndBefore: function (e) { s(this).setEndBefore(l(e)) }, setEndAfter: function (e) { s(this).setEndAfter(l(e)) }, selectNode: function (e) { s(this).selectNode(l(e)) }, selectNodeContents: function (e) { s(this).selectNodeContents(l(e)) }, compareBoundaryPoints: function (e, t) { return s(this).compareBoundaryPoints(e, c(t)) }, extractContents: function () { return u(s(this).extractContents()) }, cloneContents: function () { return u(s(this).cloneContents()) }, insertNode: function (e) { s(this).insertNode(l(e)) }, surroundContents: function (e) { s(this).surroundContents(l(e)) }, cloneRange: function () { return u(s(this).cloneRange()) }, isPointInRange: function (e, t) { return s(this).isPointInRange(l(e), t) }, comparePoint: function (e, t) { return s(this).comparePoint(l(e), t) }, intersectsNode: function (e) { return s(this).intersectsNode(l(e)) }, toString: function () { return s(this).toString() } }, p.prototype.createContextualFragment && (o.prototype.createContextualFragment = function (e) { return u(s(this).createContextualFragment(e)) }), i(window.Range, o, document.createRange()), e.wrappers.Range = o }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { e.previousSibling_ = e.previousSibling, e.nextSibling_ = e.nextSibling, e.parentNode_ = e.parentNode } function n(n, o, i) { var a = x(n), s = x(o), c = i ? x(i) : null; if (r(o), t(o), i) n.firstChild === i && (n.firstChild_ = i), i.previousSibling_ = i.previousSibling; else { n.lastChild_ = n.lastChild, n.lastChild === n.firstChild && (n.firstChild_ = n.firstChild); var l = R(a.lastChild); l && (l.nextSibling_ = l.nextSibling) } e.originalInsertBefore.call(a, s, c) } function r(n) { var r = x(n), o = r.parentNode; if (o) { var i = R(o); t(n), n.previousSibling && (n.previousSibling.nextSibling_ = n), n.nextSibling && (n.nextSibling.previousSibling_ = n), i.lastChild === n && (i.lastChild_ = n), i.firstChild === n && (i.firstChild_ = n), e.originalRemoveChild.call(o, r) } } function o(e) { P.set(e, []) } function i(e) { var t = P.get(e); return t || P.set(e, t = []), t } function a(e) { for (var t = [], n = 0, r = e.firstChild; r; r = r.nextSibling)t[n++] = r; return t } function s() { for (var e = 0; e < F.length; e++) { var t = F[e], n = t.parentRenderer; n && n.dirty || t.render() } F = [] } function c() { T = null, s() } function l(e) { var t = A.get(e); return t || (t = new h(e), A.set(e, t)), t } function u(e) { var t = j(e).root; return t instanceof C ? t : null } function d(e) { return l(e.host) } function p(e) { this.skip = !1, this.node = e, this.childNodes = [] } function h(e) { this.host = e, this.dirty = !1, this.invalidateAttributes(), this.associateNode(e) } function f(e) { for (var t = [], n = e.firstChild; n; n = n.nextSibling)E(n) ? t.push.apply(t, i(n)) : t.push(n); return t } function m(e) { if (e instanceof L) return e; if (e instanceof O) return null; for (var t = e.firstChild; t; t = t.nextSibling) { var n = m(t); if (n) return n } return null } function w(e, t) { i(t).push(e); var n = k.get(e); n ? n.push(t) : k.set(e, [t]) } function v(e) { return k.get(e) } function g(e) { k.set(e, void 0) } function b(e, t) { var n = t.getAttribute("select"); if (!n) return !0; if (n = n.trim(), !n) return !0; if (!(e instanceof M)) return !1; if (!q.test(n)) return !1; try { return e.matches(n) } catch (r) { return !1 } } function y(e, t) { var n = v(t); return n && n[n.length - 1] === e } function E(e) { return e instanceof O || e instanceof L } function _(e) { return e.shadowRoot } function S(e) { for (var t = [], n = e.shadowRoot; n; n = n.olderShadowRoot)t.push(n); return t } var T, M = e.wrappers.Element, O = e.wrappers.HTMLContentElement, L = e.wrappers.HTMLShadowElement, N = e.wrappers.Node, C = e.wrappers.ShadowRoot, j = (e.assert, e.getTreeScope), D = (e.mixin, e.oneOf), H = e.unsafeUnwrap, x = e.unwrap, R = e.wrap, I = e.ArraySplice, P = new WeakMap, k = new WeakMap, A = new WeakMap, W = D(window, ["requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout"]), F = [], U = new I; U.equals = function (e, t) { return x(e.node) === t }, p.prototype = { append: function (e) { var t = new p(e); return this.childNodes.push(t), t }, sync: function (e) { if (!this.skip) { for (var t = this.node, o = this.childNodes, i = a(x(t)), s = e || new WeakMap, c = U.calculateSplices(o, i), l = 0, u = 0, d = 0, p = 0; p < c.length; p++) { for (var h = c[p]; d < h.index; d++)u++, o[l++].sync(s); for (var f = h.removed.length, m = 0; m < f; m++) { var w = R(i[u++]); s.get(w) || r(w) } for (var v = h.addedCount, g = i[u] && R(i[u]), m = 0; m < v; m++) { var b = o[l++], y = b.node; n(t, y, g), s.set(y, !0), b.sync(s) } d += v } for (var p = d; p < o.length; p++)o[p].sync(s) } } }, h.prototype = { render: function (e) { if (this.dirty) { this.invalidateAttributes(); var t = this.host; this.distribution(t); var n = e || new p(t); this.buildRenderTree(n, t); var r = !e; r && n.sync(), this.dirty = !1 } }, get parentRenderer() { return j(this.host).renderer }, invalidate: function () { if (!this.dirty) { this.dirty = !0; var e = this.parentRenderer; if (e && e.invalidate(), F.push(this), T) return; T = window[W](c, 0) } }, distribution: function (e) { this.resetAllSubtrees(e), this.distributionResolution(e) }, resetAll: function (e) { E(e) ? o(e) : g(e), this.resetAllSubtrees(e) }, resetAllSubtrees: function (e) { for (var t = e.firstChild; t; t = t.nextSibling)this.resetAll(t); e.shadowRoot && this.resetAll(e.shadowRoot), e.olderShadowRoot && this.resetAll(e.olderShadowRoot) }, distributionResolution: function (e) { if (_(e)) { for (var t = e, n = f(t), r = S(t), o = 0; o < r.length; o++)this.poolDistribution(r[o], n); for (var o = r.length - 1; o >= 0; o--) { var i = r[o], a = m(i); if (a) { var s = i.olderShadowRoot; s && (n = f(s)); for (var c = 0; c < n.length; c++)w(n[c], a) } this.distributionResolution(i) } } for (var l = e.firstChild; l; l = l.nextSibling)this.distributionResolution(l) }, poolDistribution: function (e, t) { if (!(e instanceof L)) if (e instanceof O) { var n = e; this.updateDependentAttributes(n.getAttribute("select")); for (var r = !1, o = 0; o < t.length; o++) { var e = t[o]; e && b(e, n) && (w(e, n), t[o] = void 0, r = !0) } if (!r) for (var i = n.firstChild; i; i = i.nextSibling)w(i, n) } else for (var i = e.firstChild; i; i = i.nextSibling)this.poolDistribution(i, t) }, buildRenderTree: function (e, t) { for (var n = this.compose(t), r = 0; r < n.length; r++) { var o = n[r], i = e.append(o); this.buildRenderTree(i, o) } if (_(t)) { var a = l(t); a.dirty = !1 } }, compose: function (e) { for (var t = [], n = e.shadowRoot || e, r = n.firstChild; r; r = r.nextSibling)if (E(r)) { this.associateNode(n); for (var o = i(r), a = 0; a < o.length; a++) { var s = o[a]; y(r, s) && t.push(s) } } else t.push(r); return t }, invalidateAttributes: function () { this.attributes = Object.create(null) }, updateDependentAttributes: function (e) { if (e) { var t = this.attributes; /\.\w+/.test(e) && (t["class"] = !0), /#\w+/.test(e) && (t.id = !0), e.replace(/\[\s*([^\s=\|~\]]+)/g, function (e, n) { t[n] = !0 }) } }, dependsOnAttribute: function (e) { return this.attributes[e] }, associateNode: function (e) { H(e).polymerShadowRenderer_ = this } }; var q = /^(:not\()?[*.#[a-zA-Z_|]/; N.prototype.invalidateShadowRenderer = function (e) { var t = H(this).polymerShadowRenderer_; return !!t && (t.invalidate(), !0) }, O.prototype.getDistributedNodes = L.prototype.getDistributedNodes = function () { return s(), i(this) }, M.prototype.getDestinationInsertionPoints = function () { return s(), v(this) || [] }, O.prototype.nodeIsInserted_ = L.prototype.nodeIsInserted_ = function () { this.invalidateShadowRenderer(); var e, t = u(this); t && (e = d(t)), H(this).polymerShadowRenderer_ = e, e && e.invalidate() }, e.getRendererForHost = l, e.getShadowTrees = S, e.renderAllPending = s, e.getDestinationInsertionPoints = v, e.visual = { insertBefore: n, remove: r } }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(t) { if (window[t]) { r(!e.wrappers[t]); var c = function (e) { n.call(this, e) }; c.prototype = Object.create(n.prototype), o(c.prototype, { get form() { return s(a(this).form) } }), i(window[t], c, document.createElement(t.slice(4, -7))), e.wrappers[t] = c } } var n = e.wrappers.HTMLElement, r = e.assert, o = e.mixin, i = e.registerWrapper, a = e.unwrap, s = e.wrap, c = ["HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement"]; c.forEach(t) }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { r(e, this) } var n = e.registerWrapper, r = e.setWrapper, o = e.unsafeUnwrap, i = e.unwrap, a = e.unwrapIfNeeded, s = e.wrap, c = window.Selection; t.prototype = { get anchorNode() { return s(o(this).anchorNode) }, get focusNode() { return s(o(this).focusNode) }, addRange: function (e) { o(this).addRange(a(e)) }, collapse: function (e, t) { o(this).collapse(a(e), t) }, containsNode: function (e, t) { return o(this).containsNode(a(e), t) }, getRangeAt: function (e) { return s(o(this).getRangeAt(e)) }, removeRange: function (e) { o(this).removeRange(i(e)) }, selectAllChildren: function (e) { o(this).selectAllChildren(e instanceof ShadowRoot ? o(e.host) : a(e)) }, toString: function () { return o(this).toString() } }, c.prototype.extend && (t.prototype.extend = function (e, t) { o(this).extend(a(e), t) }), n(window.Selection, t, window.getSelection()), e.wrappers.Selection = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { r(e, this) } var n = e.registerWrapper, r = e.setWrapper, o = e.unsafeUnwrap, i = e.unwrapIfNeeded, a = e.wrap, s = window.TreeWalker; t.prototype = { get root() { return a(o(this).root) }, get currentNode() { return a(o(this).currentNode) }, set currentNode(e) { o(this).currentNode = i(e) }, get filter() { return o(this).filter }, parentNode: function () { return a(o(this).parentNode()) }, firstChild: function () { return a(o(this).firstChild()) }, lastChild: function () { return a(o(this).lastChild()) }, previousSibling: function () { return a(o(this).previousSibling()) }, previousNode: function () { return a(o(this).previousNode()) }, nextNode: function () { return a(o(this).nextNode()) } }, n(s, t), e.wrappers.TreeWalker = t }(window.ShadowDOMPolyfill), function (e) { - "use strict"; function t(e) { u.call(this, e), this.treeScope_ = new w(this, null) } function n(e) { var n = document[e]; t.prototype[e] = function () { return j(n.apply(N(this), arguments)) } } function r(e, t) { x.call(N(t), C(e)), o(e, t) } function o(e, t) { e.shadowRoot && t.adoptNode(e.shadowRoot), e instanceof m && i(e, t); for (var n = e.firstChild; n; n = n.nextSibling)o(n, t) } function i(e, t) { var n = e.olderShadowRoot; n && t.adoptNode(n) } function a(e) { L(e, this) } function s(e, t) { - var n = document.implementation[t]; e.prototype[t] = function () { - return j(n.apply(N(this), arguments)) - } - } function c(e, t) { var n = document.implementation[t]; e.prototype[t] = function () { return n.apply(N(this), arguments) } } var l = e.GetElementsByInterface, u = e.wrappers.Node, d = e.ParentNodeInterface, p = e.NonElementParentNodeInterface, h = e.wrappers.Selection, f = e.SelectorsInterface, m = e.wrappers.ShadowRoot, w = e.TreeScope, v = e.cloneNode, g = e.defineGetter, b = e.defineWrapGetter, y = e.elementFromPoint, E = e.forwardMethodsToWrapper, _ = e.matchesNames, S = e.mixin, T = e.registerWrapper, M = e.renderAllPending, O = e.rewrap, L = e.setWrapper, N = e.unsafeUnwrap, C = e.unwrap, j = e.wrap, D = e.wrapEventTargetMethods, H = (e.wrapNodeList, new WeakMap); t.prototype = Object.create(u.prototype), b(t, "documentElement"), b(t, "body"), b(t, "head"), g(t, "activeElement", function () { var e = C(this).activeElement; if (!e || !e.nodeType) return null; for (var t = j(e); !this.contains(t);) { for (; t.parentNode;)t = t.parentNode; if (!t.host) return null; t = t.host } return t }), ["createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode"].forEach(n); var x = document.adoptNode, R = document.getSelection; S(t.prototype, { adoptNode: function (e) { return e.parentNode && e.parentNode.removeChild(e), r(e, this), e }, elementFromPoint: function (e, t) { return y(this, this, e, t) }, importNode: function (e, t) { return v(e, t, N(this)) }, getSelection: function () { return M(), new h(R.call(C(this))) }, getElementsByName: function (e) { return f.querySelectorAll.call(this, "[name=" + JSON.stringify(String(e)) + "]") } }); var I = document.createTreeWalker, P = e.wrappers.TreeWalker; if (t.prototype.createTreeWalker = function (e, t, n, r) { var o = null; return n && (n.acceptNode && "function" == typeof n.acceptNode ? o = { acceptNode: function (e) { return n.acceptNode(j(e)) } } : "function" == typeof n && (o = function (e) { return n(j(e)) })), new P(I.call(C(this), C(e), t, o, r)) }, document.registerElement) { var k = document.registerElement; t.prototype.registerElement = function (t, n) { function r(e) { return e ? void L(e, this) : i ? document.createElement(i, t) : document.createElement(t) } var o, i; if (void 0 !== n && (o = n.prototype, i = n["extends"]), o || (o = Object.create(HTMLElement.prototype)), e.nativePrototypeTable.get(o)) throw new Error("NotSupportedError"); for (var a, s = Object.getPrototypeOf(o), c = []; s && !(a = e.nativePrototypeTable.get(s));)c.push(s), s = Object.getPrototypeOf(s); if (!a) throw new Error("NotSupportedError"); for (var l = Object.create(a), u = c.length - 1; u >= 0; u--)l = Object.create(l);["createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback"].forEach(function (e) { var t = o[e]; t && (l[e] = function () { j(this) instanceof r || O(this), t.apply(j(this), arguments) }) }); var d = { prototype: l }; i && (d["extends"] = i), r.prototype = o, r.prototype.constructor = r, e.constructorTable.set(l, r), e.nativePrototypeTable.set(o, l); k.call(C(this), t, d); return r }, E([window.HTMLDocument || window.Document], ["registerElement"]) } E([window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement], ["appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild"]), E([window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement], _), E([window.HTMLDocument || window.Document], ["adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "createTreeWalker", "elementFromPoint", "getElementById", "getElementsByName", "getSelection"]), S(t.prototype, l), S(t.prototype, d), S(t.prototype, f), S(t.prototype, p), S(t.prototype, { get implementation() { var e = H.get(this); return e ? e : (e = new a(C(this).implementation), H.set(this, e), e) }, get defaultView() { return j(C(this).defaultView) } }), T(window.Document, t, document.implementation.createHTMLDocument("")), window.HTMLDocument && T(window.HTMLDocument, t), D([window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement]); var A = document.implementation.createDocument; a.prototype.createDocument = function () { return arguments[2] = C(arguments[2]), j(A.apply(N(this), arguments)) }, s(a, "createDocumentType"), s(a, "createHTMLDocument"), c(a, "hasFeature"), T(window.DOMImplementation, a), E([window.DOMImplementation], ["createDocument", "createDocumentType", "createHTMLDocument", "hasFeature"]), e.adoptNodeNoRemove = r, e.wrappers.DOMImplementation = a, e.wrappers.Document = t -}(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { n.call(this, e) } var n = e.wrappers.EventTarget, r = e.wrappers.Selection, o = e.mixin, i = e.registerWrapper, a = e.renderAllPending, s = e.unwrap, c = e.unwrapIfNeeded, l = e.wrap, u = window.Window, d = window.getComputedStyle, p = window.getDefaultComputedStyle, h = window.getSelection; t.prototype = Object.create(n.prototype), u.prototype.getComputedStyle = function (e, t) { return l(this || window).getComputedStyle(c(e), t) }, p && (u.prototype.getDefaultComputedStyle = function (e, t) { return l(this || window).getDefaultComputedStyle(c(e), t) }), u.prototype.getSelection = function () { return l(this || window).getSelection() }, delete window.getComputedStyle, delete window.getDefaultComputedStyle, delete window.getSelection, ["addEventListener", "removeEventListener", "dispatchEvent"].forEach(function (e) { u.prototype[e] = function () { var t = l(this || window); return t[e].apply(t, arguments) }, delete window[e] }), o(t.prototype, { getComputedStyle: function (e, t) { return a(), d.call(s(this), c(e), t) }, getSelection: function () { return a(), new r(h.call(s(this))) }, get document() { return l(s(this).document) } }), p && (t.prototype.getDefaultComputedStyle = function (e, t) { return a(), p.call(s(this), c(e), t) }), i(u, t, window), e.wrappers.Window = t }(window.ShadowDOMPolyfill), function (e) { "use strict"; var t = e.unwrap, n = window.DataTransfer || window.Clipboard, r = n.prototype.setDragImage; r && (n.prototype.setDragImage = function (e, n, o) { r.call(this, t(e), n, o) }) }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { var t; t = e instanceof i ? e : new i(e && o(e)), r(t, this) } var n = e.registerWrapper, r = e.setWrapper, o = e.unwrap, i = window.FormData; i && (n(i, t, new i), e.wrappers.FormData = t) }(window.ShadowDOMPolyfill), function (e) { "use strict"; var t = e.unwrapIfNeeded, n = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function (e) { return n.call(this, t(e)) } }(window.ShadowDOMPolyfill), function (e) { "use strict"; function t(e) { var t = n[e], r = window[t]; if (r) { var o = document.createElement(e), i = o.constructor; window[t] = i } } var n = (e.isWrapperFor, { a: "HTMLAnchorElement", area: "HTMLAreaElement", audio: "HTMLAudioElement", base: "HTMLBaseElement", body: "HTMLBodyElement", br: "HTMLBRElement", button: "HTMLButtonElement", canvas: "HTMLCanvasElement", caption: "HTMLTableCaptionElement", col: "HTMLTableColElement", content: "HTMLContentElement", data: "HTMLDataElement", datalist: "HTMLDataListElement", del: "HTMLModElement", dir: "HTMLDirectoryElement", div: "HTMLDivElement", dl: "HTMLDListElement", embed: "HTMLEmbedElement", fieldset: "HTMLFieldSetElement", font: "HTMLFontElement", form: "HTMLFormElement", frame: "HTMLFrameElement", frameset: "HTMLFrameSetElement", h1: "HTMLHeadingElement", head: "HTMLHeadElement", hr: "HTMLHRElement", html: "HTMLHtmlElement", iframe: "HTMLIFrameElement", img: "HTMLImageElement", input: "HTMLInputElement", keygen: "HTMLKeygenElement", label: "HTMLLabelElement", legend: "HTMLLegendElement", li: "HTMLLIElement", link: "HTMLLinkElement", map: "HTMLMapElement", marquee: "HTMLMarqueeElement", menu: "HTMLMenuElement", menuitem: "HTMLMenuItemElement", meta: "HTMLMetaElement", meter: "HTMLMeterElement", object: "HTMLObjectElement", ol: "HTMLOListElement", optgroup: "HTMLOptGroupElement", option: "HTMLOptionElement", output: "HTMLOutputElement", p: "HTMLParagraphElement", param: "HTMLParamElement", pre: "HTMLPreElement", progress: "HTMLProgressElement", q: "HTMLQuoteElement", script: "HTMLScriptElement", select: "HTMLSelectElement", shadow: "HTMLShadowElement", source: "HTMLSourceElement", span: "HTMLSpanElement", style: "HTMLStyleElement", table: "HTMLTableElement", tbody: "HTMLTableSectionElement", template: "HTMLTemplateElement", textarea: "HTMLTextAreaElement", thead: "HTMLTableSectionElement", time: "HTMLTimeElement", title: "HTMLTitleElement", tr: "HTMLTableRowElement", track: "HTMLTrackElement", ul: "HTMLUListElement", video: "HTMLVideoElement" }); Object.keys(n).forEach(t), Object.getOwnPropertyNames(e.wrappers).forEach(function (t) { window[t] = e.wrappers[t] }) }(window.ShadowDOMPolyfill), function (e) { function t(e, t) { var n = ""; return Array.prototype.forEach.call(e, function (e) { n += e.textContent + "\n\n" }), t || (n = n.replace(d, "")), n } function n(e) { var t = document.createElement("style"); return t.textContent = e, t } function r(e) { var t = n(e); document.head.appendChild(t); var r = []; if (t.sheet) try { r = t.sheet.cssRules } catch (o) { } else console.warn("sheet not found", t); return t.parentNode.removeChild(t), r } function o() { C.initialized = !0, document.body.appendChild(C); var e = C.contentDocument, t = e.createElement("base"); t.href = document.baseURI, e.head.appendChild(t) } function i(e) { C.initialized || o(), document.body.appendChild(C), e(C.contentDocument), document.body.removeChild(C) } function a(e, t) { if (t) { var o; if (e.match("@import") && D) { var a = n(e); i(function (e) { e.head.appendChild(a.impl), o = Array.prototype.slice.call(a.sheet.cssRules, 0), t(o) }) } else o = r(e), t(o) } } function s(e) { e && l().appendChild(document.createTextNode(e)) } function c(e, t) { var r = n(e); r.setAttribute(t, ""), r.setAttribute(x, ""), document.head.appendChild(r) } function l() { return j || (j = document.createElement("style"), j.setAttribute(x, ""), j[x] = !0), j } var u = { strictStyling: !1, registry: {}, shimStyling: function (e, n, r) { var o = this.prepareRoot(e, n, r), i = this.isTypeExtension(r), a = this.makeScopeSelector(n, i), s = t(o, !0); s = this.scopeCssText(s, a), e && (e.shimmedStyle = s), this.addCssToDocument(s, n) }, shimStyle: function (e, t) { return this.shimCssText(e.textContent, t) }, shimCssText: function (e, t) { return e = this.insertDirectives(e), this.scopeCssText(e, t) }, makeScopeSelector: function (e, t) { return e ? t ? "[is=" + e + "]" : e : "" }, isTypeExtension: function (e) { return e && e.indexOf("-") < 0 }, prepareRoot: function (e, t, n) { var r = this.registerRoot(e, t, n); return this.replaceTextInStyles(r.rootStyles, this.insertDirectives), this.removeStyles(e, r.rootStyles), this.strictStyling && this.applyScopeToContent(e, t), r.scopeStyles }, removeStyles: function (e, t) { for (var n, r = 0, o = t.length; r < o && (n = t[r]); r++)n.parentNode.removeChild(n) }, registerRoot: function (e, t, n) { var r = this.registry[t] = { root: e, name: t, extendsName: n }, o = this.findStyles(e); r.rootStyles = o, r.scopeStyles = r.rootStyles; var i = this.registry[r.extendsName]; return i && (r.scopeStyles = i.scopeStyles.concat(r.scopeStyles)), r }, findStyles: function (e) { if (!e) return []; var t = e.querySelectorAll("style"); return Array.prototype.filter.call(t, function (e) { return !e.hasAttribute(R) }) }, applyScopeToContent: function (e, t) { e && (Array.prototype.forEach.call(e.querySelectorAll("*"), function (e) { e.setAttribute(t, "") }), Array.prototype.forEach.call(e.querySelectorAll("template"), function (e) { this.applyScopeToContent(e.content, t) }, this)) }, insertDirectives: function (e) { return e = this.insertPolyfillDirectivesInCssText(e), this.insertPolyfillRulesInCssText(e) }, insertPolyfillDirectivesInCssText: function (e) { return e = e.replace(p, function (e, t) { return t.slice(0, -2) + "{" }), e.replace(h, function (e, t) { return t + " {" }) }, insertPolyfillRulesInCssText: function (e) { return e = e.replace(f, function (e, t) { return t.slice(0, -1) }), e.replace(m, function (e, t, n, r) { var o = e.replace(t, "").replace(n, ""); return r + o }) }, scopeCssText: function (e, t) { var n = this.extractUnscopedRulesFromCssText(e); if (e = this.insertPolyfillHostInCssText(e), e = this.convertColonHost(e), e = this.convertColonHostContext(e), e = this.convertShadowDOMSelectors(e), t) { var e, r = this; a(e, function (n) { e = r.scopeRules(n, t) }) } return e = e + "\n" + n, e.trim() }, extractUnscopedRulesFromCssText: function (e) { for (var t, n = ""; t = w.exec(e);)n += t[1].slice(0, -1) + "\n\n"; for (; t = v.exec(e);)n += t[0].replace(t[2], "").replace(t[1], t[3]) + "\n\n"; return n }, convertColonHost: function (e) { return this.convertColonRule(e, E, this.colonHostPartReplacer) }, convertColonHostContext: function (e) { return this.convertColonRule(e, _, this.colonHostContextPartReplacer) }, convertColonRule: function (e, t, n) { return e.replace(t, function (e, t, r, o) { if (t = O, r) { for (var i, a = r.split(","), s = [], c = 0, l = a.length; c < l && (i = a[c]); c++)i = i.trim(), s.push(n(t, i, o)); return s.join(",") } return t + o }) }, colonHostContextPartReplacer: function (e, t, n) { return t.match(g) ? this.colonHostPartReplacer(e, t, n) : e + t + n + ", " + t + " " + e + n }, colonHostPartReplacer: function (e, t, n) { return e + t.replace(g, "") + n }, convertShadowDOMSelectors: function (e) { for (var t = 0; t < N.length; t++)e = e.replace(N[t], " "); return e }, scopeRules: function (e, t) { var n = ""; return e && Array.prototype.forEach.call(e, function (e) { if (e.selectorText && e.style && void 0 !== e.style.cssText) n += this.scopeSelector(e.selectorText, t, this.strictStyling) + " {\n\t", n += this.propertiesFromRule(e) + "\n}\n\n"; else if (e.type === CSSRule.MEDIA_RULE) n += "@media " + e.media.mediaText + " {\n", n += this.scopeRules(e.cssRules, t), n += "\n}\n\n"; else try { e.cssText && (n += e.cssText + "\n\n") } catch (r) { e.type === CSSRule.KEYFRAMES_RULE && e.cssRules && (n += this.ieSafeCssTextFromKeyFrameRule(e)) } }, this), n }, ieSafeCssTextFromKeyFrameRule: function (e) { var t = "@keyframes " + e.name + " {"; return Array.prototype.forEach.call(e.cssRules, function (e) { t += " " + e.keyText + " {" + e.style.cssText + "}" }), t += " }" }, scopeSelector: function (e, t, n) { var r = [], o = e.split(","); return o.forEach(function (e) { e = e.trim(), this.selectorNeedsScoping(e, t) && (e = n && !e.match(O) ? this.applyStrictSelectorScope(e, t) : this.applySelectorScope(e, t)), r.push(e) }, this), r.join(", ") }, selectorNeedsScoping: function (e, t) { if (Array.isArray(t)) return !0; var n = this.makeScopeMatcher(t); return !e.match(n) }, makeScopeMatcher: function (e) { return e = e.replace(/\[/g, "\\[").replace(/\]/g, "\\]"), new RegExp("^(" + e + ")" + S, "m") }, applySelectorScope: function (e, t) { return Array.isArray(t) ? this.applySelectorScopeList(e, t) : this.applySimpleSelectorScope(e, t) }, applySelectorScopeList: function (e, t) { for (var n, r = [], o = 0; n = t[o]; o++)r.push(this.applySimpleSelectorScope(e, n)); return r.join(", ") }, applySimpleSelectorScope: function (e, t) { return e.match(L) ? (e = e.replace(O, t), e.replace(L, t + " ")) : t + " " + e }, applyStrictSelectorScope: function (e, t) { t = t.replace(/\[is=([^\]]*)\]/g, "$1"); var n = [" ", ">", "+", "~"], r = e, o = "[" + t + "]"; return n.forEach(function (e) { var t = r.split(e); r = t.map(function (e) { var t = e.trim().replace(L, ""); return t && n.indexOf(t) < 0 && t.indexOf(o) < 0 && (e = t.replace(/([^:]*)(:*)(.*)/, "$1" + o + "$2$3")), e }).join(e) }), r }, insertPolyfillHostInCssText: function (e) { return e.replace(M, b).replace(T, g) }, propertiesFromRule: function (e) { var t = e.style.cssText; e.style.content && !e.style.content.match(/['"]+|attr/) && (t = t.replace(/content:[^;]*;/g, "content: '" + e.style.content + "';")); var n = e.style; for (var r in n) "initial" === n[r] && (t += r + ": initial; "); return t }, replaceTextInStyles: function (e, t) { e && t && (e instanceof Array || (e = [e]), Array.prototype.forEach.call(e, function (e) { e.textContent = t.call(this, e.textContent) }, this)) }, addCssToDocument: function (e, t) { e.match("@import") ? c(e, t) : s(e) } }, d = /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, p = /\/\*\s*@polyfill ([^*]*\*+([^\/*][^*]*\*+)*\/)([^{]*?){/gim, h = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim, f = /\/\*\s@polyfill-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, m = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, w = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, v = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, g = "-shadowcsshost", b = "-shadowcsscontext", y = ")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)", E = new RegExp("(" + g + y, "gim"), _ = new RegExp("(" + b + y, "gim"), S = "([>\\s~+[.,{:][\\s\\S]*)?$", T = /\:host/gim, M = /\:host-context/gim, O = g + "-no-combinator", L = new RegExp(g, "gim"), N = (new RegExp(b, "gim"), [/>>>/g, /::shadow/g, /::content/g, /\/deep\//g, /\/shadow\//g, /\/shadow-deep\//g, /\^\^/g, /\^(?!=)/g]), C = document.createElement("iframe"); C.style.display = "none"; var j, D = navigator.userAgent.match("Chrome"), H = "shim-shadowdom", x = "shim-shadowdom-css", R = "no-shim"; if (window.ShadowDOMPolyfill) { s("style { display: none !important; }\n"); var I = ShadowDOMPolyfill.wrap(document), P = I.querySelector("head"); P.insertBefore(l(), P.childNodes[0]), document.addEventListener("DOMContentLoaded", function () { e.urlResolver; if (window.HTMLImports && !HTMLImports.useNative) { var t = "link[rel=stylesheet][" + H + "]", n = "style[" + H + "]"; HTMLImports.importer.documentPreloadSelectors += "," + t, HTMLImports.importer.importsPreloadSelectors += "," + t, HTMLImports.parser.documentSelectors = [HTMLImports.parser.documentSelectors, t, n].join(","); var r = HTMLImports.parser.parseGeneric; HTMLImports.parser.parseGeneric = function (e) { if (!e[x]) { var t = e.__importElement || e; if (!t.hasAttribute(H)) return void r.call(this, e); e.__resource && (t = e.ownerDocument.createElement("style"), t.textContent = e.__resource), HTMLImports.path.resolveUrlsInStyle(t, e.href), t.textContent = u.shimStyle(t), t.removeAttribute(H, ""), t.setAttribute(x, ""), t[x] = !0, t.parentNode !== P && (e.parentNode === P ? P.replaceChild(t, e) : this.addElementToDocument(t)), t.__importParsed = !0, this.markParsingComplete(e), this.parseNext() } }; var o = HTMLImports.parser.hasResource; HTMLImports.parser.hasResource = function (e) { return "link" === e.localName && "stylesheet" === e.rel && e.hasAttribute(H) ? e.__resource : o.call(this, e) } } }) } e.ShadowCSS = u }(window.WebComponents)), function (e) { window.ShadowDOMPolyfill ? (window.wrap = ShadowDOMPolyfill.wrapIfNeeded, window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded) : window.wrap = window.unwrap = function (e) { return e } }(window.WebComponents), function (e) { "use strict"; function t(e) { return void 0 !== p[e] } function n() { s.call(this), this._isInvalid = !0 } function r(e) { return "" == e && n.call(this), e.toLowerCase() } function o(e) { var t = e.charCodeAt(0); return t > 32 && t < 127 && [34, 35, 60, 62, 63, 96].indexOf(t) == -1 ? e : encodeURIComponent(e) } function i(e) { var t = e.charCodeAt(0); return t > 32 && t < 127 && [34, 35, 60, 62, 96].indexOf(t) == -1 ? e : encodeURIComponent(e) } function a(e, a, s) { function c(e) { b.push(e) } var l = a || "scheme start", u = 0, d = "", v = !1, g = !1, b = []; e: for (; (e[u - 1] != f || 0 == u) && !this._isInvalid;) { var y = e[u]; switch (l) { case "scheme start": if (!y || !m.test(y)) { if (a) { c("Invalid scheme."); break e } d = "", l = "no scheme"; continue } d += y.toLowerCase(), l = "scheme"; break; case "scheme": if (y && w.test(y)) d += y.toLowerCase(); else { if (":" != y) { if (a) { if (f == y) break e; c("Code point not allowed in scheme: " + y); break e } d = "", u = 0, l = "no scheme"; continue } if (this._scheme = d, d = "", a) break e; t(this._scheme) && (this._isRelative = !0), l = "file" == this._scheme ? "relative" : this._isRelative && s && s._scheme == this._scheme ? "relative or authority" : this._isRelative ? "authority first slash" : "scheme data" } break; case "scheme data": "?" == y ? (this._query = "?", l = "query") : "#" == y ? (this._fragment = "#", l = "fragment") : f != y && "\t" != y && "\n" != y && "\r" != y && (this._schemeData += o(y)); break; case "no scheme": if (s && t(s._scheme)) { l = "relative"; continue } c("Missing scheme."), n.call(this); break; case "relative or authority": if ("/" != y || "/" != e[u + 1]) { c("Expected /, got: " + y), l = "relative"; continue } l = "authority ignore slashes"; break; case "relative": if (this._isRelative = !0, "file" != this._scheme && (this._scheme = s._scheme), f == y) { this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = s._query, this._username = s._username, this._password = s._password; break e } if ("/" == y || "\\" == y) "\\" == y && c("\\ is an invalid code point."), l = "relative slash"; else if ("?" == y) this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = "?", this._username = s._username, this._password = s._password, l = "query"; else { if ("#" != y) { var E = e[u + 1], _ = e[u + 2]; ("file" != this._scheme || !m.test(y) || ":" != E && "|" != E || f != _ && "/" != _ && "\\" != _ && "?" != _ && "#" != _) && (this._host = s._host, this._port = s._port, this._username = s._username, this._password = s._password, this._path = s._path.slice(), this._path.pop()), l = "relative path"; continue } this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = s._query, this._fragment = "#", this._username = s._username, this._password = s._password, l = "fragment" } break; case "relative slash": if ("/" != y && "\\" != y) { "file" != this._scheme && (this._host = s._host, this._port = s._port, this._username = s._username, this._password = s._password), l = "relative path"; continue } "\\" == y && c("\\ is an invalid code point."), l = "file" == this._scheme ? "file host" : "authority ignore slashes"; break; case "authority first slash": if ("/" != y) { c("Expected '/', got: " + y), l = "authority ignore slashes"; continue } l = "authority second slash"; break; case "authority second slash": if (l = "authority ignore slashes", "/" != y) { c("Expected '/', got: " + y); continue } break; case "authority ignore slashes": if ("/" != y && "\\" != y) { l = "authority"; continue } c("Expected authority, got: " + y); break; case "authority": if ("@" == y) { v && (c("@ already seen."), d += "%40"), v = !0; for (var S = 0; S < d.length; S++) { var T = d[S]; if ("\t" != T && "\n" != T && "\r" != T) if (":" != T || null !== this._password) { var M = o(T); null !== this._password ? this._password += M : this._username += M } else this._password = ""; else c("Invalid whitespace in authority.") } d = "" } else { if (f == y || "/" == y || "\\" == y || "?" == y || "#" == y) { u -= d.length, d = "", l = "host"; continue } d += y } break; case "file host": if (f == y || "/" == y || "\\" == y || "?" == y || "#" == y) { 2 != d.length || !m.test(d[0]) || ":" != d[1] && "|" != d[1] ? 0 == d.length ? l = "relative path start" : (this._host = r.call(this, d), d = "", l = "relative path start") : l = "relative path"; continue } "\t" == y || "\n" == y || "\r" == y ? c("Invalid whitespace in file host.") : d += y; break; case "host": case "hostname": if (":" != y || g) { if (f == y || "/" == y || "\\" == y || "?" == y || "#" == y) { if (this._host = r.call(this, d), d = "", l = "relative path start", a) break e; continue } "\t" != y && "\n" != y && "\r" != y ? ("[" == y ? g = !0 : "]" == y && (g = !1), d += y) : c("Invalid code point in host/hostname: " + y) } else if (this._host = r.call(this, d), d = "", l = "port", "hostname" == a) break e; break; case "port": if (/[0-9]/.test(y)) d += y; else { if (f == y || "/" == y || "\\" == y || "?" == y || "#" == y || a) { if ("" != d) { var O = parseInt(d, 10); O != p[this._scheme] && (this._port = O + ""), d = "" } if (a) break e; l = "relative path start"; continue } "\t" == y || "\n" == y || "\r" == y ? c("Invalid code point in port: " + y) : n.call(this) } break; case "relative path start": if ("\\" == y && c("'\\' not allowed in path."), l = "relative path", "/" != y && "\\" != y) continue; break; case "relative path": if (f != y && "/" != y && "\\" != y && (a || "?" != y && "#" != y)) "\t" != y && "\n" != y && "\r" != y && (d += o(y)); else { "\\" == y && c("\\ not allowed in relative path."); var L; (L = h[d.toLowerCase()]) && (d = L), ".." == d ? (this._path.pop(), "/" != y && "\\" != y && this._path.push("")) : "." == d && "/" != y && "\\" != y ? this._path.push("") : "." != d && ("file" == this._scheme && 0 == this._path.length && 2 == d.length && m.test(d[0]) && "|" == d[1] && (d = d[0] + ":"), this._path.push(d)), d = "", "?" == y ? (this._query = "?", l = "query") : "#" == y && (this._fragment = "#", l = "fragment") } break; case "query": a || "#" != y ? f != y && "\t" != y && "\n" != y && "\r" != y && (this._query += i(y)) : (this._fragment = "#", l = "fragment"); break; case "fragment": f != y && "\t" != y && "\n" != y && "\r" != y && (this._fragment += y) }u++ } } function s() { this._scheme = "", this._schemeData = "", this._username = "", this._password = null, this._host = "", this._port = "", this._path = [], this._query = "", this._fragment = "", this._isInvalid = !1, this._isRelative = !1 } function c(e, t) { void 0 === t || t instanceof c || (t = new c(String(t))), this._url = e, s.call(this); var n = e.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, ""); a.call(this, n, null, t) } var l = !1; if (!e.forceJURL) try { var u = new URL("b", "http://a"); u.pathname = "c%20d", l = "http://a/c%20d" === u.href } catch (d) { } if (!l) { var p = Object.create(null); p.ftp = 21, p.file = 0, p.gopher = 70, p.http = 80, p.https = 443, p.ws = 80, p.wss = 443; var h = Object.create(null); h["%2e"] = ".", h[".%2e"] = "..", h["%2e."] = "..", h["%2e%2e"] = ".."; var f = void 0, m = /[a-zA-Z]/, w = /[a-zA-Z0-9\+\-\.]/; c.prototype = { toString: function () { return this.href }, get href() { if (this._isInvalid) return this._url; var e = ""; return "" == this._username && null == this._password || (e = this._username + (null != this._password ? ":" + this._password : "") + "@"), this.protocol + (this._isRelative ? "//" + e + this.host : "") + this.pathname + this._query + this._fragment }, set href(e) { s.call(this), a.call(this, e) }, get protocol() { return this._scheme + ":" }, set protocol(e) { this._isInvalid || a.call(this, e + ":", "scheme start") }, get host() { return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host }, set host(e) { !this._isInvalid && this._isRelative && a.call(this, e, "host") }, get hostname() { return this._host }, set hostname(e) { !this._isInvalid && this._isRelative && a.call(this, e, "hostname") }, get port() { return this._port }, set port(e) { !this._isInvalid && this._isRelative && a.call(this, e, "port") }, get pathname() { return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData }, set pathname(e) { !this._isInvalid && this._isRelative && (this._path = [], a.call(this, e, "relative path start")) }, get search() { return this._isInvalid || !this._query || "?" == this._query ? "" : this._query }, set search(e) { !this._isInvalid && this._isRelative && (this._query = "?", "?" == e[0] && (e = e.slice(1)), a.call(this, e, "query")) }, get hash() { return this._isInvalid || !this._fragment || "#" == this._fragment ? "" : this._fragment }, set hash(e) { this._isInvalid || (this._fragment = "#", "#" == e[0] && (e = e.slice(1)), a.call(this, e, "fragment")) }, get origin() { var e; if (this._isInvalid || !this._scheme) return ""; switch (this._scheme) { case "data": case "file": case "javascript": case "mailto": return "null" }return e = this.host, e ? this._scheme + "://" + e : "" } }; var v = e.URL; v && (c.createObjectURL = function (e) { return v.createObjectURL.apply(v, arguments) }, c.revokeObjectURL = function (e) { v.revokeObjectURL(e) }), e.URL = c } }(self), function (e) { function t(e) { y.push(e), b || (b = !0, m(r)) } function n(e) { return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(e) || e } function r() { b = !1; var e = y; y = [], e.sort(function (e, t) { return e.uid_ - t.uid_ }); var t = !1; e.forEach(function (e) { var n = e.takeRecords(); o(e), n.length && (e.callback_(n, e), t = !0) }), t && r() } function o(e) { e.nodes_.forEach(function (t) { var n = w.get(t); n && n.forEach(function (t) { t.observer === e && t.removeTransientObservers() }) }) } function i(e, t) { for (var n = e; n; n = n.parentNode) { var r = w.get(n); if (r) for (var o = 0; o < r.length; o++) { var i = r[o], a = i.options; if (n === e || a.subtree) { var s = t(a); s && i.enqueue(s) } } } } function a(e) { this.callback_ = e, this.nodes_ = [], this.records_ = [], this.uid_ = ++E } function s(e, t) { this.type = e, this.target = t, this.addedNodes = [], this.removedNodes = [], this.previousSibling = null, this.nextSibling = null, this.attributeName = null, this.attributeNamespace = null, this.oldValue = null } function c(e) { var t = new s(e.type, e.target); return t.addedNodes = e.addedNodes.slice(), t.removedNodes = e.removedNodes.slice(), t.previousSibling = e.previousSibling, t.nextSibling = e.nextSibling, t.attributeName = e.attributeName, t.attributeNamespace = e.attributeNamespace, t.oldValue = e.oldValue, t } function l(e, t) { return _ = new s(e, t) } function u(e) { return S ? S : (S = c(_), S.oldValue = e, S) } function d() { _ = S = void 0 } function p(e) { return e === S || e === _ } function h(e, t) { return e === t ? e : S && p(e) ? S : null } function f(e, t, n) { this.observer = e, this.target = t, this.options = n, this.transientObservedNodes = [] } if (!e.JsMutationObserver) { var m, w = new WeakMap; if (/Trident|Edge/.test(navigator.userAgent)) m = setTimeout; else if (window.setImmediate) m = window.setImmediate; else { var v = [], g = String(Math.random()); window.addEventListener("message", function (e) { if (e.data === g) { var t = v; v = [], t.forEach(function (e) { e() }) } }), m = function (e) { v.push(e), window.postMessage(g, "*") } } var b = !1, y = [], E = 0; a.prototype = { observe: function (e, t) { if (e = n(e), !t.childList && !t.attributes && !t.characterData || t.attributeOldValue && !t.attributes || t.attributeFilter && t.attributeFilter.length && !t.attributes || t.characterDataOldValue && !t.characterData) throw new SyntaxError; var r = w.get(e); r || w.set(e, r = []); for (var o, i = 0; i < r.length; i++)if (r[i].observer === this) { o = r[i], o.removeListeners(), o.options = t; break } o || (o = new f(this, e, t), r.push(o), this.nodes_.push(e)), o.addListeners() }, disconnect: function () { this.nodes_.forEach(function (e) { for (var t = w.get(e), n = 0; n < t.length; n++) { var r = t[n]; if (r.observer === this) { r.removeListeners(), t.splice(n, 1); break } } }, this), this.records_ = [] }, takeRecords: function () { var e = this.records_; return this.records_ = [], e } }; var _, S; f.prototype = { enqueue: function (e) { var n = this.observer.records_, r = n.length; if (n.length > 0) { var o = n[r - 1], i = h(o, e); if (i) return void (n[r - 1] = i) } else t(this.observer); n[r] = e }, addListeners: function () { this.addListeners_(this.target) }, addListeners_: function (e) { var t = this.options; t.attributes && e.addEventListener("DOMAttrModified", this, !0), t.characterData && e.addEventListener("DOMCharacterDataModified", this, !0), t.childList && e.addEventListener("DOMNodeInserted", this, !0), (t.childList || t.subtree) && e.addEventListener("DOMNodeRemoved", this, !0) }, removeListeners: function () { this.removeListeners_(this.target) }, removeListeners_: function (e) { var t = this.options; t.attributes && e.removeEventListener("DOMAttrModified", this, !0), t.characterData && e.removeEventListener("DOMCharacterDataModified", this, !0), t.childList && e.removeEventListener("DOMNodeInserted", this, !0), (t.childList || t.subtree) && e.removeEventListener("DOMNodeRemoved", this, !0) }, addTransientObserver: function (e) { if (e !== this.target) { this.addListeners_(e), this.transientObservedNodes.push(e); var t = w.get(e); t || w.set(e, t = []), t.push(this) } }, removeTransientObservers: function () { var e = this.transientObservedNodes; this.transientObservedNodes = [], e.forEach(function (e) { this.removeListeners_(e); for (var t = w.get(e), n = 0; n < t.length; n++)if (t[n] === this) { t.splice(n, 1); break } }, this) }, handleEvent: function (e) { switch (e.stopImmediatePropagation(), e.type) { case "DOMAttrModified": var t = e.attrName, n = e.relatedNode.namespaceURI, r = e.target, o = new l("attributes", r); o.attributeName = t, o.attributeNamespace = n; var a = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue; i(r, function (e) { if (e.attributes && (!e.attributeFilter || !e.attributeFilter.length || e.attributeFilter.indexOf(t) !== -1 || e.attributeFilter.indexOf(n) !== -1)) return e.attributeOldValue ? u(a) : o }); break; case "DOMCharacterDataModified": var r = e.target, o = l("characterData", r), a = e.prevValue; i(r, function (e) { if (e.characterData) return e.characterDataOldValue ? u(a) : o }); break; case "DOMNodeRemoved": this.addTransientObserver(e.target); case "DOMNodeInserted": var s, c, p = e.target; "DOMNodeInserted" === e.type ? (s = [p], c = []) : (s = [], c = [p]); var h = p.previousSibling, f = p.nextSibling, o = l("childList", e.target.parentNode); o.addedNodes = s, o.removedNodes = c, o.previousSibling = h, o.nextSibling = f, i(e.relatedNode, function (e) { if (e.childList) return o }) }d() } }, e.JsMutationObserver = a, e.MutationObserver || (e.MutationObserver = a, a._isPolyfilled = !0) } }(self), function (e) { "use strict"; if (!window.performance || !window.performance.now) { var t = Date.now(); window.performance = { now: function () { return Date.now() - t } } } window.requestAnimationFrame || (window.requestAnimationFrame = function () { var e = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; return e ? function (t) { return e(function () { t(performance.now()) }) } : function (e) { return window.setTimeout(e, 1e3 / 60) } }()), window.cancelAnimationFrame || (window.cancelAnimationFrame = function () { return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function (e) { clearTimeout(e) } }()); var n = function () { var e = document.createEvent("Event"); return e.initEvent("foo", !0, !0), e.preventDefault(), e.defaultPrevented }(); if (!n) { var r = Event.prototype.preventDefault; Event.prototype.preventDefault = function () { this.cancelable && (r.call(this), Object.defineProperty(this, "defaultPrevented", { get: function () { return !0 }, configurable: !0 })) } } var o = /Trident/.test(navigator.userAgent); if ((!window.CustomEvent || o && "function" != typeof window.CustomEvent) && (window.CustomEvent = function (e, t) { t = t || {}; var n = document.createEvent("CustomEvent"); return n.initCustomEvent(e, Boolean(t.bubbles), Boolean(t.cancelable), t.detail), n }, window.CustomEvent.prototype = window.Event.prototype), !window.Event || o && "function" != typeof window.Event) { var i = window.Event; window.Event = function (e, t) { t = t || {}; var n = document.createEvent("Event"); return n.initEvent(e, Boolean(t.bubbles), Boolean(t.cancelable)), n }, window.Event.prototype = i.prototype } }(window.WebComponents), window.HTMLImports = window.HTMLImports || { flags: {} }, function (e) { - function t(e, t) { t = t || f, r(function () { i(e, t) }, t) } function n(e) { return "complete" === e.readyState || e.readyState === v } function r(e, t) { if (n(t)) e && e(); else { var o = function () { "complete" !== t.readyState && t.readyState !== v || (t.removeEventListener(g, o), r(e, t)) }; t.addEventListener(g, o) } } function o(e) { e.target.__loaded = !0 } function i(e, t) { - function n() { c == l && e && e({ allImports: s, loadedImports: u, errorImports: d }) } function r(e) { o(e), u.push(this), c++, n() } function i(e) { - d.push(this), c++, n() - } var s = t.querySelectorAll("link[rel=import]"), c = 0, l = s.length, u = [], d = []; if (l) for (var p, h = 0; h < l && (p = s[h]); h++)a(p) ? (u.push(this), c++, n()) : (p.addEventListener("load", r), p.addEventListener("error", i)); else n() - } function a(e) { return d ? e.__loaded || e["import"] && "loading" !== e["import"].readyState : e.__importParsed } function s(e) { for (var t, n = 0, r = e.length; n < r && (t = e[n]); n++)c(t) && l(t) } function c(e) { return "link" === e.localName && "import" === e.rel } function l(e) { var t = e["import"]; t ? o({ target: e }) : (e.addEventListener("load", o), e.addEventListener("error", o)) } var u = "import", d = Boolean(u in document.createElement("link")), p = Boolean(window.ShadowDOMPolyfill), h = function (e) { return p ? window.ShadowDOMPolyfill.wrapIfNeeded(e) : e }, f = h(document), m = { get: function () { var e = window.HTMLImports.currentScript || document.currentScript || ("complete" !== document.readyState ? document.scripts[document.scripts.length - 1] : null); return h(e) }, configurable: !0 }; Object.defineProperty(document, "_currentScript", m), Object.defineProperty(f, "_currentScript", m); var w = /Trident/.test(navigator.userAgent), v = w ? "complete" : "interactive", g = "readystatechange"; d && (new MutationObserver(function (e) { for (var t, n = 0, r = e.length; n < r && (t = e[n]); n++)t.addedNodes && s(t.addedNodes) }).observe(document.head, { childList: !0 }), function () { if ("loading" === document.readyState) for (var e, t = document.querySelectorAll("link[rel=import]"), n = 0, r = t.length; n < r && (e = t[n]); n++)l(e) }()), t(function (e) { window.HTMLImports.ready = !0, window.HTMLImports.readyTime = (new Date).getTime(); var t = f.createEvent("CustomEvent"); t.initCustomEvent("HTMLImportsLoaded", !0, !0, e), f.dispatchEvent(t) }), e.IMPORT_LINK_TYPE = u, e.useNative = d, e.rootDocument = f, e.whenReady = t, e.isIE = w -}(window.HTMLImports), function (e) { var t = [], n = function (e) { t.push(e) }, r = function () { t.forEach(function (t) { t(e) }) }; e.addModule = n, e.initializeModules = r }(window.HTMLImports), window.HTMLImports.addModule(function (e) { var t = /(url\()([^)]*)(\))/g, n = /(@import[\s]+(?!url\())([^;]*)(;)/g, r = { resolveUrlsInStyle: function (e, t) { var n = e.ownerDocument, r = n.createElement("a"); return e.textContent = this.resolveUrlsInCssText(e.textContent, t, r), e }, resolveUrlsInCssText: function (e, r, o) { var i = this.replaceUrls(e, o, r, t); return i = this.replaceUrls(i, o, r, n) }, replaceUrls: function (e, t, n, r) { return e.replace(r, function (e, r, o, i) { var a = o.replace(/["']/g, ""); return n && (a = new URL(a, n).href), t.href = a, a = t.href, r + "'" + a + "'" + i }) } }; e.path = r }), window.HTMLImports.addModule(function (e) { var t = { async: !0, ok: function (e) { return e.status >= 200 && e.status < 300 || 304 === e.status || 0 === e.status }, load: function (n, r, o) { var i = new XMLHttpRequest; return (e.flags.debug || e.flags.bust) && (n += "?" + Math.random()), i.open("GET", n, t.async), i.addEventListener("readystatechange", function (e) { if (4 === i.readyState) { var n = null; try { var a = i.getResponseHeader("Location"); a && (n = "/" === a.substr(0, 1) ? location.origin + a : a) } catch (e) { console.error(e.message) } r.call(o, !t.ok(i) && i, i.response || i.responseText, n) } }), i.send(), i }, loadDocument: function (e, t, n) { this.load(e, t, n).responseType = "document" } }; e.xhr = t }), window.HTMLImports.addModule(function (e) { var t = e.xhr, n = e.flags, r = function (e, t) { this.cache = {}, this.onload = e, this.oncomplete = t, this.inflight = 0, this.pending = {} }; r.prototype = { addNodes: function (e) { this.inflight += e.length; for (var t, n = 0, r = e.length; n < r && (t = e[n]); n++)this.require(t); this.checkDone() }, addNode: function (e) { this.inflight++, this.require(e), this.checkDone() }, require: function (e) { var t = e.src || e.href; e.__nodeUrl = t, this.dedupe(t, e) || this.fetch(t, e) }, dedupe: function (e, t) { if (this.pending[e]) return this.pending[e].push(t), !0; return this.cache[e] ? (this.onload(e, t, this.cache[e]), this.tail(), !0) : (this.pending[e] = [t], !1) }, fetch: function (e, r) { if (n.load && console.log("fetch", e, r), e) if (e.match(/^data:/)) { var o = e.split(","), i = o[0], a = o[1]; a = i.indexOf(";base64") > -1 ? atob(a) : decodeURIComponent(a), setTimeout(function () { this.receive(e, r, null, a) }.bind(this), 0) } else { var s = function (t, n, o) { this.receive(e, r, t, n, o) }.bind(this); t.load(e, s) } else setTimeout(function () { this.receive(e, r, { error: "href must be specified" }, null) }.bind(this), 0) }, receive: function (e, t, n, r, o) { this.cache[e] = r; for (var i, a = this.pending[e], s = 0, c = a.length; s < c && (i = a[s]); s++)this.onload(e, i, r, n, o), this.tail(); this.pending[e] = null }, tail: function () { --this.inflight, this.checkDone() }, checkDone: function () { this.inflight || this.oncomplete() } }, e.Loader = r }), window.HTMLImports.addModule(function (e) { var t = function (e) { this.addCallback = e, this.mo = new MutationObserver(this.handler.bind(this)) }; t.prototype = { handler: function (e) { for (var t, n = 0, r = e.length; n < r && (t = e[n]); n++)"childList" === t.type && t.addedNodes.length && this.addedNodes(t.addedNodes) }, addedNodes: function (e) { this.addCallback && this.addCallback(e); for (var t, n = 0, r = e.length; n < r && (t = e[n]); n++)t.children && t.children.length && this.addedNodes(t.children) }, observe: function (e) { this.mo.observe(e, { childList: !0, subtree: !0 }) } }, e.Observer = t }), window.HTMLImports.addModule(function (e) { function t(e) { return "link" === e.localName && e.rel === u } function n(e) { var t = r(e); return "data:text/javascript;charset=utf-8," + encodeURIComponent(t) } function r(e) { return e.textContent + o(e) } function o(e) { var t = e.ownerDocument; t.__importedScripts = t.__importedScripts || 0; var n = e.ownerDocument.baseURI, r = t.__importedScripts ? "-" + t.__importedScripts : ""; return t.__importedScripts++, "\n//# sourceURL=" + n + r + ".js\n" } function i(e) { var t = e.ownerDocument.createElement("style"); return t.textContent = e.textContent, a.resolveUrlsInStyle(t), t } var a = e.path, s = e.rootDocument, c = e.flags, l = e.isIE, u = e.IMPORT_LINK_TYPE, d = "link[rel=" + u + "]", p = { documentSelectors: d, importsSelectors: [d, "link[rel=stylesheet]:not([type])", "style:not([type])", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]'].join(","), map: { link: "parseLink", script: "parseScript", style: "parseStyle" }, dynamicElements: [], parseNext: function () { var e = this.nextToParse(); e && this.parse(e) }, parse: function (e) { if (this.isParsed(e)) return void (c.parse && console.log("[%s] is already parsed", e.localName)); var t = this[this.map[e.localName]]; t && (this.markParsing(e), t.call(this, e)) }, parseDynamic: function (e, t) { this.dynamicElements.push(e), t || this.parseNext() }, markParsing: function (e) { c.parse && console.log("parsing", e), this.parsingElement = e }, markParsingComplete: function (e) { e.__importParsed = !0, this.markDynamicParsingComplete(e), e.__importElement && (e.__importElement.__importParsed = !0, this.markDynamicParsingComplete(e.__importElement)), this.parsingElement = null, c.parse && console.log("completed", e) }, markDynamicParsingComplete: function (e) { var t = this.dynamicElements.indexOf(e); t >= 0 && this.dynamicElements.splice(t, 1) }, parseImport: function (e) { if (e["import"] = e.__doc, window.HTMLImports.__importsParsingHook && window.HTMLImports.__importsParsingHook(e), e["import"] && (e["import"].__importParsed = !0), this.markParsingComplete(e), e.__resource && !e.__error ? e.dispatchEvent(new CustomEvent("load", { bubbles: !1 })) : e.dispatchEvent(new CustomEvent("error", { bubbles: !1 })), e.__pending) for (var t; e.__pending.length;)t = e.__pending.shift(), t && t({ target: e }); this.parseNext() }, parseLink: function (e) { t(e) ? this.parseImport(e) : (e.href = e.href, this.parseGeneric(e)) }, parseStyle: function (e) { var t = e; e = i(e), t.__appliedElement = e, e.__importElement = t, this.parseGeneric(e) }, parseGeneric: function (e) { this.trackElement(e), this.addElementToDocument(e) }, rootImportForElement: function (e) { for (var t = e; t.ownerDocument.__importLink;)t = t.ownerDocument.__importLink; return t }, addElementToDocument: function (e) { var t = this.rootImportForElement(e.__importElement || e); t.parentNode.insertBefore(e, t) }, trackElement: function (e, t) { var n = this, r = function (o) { e.removeEventListener("load", r), e.removeEventListener("error", r), t && t(o), n.markParsingComplete(e), n.parseNext() }; if (e.addEventListener("load", r), e.addEventListener("error", r), l && "style" === e.localName) { var o = !1; if (e.textContent.indexOf("@import") == -1) o = !0; else if (e.sheet) { o = !0; for (var i, a = e.sheet.cssRules, s = a ? a.length : 0, c = 0; c < s && (i = a[c]); c++)i.type === CSSRule.IMPORT_RULE && (o = o && Boolean(i.styleSheet)) } o && setTimeout(function () { e.dispatchEvent(new CustomEvent("load", { bubbles: !1 })) }) } }, parseScript: function (t) { var r = document.createElement("script"); r.__importElement = t, r.src = t.src ? t.src : n(t), e.currentScript = t, this.trackElement(r, function (t) { r.parentNode && r.parentNode.removeChild(r), e.currentScript = null }), this.addElementToDocument(r) }, nextToParse: function () { return this._mayParse = [], !this.parsingElement && (this.nextToParseInDoc(s) || this.nextToParseDynamic()) }, nextToParseInDoc: function (e, n) { if (e && this._mayParse.indexOf(e) < 0) { this._mayParse.push(e); for (var r, o = e.querySelectorAll(this.parseSelectorsForNode(e)), i = 0, a = o.length; i < a && (r = o[i]); i++)if (!this.isParsed(r)) return this.hasResource(r) ? t(r) ? this.nextToParseInDoc(r.__doc, r) : r : void 0 } return n }, nextToParseDynamic: function () { return this.dynamicElements[0] }, parseSelectorsForNode: function (e) { var t = e.ownerDocument || e; return t === s ? this.documentSelectors : this.importsSelectors }, isParsed: function (e) { return e.__importParsed }, needsDynamicParsing: function (e) { return this.dynamicElements.indexOf(e) >= 0 }, hasResource: function (e) { return !t(e) || void 0 !== e.__doc } }; e.parser = p, e.IMPORT_SELECTOR = d }), window.HTMLImports.addModule(function (e) { function t(e) { return n(e, a) } function n(e, t) { return "link" === e.localName && e.getAttribute("rel") === t } function r(e) { return !!Object.getOwnPropertyDescriptor(e, "baseURI") } function o(e, t) { var n = document.implementation.createHTMLDocument(a); n._URL = t; var o = n.createElement("base"); o.setAttribute("href", t), n.baseURI || r(n) || Object.defineProperty(n, "baseURI", { value: t }); var i = n.createElement("meta"); return i.setAttribute("charset", "utf-8"), n.head.appendChild(i), n.head.appendChild(o), n.body.innerHTML = e, window.HTMLTemplateElement && HTMLTemplateElement.bootstrap && HTMLTemplateElement.bootstrap(n), n } var i = e.flags, a = e.IMPORT_LINK_TYPE, s = e.IMPORT_SELECTOR, c = e.rootDocument, l = e.Loader, u = e.Observer, d = e.parser, p = { documents: {}, documentPreloadSelectors: s, importsPreloadSelectors: [s].join(","), loadNode: function (e) { h.addNode(e) }, loadSubtree: function (e) { var t = this.marshalNodes(e); h.addNodes(t) }, marshalNodes: function (e) { return e.querySelectorAll(this.loadSelectorsForNode(e)) }, loadSelectorsForNode: function (e) { var t = e.ownerDocument || e; return t === c ? this.documentPreloadSelectors : this.importsPreloadSelectors }, loaded: function (e, n, r, a, s) { if (i.load && console.log("loaded", e, n), n.__resource = r, n.__error = a, t(n)) { var c = this.documents[e]; void 0 === c && (c = a ? null : o(r, s || e), c && (c.__importLink = n, this.bootDocument(c)), this.documents[e] = c), n.__doc = c } d.parseNext() }, bootDocument: function (e) { this.loadSubtree(e), this.observer.observe(e), d.parseNext() }, loadedAll: function () { d.parseNext() } }, h = new l(p.loaded.bind(p), p.loadedAll.bind(p)); if (p.observer = new u, !document.baseURI) { var f = { get: function () { var e = document.querySelector("base"); return e ? e.href : window.location.href }, configurable: !0 }; Object.defineProperty(document, "baseURI", f), Object.defineProperty(c, "baseURI", f) } e.importer = p, e.importLoader = h }), window.HTMLImports.addModule(function (e) { var t = e.parser, n = e.importer, r = { added: function (e) { for (var r, o, i, a, s = 0, c = e.length; s < c && (a = e[s]); s++)r || (r = a.ownerDocument, o = t.isParsed(r)), i = this.shouldLoadNode(a), i && n.loadNode(a), this.shouldParseNode(a) && o && t.parseDynamic(a, i) }, shouldLoadNode: function (e) { return 1 === e.nodeType && o.call(e, n.loadSelectorsForNode(e)) }, shouldParseNode: function (e) { return 1 === e.nodeType && o.call(e, t.parseSelectorsForNode(e)) } }; n.observer.addCallback = r.added.bind(r); var o = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector }), function (e) { function t() { window.HTMLImports.importer.bootDocument(r) } var n = e.initializeModules; e.isIE; if (!e.useNative) { n(); var r = e.rootDocument; "complete" === document.readyState || "interactive" === document.readyState && !window.attachEvent ? t() : document.addEventListener("DOMContentLoaded", t) } }(window.HTMLImports), window.CustomElements = window.CustomElements || { flags: {} }, function (e) { var t = e.flags, n = [], r = function (e) { n.push(e) }, o = function () { n.forEach(function (t) { t(e) }) }; e.addModule = r, e.initializeModules = o, e.hasNative = Boolean(document.registerElement), e.isIE = /Trident/.test(navigator.userAgent), e.useNative = !t.register && e.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative) }(window.CustomElements), window.CustomElements.addModule(function (e) { function t(e, t) { n(e, function (e) { return !!t(e) || void r(e, t) }), r(e, t) } function n(e, t, r) { var o = e.firstElementChild; if (!o) for (o = e.firstChild; o && o.nodeType !== Node.ELEMENT_NODE;)o = o.nextSibling; for (; o;)t(o, r) !== !0 && n(o, t, r), o = o.nextElementSibling; return null } function r(e, n) { for (var r = e.shadowRoot; r;)t(r, n), r = r.olderShadowRoot } function o(e, t) { i(e, t, []) } function i(e, t, n) { if (e = window.wrap(e), !(n.indexOf(e) >= 0)) { n.push(e); for (var r, o = e.querySelectorAll("link[rel=" + a + "]"), s = 0, c = o.length; s < c && (r = o[s]); s++)r["import"] && i(r["import"], t, n); t(e) } } var a = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none"; e.forDocumentTree = o, e.forSubtree = t }), window.CustomElements.addModule(function (e) { function t(e, t) { return n(e, t) || r(e, t) } function n(t, n) { return !!e.upgrade(t, n) || void (n && a(t)) } function r(e, t) { b(e, function (e) { if (n(e, t)) return !0 }) } function o(e) { S.push(e), _ || (_ = !0, setTimeout(i)) } function i() { _ = !1; for (var e, t = S, n = 0, r = t.length; n < r && (e = t[n]); n++)e(); S = [] } function a(e) { E ? o(function () { s(e) }) : s(e) } function s(e) { e.__upgraded__ && !e.__attached && (e.__attached = !0, e.attachedCallback && e.attachedCallback()) } function c(e) { l(e), b(e, function (e) { l(e) }) } function l(e) { E ? o(function () { u(e) }) : u(e) } function u(e) { e.__upgraded__ && e.__attached && (e.__attached = !1, e.detachedCallback && e.detachedCallback()) } function d(e) { for (var t = e, n = window.wrap(document); t;) { if (t == n) return !0; t = t.parentNode || t.nodeType === Node.DOCUMENT_FRAGMENT_NODE && t.host } } function p(e) { if (e.shadowRoot && !e.shadowRoot.__watched) { g.dom && console.log("watching shadow-root for: ", e.localName); for (var t = e.shadowRoot; t;)m(t), t = t.olderShadowRoot } } function h(e, n) { if (g.dom) { var r = n[0]; if (r && "childList" === r.type && r.addedNodes && r.addedNodes) { for (var o = r.addedNodes[0]; o && o !== document && !o.host;)o = o.parentNode; var i = o && (o.URL || o._URL || o.host && o.host.localName) || ""; i = i.split("/?").shift().split("/").pop() } console.group("mutations (%d) [%s]", n.length, i || "") } var a = d(e); n.forEach(function (e) { "childList" === e.type && (T(e.addedNodes, function (e) { e.localName && t(e, a) }), T(e.removedNodes, function (e) { e.localName && c(e) })) }), g.dom && console.groupEnd() } function f(e) { for (e = window.wrap(e), e || (e = window.wrap(document)); e.parentNode;)e = e.parentNode; var t = e.__observer; t && (h(e, t.takeRecords()), i()) } function m(e) { if (!e.__observer) { var t = new MutationObserver(h.bind(this, e)); t.observe(e, { childList: !0, subtree: !0 }), e.__observer = t } } function w(e) { e = window.wrap(e), g.dom && console.group("upgradeDocument: ", e.baseURI.split("/").pop()); var n = e === window.wrap(document); t(e, n), m(e), g.dom && console.groupEnd() } function v(e) { y(e, w) } var g = e.flags, b = e.forSubtree, y = e.forDocumentTree, E = window.MutationObserver._isPolyfilled && g["throttle-attached"]; e.hasPolyfillMutations = E, e.hasThrottledAttached = E; var _ = !1, S = [], T = Array.prototype.forEach.call.bind(Array.prototype.forEach), M = Element.prototype.createShadowRoot; M && (Element.prototype.createShadowRoot = function () { var e = M.call(this); return window.CustomElements.watchShadow(this), e }), e.watchShadow = p, e.upgradeDocumentTree = v, e.upgradeDocument = w, e.upgradeSubtree = r, e.upgradeAll = t, e.attached = a, e.takeRecords = f }), window.CustomElements.addModule(function (e) { function t(t, r) { if ("template" === t.localName && window.HTMLTemplateElement && HTMLTemplateElement.decorate && HTMLTemplateElement.decorate(t), !t.__upgraded__ && t.nodeType === Node.ELEMENT_NODE) { var o = t.getAttribute("is"), i = e.getRegisteredDefinition(t.localName) || e.getRegisteredDefinition(o); if (i && (o && i.tag == t.localName || !o && !i["extends"])) return n(t, i, r) } } function n(t, n, o) { return a.upgrade && console.group("upgrade:", t.localName), n.is && t.setAttribute("is", n.is), r(t, n), t.__upgraded__ = !0, i(t), o && e.attached(t), e.upgradeSubtree(t, o), a.upgrade && console.groupEnd(), t } function r(e, t) { Object.__proto__ ? e.__proto__ = t.prototype : (o(e, t.prototype, t["native"]), e.__proto__ = t.prototype) } function o(e, t, n) { for (var r = {}, o = t; o !== n && o !== HTMLElement.prototype;) { for (var i, a = Object.getOwnPropertyNames(o), s = 0; i = a[s]; s++)r[i] || (Object.defineProperty(e, i, Object.getOwnPropertyDescriptor(o, i)), r[i] = 1); o = Object.getPrototypeOf(o) } } function i(e) { e.createdCallback && e.createdCallback() } var a = e.flags; e.upgrade = t, e.upgradeWithDefinition = n, e.implementPrototype = r }), window.CustomElements.addModule(function (e) { function t(t, r) { var c = r || {}; if (!t) throw new Error("document.registerElement: first argument `name` must not be empty"); if (t.indexOf("-") < 0) throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(t) + "'."); if (o(t)) throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(t) + "'. The type name is invalid."); if (l(t)) throw new Error("DuplicateDefinitionError: a type with name '" + String(t) + "' is already registered"); return c.prototype || (c.prototype = Object.create(HTMLElement.prototype)), c.__name = t.toLowerCase(), c["extends"] && (c["extends"] = c["extends"].toLowerCase()), c.lifecycle = c.lifecycle || {}, c.ancestry = i(c["extends"]), a(c), s(c), n(c.prototype), u(c.__name, c), c.ctor = d(c), c.ctor.prototype = c.prototype, c.prototype.constructor = c.ctor, e.ready && w(document), c.ctor } function n(e) { if (!e.setAttribute._polyfilled) { var t = e.setAttribute; e.setAttribute = function (e, n) { r.call(this, e, n, t) }; var n = e.removeAttribute; e.removeAttribute = function (e) { r.call(this, e, null, n) }, e.setAttribute._polyfilled = !0 } } function r(e, t, n) { e = e.toLowerCase(); var r = this.getAttribute(e); n.apply(this, arguments); var o = this.getAttribute(e); this.attributeChangedCallback && o !== r && this.attributeChangedCallback(e, r, o) } function o(e) { for (var t = 0; t < E.length; t++)if (e === E[t]) return !0 } function i(e) { var t = l(e); return t ? i(t["extends"]).concat([t]) : [] } function a(e) { for (var t, n = e["extends"], r = 0; t = e.ancestry[r]; r++)n = t.is && t.tag; e.tag = n || e.__name, n && (e.is = e.__name) } function s(e) { if (!Object.__proto__) { var t = HTMLElement.prototype; if (e.is) { var n = document.createElement(e.tag); t = Object.getPrototypeOf(n) } for (var r, o = e.prototype, i = !1; o;)o == t && (i = !0), r = Object.getPrototypeOf(o), r && (o.__proto__ = r), o = r; i || console.warn(e.tag + " prototype not found in prototype chain for " + e.is), e["native"] = t } } function c(e) { return g(T(e.tag), e) } function l(e) { if (e) return _[e.toLowerCase()] } function u(e, t) { _[e] = t } function d(e) { return function () { return c(e) } } function p(e, t, n) { return e === S ? h(t, n) : M(e, t) } function h(e, t) { e && (e = e.toLowerCase()), t && (t = t.toLowerCase()); var n = l(t || e); if (n) { if (e == n.tag && t == n.is) return new n.ctor; if (!t && !n.is) return new n.ctor } var r; return t ? (r = h(e), r.setAttribute("is", t), r) : (r = T(e), e.indexOf("-") >= 0 && b(r, HTMLElement), r) } function f(e, t) { var n = e[t]; e[t] = function () { var e = n.apply(this, arguments); return v(e), e } } var m, w = (e.isIE, e.upgradeDocumentTree), v = e.upgradeAll, g = e.upgradeWithDefinition, b = e.implementPrototype, y = e.useNative, E = ["annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph"], _ = {}, S = "http://www.w3.org/1999/xhtml", T = document.createElement.bind(document), M = document.createElementNS.bind(document); m = Object.__proto__ || y ? function (e, t) { return e instanceof t } : function (e, t) { if (e instanceof t) return !0; for (var n = e; n;) { if (n === t.prototype) return !0; n = n.__proto__ } return !1 }, f(Node.prototype, "cloneNode"), f(document, "importNode"), document.registerElement = t, document.createElement = h, document.createElementNS = p, e.registry = _, e["instanceof"] = m, e.reservedTagList = E, e.getRegisteredDefinition = l, document.register = document.registerElement }), function (e) { function t() { i(window.wrap(document)), window.CustomElements.ready = !0; var e = window.requestAnimationFrame || function (e) { setTimeout(e, 16) }; e(function () { setTimeout(function () { window.CustomElements.readyTime = Date.now(), window.HTMLImports && (window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime), document.dispatchEvent(new CustomEvent("WebComponentsReady", { bubbles: !0 })) }) }) } var n = e.useNative, r = e.initializeModules; e.isIE; if (n) { var o = function () { }; e.watchShadow = o, e.upgrade = o, e.upgradeAll = o, e.upgradeDocumentTree = o, e.upgradeSubtree = o, e.takeRecords = o, e["instanceof"] = function (e, t) { return e instanceof t } } else r(); var i = e.upgradeDocumentTree, a = e.upgradeDocument; if (window.wrap || (window.ShadowDOMPolyfill ? (window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded, window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded) : window.wrap = window.unwrap = function (e) { return e }), window.HTMLImports && (window.HTMLImports.__importsParsingHook = function (e) { e["import"] && a(wrap(e["import"])) }), "complete" === document.readyState || e.flags.eager) t(); else if ("interactive" !== document.readyState || window.attachEvent || window.HTMLImports && !window.HTMLImports.ready) { var s = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded"; window.addEventListener(s, t) } else t() }(window.CustomElements), function (e) { Function.prototype.bind || (Function.prototype.bind = function (e) { var t = this, n = Array.prototype.slice.call(arguments, 1); return function () { var r = n.slice(); return r.push.apply(r, arguments), t.apply(e, r) } }) }(window.WebComponents), function (e) { var t = document.createElement("style"); t.textContent = "body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n"; var n = document.querySelector("head"); n.insertBefore(t, n.firstChild) }(window.WebComponents), function (e) { window.Platform = e }(window.WebComponents); \ No newline at end of file diff --git a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_viewer_full.html b/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_viewer_full.html deleted file mode 100644 index 4aac8735da109e1fc17c532e767fad21f85527f0..0000000000000000000000000000000000000000 --- a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/static/trace_viewer_full.html +++ /dev/null @@ -1,10175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/utils.py b/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/utils.py deleted file mode 100644 index 5991cf2b33d1e818e6876c8d7550fbb6c87cdaa3..0000000000000000000000000000000000000000 --- a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/utils.py +++ /dev/null @@ -1,147 +0,0 @@ -# ------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# Copyright(c) 2023 Huawei Technologies. -# All rights reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Modifications: Add visualization of PyTorch Ascend profiling. -# -------------------------------------------------------------------------- -import logging -import math -import os -import time -from contextlib import contextmanager - -from . import consts - -predefined_logging_level = ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET') - - -def get_logging_level(): - log_level = os.environ.get('TORCH_PROFILER_LOG_LEVEL', 'INFO').upper() - if log_level not in predefined_logging_level: - log_level = logging.getLevelName(logging.INFO) - return log_level - - -logger = None - - -def get_logger(): - global logger - if logger is None: - logger = logging.getLogger(consts.PLUGIN_NAME) - logger.setLevel(get_logging_level()) - return logger - - -def is_gpu_chrome_trace_file(path): - return consts.WORKER_PATTERN.match(path) - - -def is_worker_span_dir(path): - return consts.WORKER_SPAN_PATTERN.match(path) - - -def is_npu_trace_path(path): - return consts.TRACE_PATTERN.match(path) - - -def href(text, url): - """"return html formatted hyperlink string - - Note: - target="_blank" causes this link to be opened in new tab if clicked. - """ - return f'{text}' - - -class Canonicalizer: - def __init__( - self, - time_metric='us', - memory_metric='B', - *, - input_time_metric='us', - input_memory_metric='B'): - # raw timestamp is in microsecond - time_metric_to_factor = { - 'us': 1, - 'ms': 1e3, - 's': 1e6, - } - # raw memory is in bytes - memory_metric_to_factor = { - 'B': math.pow(1024, 0), - 'KB': math.pow(1024, 1), - 'MB': math.pow(1024, 2), - 'GB': math.pow(1024, 3), - } - - # canonicalize the memory metric to a string - self.canonical_time_metrics = { - 'micro': 'us', 'microsecond': 'us', 'us': 'us', - 'milli': 'ms', 'millisecond': 'ms', 'ms': 'ms', - '': 's', 'second': 's', 's': 's', - } - # canonicalize the memory metric to a string - self.canonical_memory_metrics = { - '': 'B', 'B': 'B', - 'K': 'KB', 'KB': 'KB', - 'M': 'MB', 'MB': 'MB', - 'G': 'GB', 'GB': 'GB', - } - - self.time_metric = self.canonical_time_metrics.get(time_metric) - self.memory_metric = self.canonical_memory_metrics.get(memory_metric) - - # scale factor scale input to output - self.time_factor = time_metric_to_factor.get(self.canonical_time_metrics.get(input_time_metric)) /\ - time_metric_to_factor.get(self.time_metric) - self.memory_factor = memory_metric_to_factor.get(self.canonical_memory_metrics.get(input_memory_metric)) /\ - memory_metric_to_factor.get(self.memory_metric) - - def convert_time(self, t): - return self.time_factor * t - - def convert_memory(self, m): - return self.memory_factor * m - - -class DisplayRounder: - """Round a value for display purpose.""" - - def __init__(self, ndigits): - self.ndigits = ndigits - self.precision = math.pow(10, -ndigits) - - def __call__(self, v: float): - _v = abs(v) - if _v >= self.precision or v == 0: - return round(v, 3) - else: - ndigit = abs(math.floor(math.log10(_v))) - return round(v, ndigit) - - -@contextmanager -def timing(description: str, force: bool = False) -> None: - if force or os.environ.get('TORCH_PROFILER_BENCHMARK', '0') == '1': - start = time.time() - yield - elapsed_time = time.time() - start - logger.info(f'{description}: {elapsed_time}') - else: - yield diff --git a/profiler/msprof_analyze/README.md b/profiler/msprof_analyze/README.md index 13e32a14a59f7676904e4723c146764adf856f19..208fe4e295e817e0a8c0c6bb6100d6c480cab96b 100644 --- a/profiler/msprof_analyze/README.md +++ b/profiler/msprof_analyze/README.md @@ -115,26 +115,27 @@ Successfully installed msprof-analyze-{version} 请通过下表链接下载profiler工具whl包。 -| profiler版本 | 发布日期 | 下载链接 | 校验码 | -|------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ | -| 2.0.2 | 2025-03-31 | [msprof_analyze-2.0.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.2/msprof_analyze-2.0.2-py3-none-any.whl) | 4227ff628187297b2f3bc14b9dd3a8765833ed25d527f750bc266a8d29f86935 | -| 2.0.1 | 2025-02-28 | [msprof_analyze-2.0.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.1/msprof_analyze-2.0.1-py3-none-any.whl) | 82dfe2c779dbab9015f61d36ea0c32d832b6d182454b3f7db68e6c0ed49c0423 | -| 2.0.0 | 2025-02-08 | [msprof_analyze-2.0.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.0/msprof_analyze-2.0.0-py3-none-any.whl) | 8e44e5f3e7681c377bb2657a600ad9841d3bed11061ddd7844c30e8a97242101 | -| 1.3.4 | 2025-01-20 | [msprof_analyze-1.3.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.4/msprof_analyze-1.3.4-py3-none-any.whl) | 8de92188d1a97105fb14cadcb0875ccd5f66629ee3bb25f37178da1906f4cce2 | -| 1.3.3 | 2024-12-26 | [msprof_analyze-1.3.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.3/msprof_analyze-1.3.3-py3-none-any.whl) | 27676f2eee636bd0c65243f81e292c7f9d30d7f985c772ac9cbaf10b54d3584e | -| 1.3.2 | 2024-12-20 | [msprof_analyze-1.3.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.2/msprof_analyze-1.3.2-py3-none-any.whl) | ceb227e751ec3a204135be13801f1deee6a66c347f1bb3cdaef596872874df06 | -| 1.3.1 | 2024-12-04 | [msprof_analyze-1.3.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.1/msprof_analyze-1.3.1-py3-none-any.whl) | eae5548804314110a649caae537f2c63320fc70ec41ce1167f67c1d674d8798e | -| 1.3.0 | 2024-10-12 | [msprof_analyze-1.3.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.0/msprof_analyze-1.3.0-py3-none-any.whl) | 8b09758c6b5181bb656a95857c32852f898c370e7f1041e5a08e4f10d5004d48 | -| 1.2.5 | 2024-09-25 | [msprof_analyze-1.2.5-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.5/msprof_analyze-1.2.5-py3-none-any.whl) | aea8ae8deac07b5b4980bd2240da27d0eec93b9ace9ea9eb2e3a05ae9072018b | -| 1.2.4 | 2024-09-19 | [msprof_analyze-1.2.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.4/msprof_analyze-1.2.4-py3-none-any.whl) | 7c392e72c3347c4034fd3fdfcccb1f7936c24d9c3eb217e2cc05bae1347e5ab7 | -| 1.2.3 | 2024-08-29 | [msprof_analyze-1.2.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.3/msprof_analyze-1.2.3-py3-none-any.whl) | 354a55747f64ba1ec6ee6fe0f05a53e84e1b403ee0341ec40cc216dd25fda14c | -| 1.2.2 | 2024-08-23 | [msprof_analyze-1.2.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.2/msprof_analyze-1.2.2-py3-none-any.whl) | ed92a8e4eaf5ada8a2b4079072ec0cc42501b1b1f2eb00c8fdcb077fecb4ae02 | -| 1.2.1 | 2024-08-14 | [msprof_analyze-1.2.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.1/msprof_analyze-1.2.1-py3-none-any.whl) | 7acd477417bfb3ea29029dadf175d019ad3212403b7e11dc1f87e84c2412c078 | -| 1.2.0 | 2024-07-25 | [msprof_analyze-1.2.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.0/msprof_analyze-1.2.0-py3-none-any.whl) | 6a4366e3beca40b4a8305080e6e441d6ecafb5c05489e5905ac0265787555f37 | -| 1.1.2 | 2024-07-12 | [msprof_analyze-1.1.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.2/msprof_analyze-1.1.2-py3-none-any.whl) | af62125b1f9348bf491364e03af712fc6d0282ccee3fb07458bc9bbef82dacc6 | -| 1.1.1 | 2024-06-20 | [msprof_analyze-1.1.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.1/msprof_analyze-1.1.1-py3-none-any.whl) | 76aad967a3823151421153d368d4d2f8e5cfbcb356033575e0b8ec5acea8e5e4 | -| 1.1.0 | 2024-05-28 | [msprof_analyze-1.1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.0/msprof_analyze-1.1.0-py3-none-any.whl) | b339f70e7d1e45e81f289332ca64990a744d0e7ce6fdd84a8d82e814fa400698 | -| 1.0 | 2024-05-10 | [msprof_analyze-1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.0/msprof_analyze-1.0-py3-none-any.whl) | 95b2f41c8c8e8afe4887b738c8cababcb4f412e1874483b6adae4a025fcbb7d4 | +| profiler版本 | 发布日期 | 下载链接 | 校验码 | +|------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ | +| 8.1.0a1 | 2025-06-26 | [msprof_analyze-8.1.0a1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/8.1.0a1/msprof_analyze-8.1.0a1-py3-none-any.whl) | d694b8e1318f346b647f13e9185d3fdefb88a124f9b0e07b74b769a292001886 | +| 2.0.2 | 2025-03-31 | [msprof_analyze-2.0.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.2/msprof_analyze-2.0.2-py3-none-any.whl) | 4227ff628187297b2f3bc14b9dd3a8765833ed25d527f750bc266a8d29f86935 | +| 2.0.1 | 2025-02-28 | [msprof_analyze-2.0.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.1/msprof_analyze-2.0.1-py3-none-any.whl) | 82dfe2c779dbab9015f61d36ea0c32d832b6d182454b3f7db68e6c0ed49c0423 | +| 2.0.0 | 2025-02-08 | [msprof_analyze-2.0.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.0/msprof_analyze-2.0.0-py3-none-any.whl) | 8e44e5f3e7681c377bb2657a600ad9841d3bed11061ddd7844c30e8a97242101 | +| 1.3.4 | 2025-01-20 | [msprof_analyze-1.3.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.4/msprof_analyze-1.3.4-py3-none-any.whl) | 8de92188d1a97105fb14cadcb0875ccd5f66629ee3bb25f37178da1906f4cce2 | +| 1.3.3 | 2024-12-26 | [msprof_analyze-1.3.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.3/msprof_analyze-1.3.3-py3-none-any.whl) | 27676f2eee636bd0c65243f81e292c7f9d30d7f985c772ac9cbaf10b54d3584e | +| 1.3.2 | 2024-12-20 | [msprof_analyze-1.3.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.2/msprof_analyze-1.3.2-py3-none-any.whl) | ceb227e751ec3a204135be13801f1deee6a66c347f1bb3cdaef596872874df06 | +| 1.3.1 | 2024-12-04 | [msprof_analyze-1.3.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.1/msprof_analyze-1.3.1-py3-none-any.whl) | eae5548804314110a649caae537f2c63320fc70ec41ce1167f67c1d674d8798e | +| 1.3.0 | 2024-10-12 | [msprof_analyze-1.3.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.0/msprof_analyze-1.3.0-py3-none-any.whl) | 8b09758c6b5181bb656a95857c32852f898c370e7f1041e5a08e4f10d5004d48 | +| 1.2.5 | 2024-09-25 | [msprof_analyze-1.2.5-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.5/msprof_analyze-1.2.5-py3-none-any.whl) | aea8ae8deac07b5b4980bd2240da27d0eec93b9ace9ea9eb2e3a05ae9072018b | +| 1.2.4 | 2024-09-19 | [msprof_analyze-1.2.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.4/msprof_analyze-1.2.4-py3-none-any.whl) | 7c392e72c3347c4034fd3fdfcccb1f7936c24d9c3eb217e2cc05bae1347e5ab7 | +| 1.2.3 | 2024-08-29 | [msprof_analyze-1.2.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.3/msprof_analyze-1.2.3-py3-none-any.whl) | 354a55747f64ba1ec6ee6fe0f05a53e84e1b403ee0341ec40cc216dd25fda14c | +| 1.2.2 | 2024-08-23 | [msprof_analyze-1.2.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.2/msprof_analyze-1.2.2-py3-none-any.whl) | ed92a8e4eaf5ada8a2b4079072ec0cc42501b1b1f2eb00c8fdcb077fecb4ae02 | +| 1.2.1 | 2024-08-14 | [msprof_analyze-1.2.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.1/msprof_analyze-1.2.1-py3-none-any.whl) | 7acd477417bfb3ea29029dadf175d019ad3212403b7e11dc1f87e84c2412c078 | +| 1.2.0 | 2024-07-25 | [msprof_analyze-1.2.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.0/msprof_analyze-1.2.0-py3-none-any.whl) | 6a4366e3beca40b4a8305080e6e441d6ecafb5c05489e5905ac0265787555f37 | +| 1.1.2 | 2024-07-12 | [msprof_analyze-1.1.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.2/msprof_analyze-1.1.2-py3-none-any.whl) | af62125b1f9348bf491364e03af712fc6d0282ccee3fb07458bc9bbef82dacc6 | +| 1.1.1 | 2024-06-20 | [msprof_analyze-1.1.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.1/msprof_analyze-1.1.1-py3-none-any.whl) | 76aad967a3823151421153d368d4d2f8e5cfbcb356033575e0b8ec5acea8e5e4 | +| 1.1.0 | 2024-05-28 | [msprof_analyze-1.1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.0/msprof_analyze-1.1.0-py3-none-any.whl) | b339f70e7d1e45e81f289332ca64990a744d0e7ce6fdd84a8d82e814fa400698 | +| 1.0 | 2024-05-10 | [msprof_analyze-1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.0/msprof_analyze-1.0-py3-none-any.whl) | 95b2f41c8c8e8afe4887b738c8cababcb4f412e1874483b6adae4a025fcbb7d4 | 2. whl包校验。 diff --git a/profiler/msprof_analyze/cluster_analyse/README.md b/profiler/msprof_analyze/cluster_analyse/README.md index 7e881d94d3c8bce3ba78fe81f3480b7588c93093..2ab5cf646112153626163920f5b004a8dc1fcef4 100644 --- a/profiler/msprof_analyze/cluster_analyse/README.md +++ b/profiler/msprof_analyze/cluster_analyse/README.md @@ -91,22 +91,23 @@ experimental_config = torch_npu.profiler._ExperimentalConfig( --mode参数设置不同的数据解析模式,可分析生成cluster_analysis.db交付件,交付件详细内容请参见[cluster_analysis.db交付件表结构说明](#cluster_analysisdb交付件表结构说明)。 - | 参数名 | 说明 | 是否必选 | - |--------------------------| ------------------------------------------------------------ | -------- | - | communication_matrix | 解析通信矩阵数据。 | 否 | - | communication_time | 解析通信耗时数据。 | 否 | - | all | 解析内容包括:
通信矩阵communication_matrix
通信耗时数据communication_time
汇总集群内的节点信息(基于ascend_pytorch_profiler_{rank_id}.db生成)
--mode参数默认值为all。 | 否 | - | cann_api_sum | 集群API性能数据汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/CannApiSum目录下输出交付件stats.ipynb。 | 否 | - | compute_op_sum | 集群场景性能数据的device运行算子信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/ComputeOpSum目录下输出交付件stats.ipynb;可根据实际情况决定是否打开--exclude_op_name。 | 否 | - | hccl_sum | 集合通信算子耗时分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/HcclSum目录下输出交付件stats.ipynb。 | 否 | - | mstx_sum | 集群场景mstx打点信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/MstxSum目录下输出交付件stats.ipynb。 | 否 | - | communication_group_map | 集群场景通信域与并行策略呈现,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件和analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | - | communication_time_sum | 集群场景通信时间和带宽汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。| 否 | - | communication_matrix_sum | 集群场景通信矩阵汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。| 否 | - | freq_analysis | 集群场景aicore frequency信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。打印输出是否aicore存在空闲(频率为800MHz)、异常(频率不为1800MHz或800MHz)的现象。如果有,则在输出交付件cluster_analysis.db增加对应的卡和频率信息。 | 否 | - | ep_load_balance | 集群场景moe负载信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db增加EPTokensSummary, TopEPTokensInfo分析表格。 | 否 | - | slow_rank | 集群场景通信算子快慢卡汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db中展示各个rank按照当前的快慢卡统计算法得出的快慢卡影响次数。|| - | 自定义分析参数 | 与cann_api_sum、compute_op_sum、hccl_sum等参数功能类似,用户可自定义一套性能数据的分析规则,要求用户开发者详细了解性能分析规则,具体开发指导请参见“[自定义分析规则开发指导](#自定义分析规则开发指导)”。 | 否 | +| 参数名 | 说明 | 是否必选 | +|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------| +| communication_matrix | 解析通信矩阵数据。 | 否 | +| communication_time | 解析通信耗时数据。 | 否 | +| all | 解析内容包括:
通信矩阵communication_matrix
通信耗时数据communication_time
汇总集群内的节点信息(基于ascend_pytorch_profiler_{rank_id}.db生成)
--mode参数默认值为all。 | 否 | +| cann_api_sum | 集群API性能数据汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/CannApiSum目录下输出交付件stats.ipynb。 | 否 | +| compute_op_sum | 集群场景性能数据的device运行算子信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/ComputeOpSum目录下输出交付件stats.ipynb;可根据实际情况决定是否打开--exclude_op_name。 | 否 | +| hccl_sum | 集合通信算子耗时分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/HcclSum目录下输出交付件stats.ipynb。 | 否 | +| mstx_sum | 集群场景mstx打点信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/MstxSum目录下输出交付件stats.ipynb。 | 否 | +| communication_group_map | 集群场景通信域与并行策略呈现,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件和analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | +| communication_time_sum | 集群场景通信时间和带宽汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | +| communication_matrix_sum | 集群场景通信矩阵汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | +| freq_analysis | 集群场景aicore frequency信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。打印输出是否aicore存在空闲(频率为800MHz)、异常(频率不为1800MHz或800MHz)的现象。如果有,则在输出交付件cluster_analysis.db增加对应的卡和频率信息。 | 否 | +| ep_load_balance | 集群场景moe负载信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db增加EPTokensSummary, TopEPTokensInfo分析表格。 | 否 | +| slow_rank | 集群场景通信算子快慢卡汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db中展示各个rank按照当前的快慢卡统计算法得出的快慢卡影响次数。 | 否 | +| mstx2commop | 集群场景基于mstx打点信息生成通信算子信息,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件ascend_pytorch_profiler_{rank_id}.db增加COMMUNICATION_OP, STRING_IDS分析表格。 | 否 | +| 自定义分析参数 | 与cann_api_sum、compute_op_sum、hccl_sum等参数功能类似,用户可自定义一套性能数据的分析规则,要求用户开发者详细了解性能分析规则,具体开发指导请参见“[自定义分析规则开发指导](#自定义分析规则开发指导)”。 | 否 | ### 交付件 @@ -699,6 +700,46 @@ msprof-analyze配置--mode参数时可分析并输出cluster_analysis.db交付 | rankId | INTEGER | 慢卡 | | slowAffectCount | INTEGER | 该rank影响了多少次通信 | +### mstx2commop + +设置-m mstx2commop时,会生成以下表。 + +#### COMMUNICATION_OP + +说明: + +基于db格式的集群通信算子数据。 + +格式: + +| 字段名 | 类型 | 含义 | +|--------------|---------|----------------------------------------------------------------------------| +| opName | INTEGER | 算子名,STRING_IDS(opName),例:hcom_allReduce__428_0_1 | +| startNs | INTEGER | 通信大算子的开始时间,单位ns | +| endNs | INTEGER | 通信大算子的结束时间,单位ns | +| connectionId | INTEGER | 生成host-device连线 | +| groupName | INTEGER | 通信域,STRING_IDS(groupName),例:10.170.22.98%enp67s0f5_60000_0_1708156014257149 | +| opId | INTEGER | 索引,通信大算子Id,用于关联COMMUNICATION_TASK_INFO表 | +| relay | INTEGER | 借轨通信标识 | +| retry | INTEGER | 重传标识 | +| dataType | INTEGER | 大算子传输的数据类型,如(INT8,FP32),ENUM_HCCL_DATA_TYPE(dataType) | +| algType | INTEGER | 通信算子使用的算法,可分为多个阶段,STRING_IDS(algType),如(HD-MESH) | +| count | NUMERIC | 算子传输的dataType类型的数据量 | +| opType | INTEGER | 算子类型,STRING_IDS(opType),例:hcom_broadcast_ | + +#### STRING_IDS + +说明: + +字符串映射表,COMMUNICATION_OP表opName字段可通过关联STRING_IDS表得到value。 + +格式: + +| 字段名 | 类型 | 含义 | +|-------|---------|--------------| +| id | INTEGER | 索引,string id | +| value | TEXT | string value | + ## 附录 ### 自定义分析规则开发指导 diff --git a/profiler/msprof_analyze/cluster_analyse/communication_group/base_communication_group.py b/profiler/msprof_analyze/cluster_analyse/communication_group/base_communication_group.py index 2765ba263c809a0b0c4bf0d42da5d60b6066e182..31cf1ad9ff184d840ec16b9b636fbc3555728980 100644 --- a/profiler/msprof_analyze/cluster_analyse/communication_group/base_communication_group.py +++ b/profiler/msprof_analyze/cluster_analyse/communication_group/base_communication_group.py @@ -190,18 +190,22 @@ class BaseCommunicationGroup: comm_group_df.loc[comm_group_df.shape[0]] = [Constant.P2P, list(rank_set), group_name] # create parallel group dataframe - parallel_group_cols = ["group_name", "group_id", "pg_name"] + parallel_group_cols = ["group_name", "group_id", "pg_name", "global_ranks"] parallel_group_df = pd.DataFrame(columns=parallel_group_cols) for group_id, parallel_info in self.parallel_group_info.items(): group_name = str(double_hash(group_id)) # group_name is hashed group_id pg_name = parallel_info.get("group_name", "") - if not pg_name: + global_ranks = parallel_info.get("global_ranks", []) + if not pg_name or not global_ranks: continue - parallel_group_df.loc[parallel_group_df.shape[0]] = [group_name, group_id, pg_name] + parallel_group_df.loc[parallel_group_df.shape[0]] = [group_name, group_id, pg_name, global_ranks] # merge by group_name df = pd.merge(comm_group_df, parallel_group_df, on='group_name', how='left') df.fillna("", inplace=True) + if self.parallel_group_info: + df["rank_set"] = df["global_ranks"] + df = df.drop(columns=["global_ranks"]) self.comm_group_parallel_info_df = df diff --git a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/io/__init__.py b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/__init__.py similarity index 42% rename from plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/io/__init__.py rename to profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/__init__.py index 296f53b7c813b2c97b498469f49b973438d9f3ae..7101187a2c2619f3b1c20dded14b433950b4c662 100644 --- a/plugins/tensorboard-plugins/tb_plugin/torch_tb_profiler/io/__init__.py +++ b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/__init__.py @@ -1,9 +1,7 @@ -# ------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. -# Copyright(c) 2023 Huawei Technologies. -# All rights reserved +# Copyright (c) 2024, Huawei Technologies Co., Ltd. +# All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # @@ -14,10 +12,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Modifications: Add visualization of PyTorch Ascend profiling. -# -------------------------------------------------------------------------- -from .cache import Cache -from .file import (BaseFileSystem, StatData, abspath, basename, download_file, - exists, get_filesystem, glob, isdir, join, listdir, - makedirs, read, register_filesystem, relpath, walk, stat, check_file_valid) diff --git a/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py new file mode 100644 index 0000000000000000000000000000000000000000..0b53798f515c0ce70df7776f8f80eeb743ca7d1d --- /dev/null +++ b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py @@ -0,0 +1,200 @@ +# Copyright (c) 2024, Huawei Technologies Co., Ltd. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import shutil + +import pandas as pd +from msprof_analyze.prof_common.path_manager import PathManager + +from msprof_analyze.cluster_analyse.recipes.base_recipe_analysis import BaseRecipeAnalysis +from msprof_analyze.prof_common.db_manager import DBManager +from msprof_analyze.prof_common.constant import Constant +from msprof_analyze.prof_common.logger import get_logger +from msprof_analyze.prof_exports.mstx2commop_export import Mstx2CommopExport +from msprof_analyze.prof_common.database_service import DatabaseService + +logger = get_logger() + +TABLE_COMMUNICATION_OP = "COMMUNICATION_OP" +TABLE_STRING_IDS = "STRING_IDS" + + +def double_hash(data): + uint32_bits = 32 + uint32_max = 0xFFFFFFFF # 32 位无符号整数的最大值 + prime = [29, 131] + hash_values = [0, 0] + + for d in data: + hash_values[0] = (hash_values[0] * prime[0] + ord(d)) & uint32_max + hash_values[1] = (hash_values[1] * prime[1] + ord(d)) & uint32_max + + return ((hash_values[0] << uint32_bits) | hash_values[1]) + + +class Mstx2Commop(BaseRecipeAnalysis): + + def __init__(self, params): + super().__init__(params) + logger.info("Mstx2Commop init.") + self.communication_op = None + self.string_ids_insert = None + self.set_output = Constant.CLUSTER_ANALYSIS_OUTPUT_PATH in params # 是否设置了output_path参数 + + @property + def base_dir(self): + return os.path.basename(os.path.dirname(__file__)) + + def run(self, context): + self.mapper_func(context) + + def _mapper_func(self, data_map, analysis_class): + profiler_db_path = data_map.get(Constant.PROFILER_DB_PATH) + step_range = data_map.get(Constant.STEP_RANGE) + data_service = DatabaseService(profiler_db_path, step_range) + data_service.add_table_for_query("ENUM_HCCL_DATA_TYPE", ["id", "name"]) + data_service.add_table_for_query("STRING_IDS", ["id", "value"]) + df_dict = data_service.query_data() + + df = Mstx2CommopExport(profiler_db_path, analysis_class, step_range).read_export_db() + + if df is None or df.empty: + logger.warning(f"There is no stats data in {profiler_db_path}.") + return None + + df_hccl_dt = df_dict.get("ENUM_HCCL_DATA_TYPE") + + if df_hccl_dt is None or df_hccl_dt.empty: + logger.warning(f"There is no stats data in {profiler_db_path}.") + return None + + df_string_ids = df_dict.get("STRING_IDS") + + if df_string_ids is None or df_string_ids.empty: + logger.warning(f"There is no stats data in {profiler_db_path}.") + return None + + value_len = 4 + optype_index, op_start_index = 0, 9 + groupname_index, datatype_index, count_index = 1, 2, 3 + + # json格式数据转化 + if df.loc[0, 'value'][0] == '{': + df['value'] = df['value'].apply(lambda x: json.loads(x)) + df['opType_primal'] = df['value'].apply(lambda x: x['opName'] + '_') + df['groupName_primal'] = df['value'].apply(lambda x: x['groupName']) + df['dataType'] = df['value'].apply(lambda x: x['dataType']) + df['count'] = df['value'].apply(lambda x: x['count']) + # 非json格式数据转化 + else: + df['value_list'] = df['value'].apply(lambda x: x.split(',')) + df['value_list_len'] = df['value_list'].apply(len) + df = df[df['value_list_len'] == value_len] + df['opType_primal'] = df['value_list'].apply(lambda x: 'hcom_' + x[optype_index][op_start_index:] + '_') + df['groupName_primal'] = df['value_list'].apply(lambda x: x[groupname_index]) + df['dataType'] = df['value_list'].apply(lambda x: x[datatype_index]) + df['count'] = df['value_list'].apply(lambda x: x[count_index]) + + df['groupName_hash'] = df['groupName_primal'].apply(double_hash).apply(str) + + df['gN_oT'] = df['groupName_primal'] + df['opType_primal'] + + gnot_set = set(list(df['gN_oT'])) + + df_concat = pd.DataFrame() + for g_o in gnot_set: + df_split = df[df['gN_oT'] == g_o] + df_split = df_split.copy() + df_split['queue'] = list(range(len(df_split))) + df_concat = pd.concat([df_concat, df_split], axis=0) + + df_concat['queue'] = df_concat['queue'].apply(str) + + df_concat['groupId'] = df_concat['groupName_hash'].apply(lambda x: "_" + x[-3:]) + + df_concat['opName_primal'] = df_concat['opType_primal'] + df_concat['groupId'] + '_' + df_concat['queue'] + '_1' + + df_concat['opId'] = list(range(len(df_concat))) + df_concat['relay'] = None + df_concat['retry'] = None + df_concat['algType'] = None + + df_hccl_dt['name'] = df_hccl_dt['name'].apply(lambda x: x.lower()) + hccl_data_type_dict = dict(zip(df_hccl_dt['name'], df_hccl_dt['id'])) + + string_ids_dict = dict(zip(df_string_ids['value'], df_string_ids['id'])) + + string_ids_max = df_string_ids['id'].max() + + df_concat['dataType'] = df_concat['dataType'].apply(lambda x: hccl_data_type_dict[x]) + + df_concat['string_id_opType_primal'] = df_concat['opType_primal'].apply( + lambda x: 1 if x in string_ids_dict else 0) + df_concat['string_id_opName_primal'] = df_concat['opName_primal'].apply( + lambda x: 1 if x in string_ids_dict else 0) + df_concat['string_id_groupName_primal'] = df_concat['groupName_primal'].apply( + lambda x: 1 if x in string_ids_dict else 0) + optype_primal_list = list(set(df_concat[df_concat['string_id_opType_primal'] == 0]['opType_primal'])) + opname_primal_list = list(set(df_concat[df_concat['string_id_opName_primal'] == 0]['opName_primal'])) + groupname_primal_list = list(set(df_concat[df_concat['string_id_groupName_primal'] == 0]['groupName_primal'])) + + special_primal_list = optype_primal_list + opname_primal_list + groupname_primal_list + special_id_list = list(range(string_ids_max + 1, string_ids_max + len(special_primal_list) + 1)) + + special_id_dict = dict(zip(special_primal_list, special_id_list)) + + df_concat['opType'] = df_concat['opType_primal'].apply( + lambda x: string_ids_dict[x] if x in string_ids_dict else special_id_dict[x] + ) + df_concat['opName'] = df_concat['opName_primal'].apply( + lambda x: string_ids_dict[x] if x in string_ids_dict else special_id_dict[x] + ) + df_concat['groupName'] = df_concat['groupName_primal'].apply( + lambda x: string_ids_dict[x] if x in string_ids_dict else special_id_dict[x] + ) + + communication_op = df_concat[ + ['opName', 'startNs', 'endNs', 'connectionId', 'groupName', 'opId', 'relay', 'retry', 'dataType', 'algType', + 'count', 'opType']] + communication_op = communication_op.copy() + communication_op.sort_values('startNs', ascending=True, inplace=True) + communication_op.set_index('opId', inplace=True) + string_ids_insert = list(map(list, zip(special_id_list, special_primal_list))) + + new_profiler_db = self._prepare_output_profiler_db(data_map.get(Constant.PROFILER_DB_PATH)) + + DBManager.insert_data_into_db(new_profiler_db, TABLE_STRING_IDS, string_ids_insert) + + self.dump_data(data=communication_op, file_name="", table_name=TABLE_COMMUNICATION_OP, + custom_db_path=new_profiler_db) + + return data_map.get(Constant.RANK_ID) + + def _prepare_output_profiler_db(self, profiler_db_path): + """ + copy profiler_db to output if not exist + """ + output_dir = os.path.join(self._cluster_analysis_output_path, self._recipe_name) + relative_db_path = os.path.relpath(profiler_db_path, start=self._collection_dir) + relative_dir = os.path.dirname(relative_db_path) + + new_path = os.path.join(output_dir, relative_dir) + new_db_path = os.path.join(output_dir, relative_db_path) + PathManager.make_dir_safety(new_path) + shutil.copyfile(profiler_db_path, new_db_path) + return new_db_path + diff --git a/profiler/msprof_analyze/prof_exports/mstx2commop_export.py b/profiler/msprof_analyze/prof_exports/mstx2commop_export.py new file mode 100644 index 0000000000000000000000000000000000000000..f84b5e71407dfd1f5acb8594963177ebd863387e --- /dev/null +++ b/profiler/msprof_analyze/prof_exports/mstx2commop_export.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024, Huawei Technologies Co., Ltd. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from msprof_analyze.prof_exports.base_stats_export import BaseStatsExport + +QUERY = """ +SELECT + ta.startNs, + ta.endNs, + ta.connectionId, + si.value +FROM + MSTX_EVENTS ms +JOIN + TASK ta + ON ms.connectionId == ta.connectionId +JOIN + STRING_IDS si + ON ms.message == si.id +WHERE + si.value LIKE '%"streamId":%' + AND si.value LIKE '%"count":%' + AND si.value LIKE '%"dataType":%' + AND si.value LIKE '%"groupName":%' + AND si.value LIKE '%"opName":%' + {} + """ + + +class Mstx2CommopExport(BaseStatsExport): + + def __init__(self, db_path, recipe_name, step_range): + super().__init__(db_path, recipe_name, step_range) + filter_stat = "AND ta.startNs >= ? and ta.startNs <= ?" if step_range else "" + self._query = QUERY.format(filter_stat) diff --git a/profiler/msprof_analyze/test/st/compare_tools/test_compare_tools_cmd_pytorch_db_npu_vs_npu.py b/profiler/msprof_analyze/test/st/compare_tools/test_compare_tools_cmd_pytorch_db_npu_vs_npu.py new file mode 100644 index 0000000000000000000000000000000000000000..5485f99da38f65fb916221aae1945ccf7ca6be0b --- /dev/null +++ b/profiler/msprof_analyze/test/st/compare_tools/test_compare_tools_cmd_pytorch_db_npu_vs_npu.py @@ -0,0 +1,77 @@ +# Copyright (c) 2025, Huawei Technologies Co., Ltd. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +from unittest import TestCase + +import pandas as pd + +from msprof_analyze.prof_common.path_manager import PathManager +from msprof_analyze.test.st.utils import execute_cmd, check_result_file +from msprof_analyze.test.st.utils import ST_DATA_PATH + + +class TestCompareToolsCmdPytorchDbNpuVsNpu(TestCase): + BASE_PROFILING_PATH = os.path.join(ST_DATA_PATH, "cluster_data_2_db", + "n122-120-121_12321_20240911113658382_ascend_pt") + COMPARISON_PROFILING_PATH = os.path.join(ST_DATA_PATH, "cluster_data_2_db", + "n122-120-121_12322_20240911113658370_ascend_pt") + OUTPUT_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), "CompareToolsCmdPytorchDbNpuVsNpu") + COMMAND_SUCCESS = 0 + result_excel = "" + + def setup_class(self): + PathManager.make_dir_safety(self.OUTPUT_PATH) + cmd = ["msprof-analyze", "compare", "-d", self.COMPARISON_PROFILING_PATH, "-bp", self.BASE_PROFILING_PATH, "-o", + self.OUTPUT_PATH, "--force"] + if execute_cmd(cmd) != self.COMMAND_SUCCESS or not os.path.exists(self.OUTPUT_PATH): + self.assertTrue(False, msg="comparison task failed.") + if not check_result_file(self.OUTPUT_PATH): + self.assertTrue(False, msg="comparison result excel is not find.") + self.result_excel = os.path.join(self.OUTPUT_PATH, check_result_file(self.OUTPUT_PATH)) + + def teardown_class(self): + PathManager.remove_path_safety(self.OUTPUT_PATH) + + def test_overall_metrics(self): + duration_exp = [ + 14302.47, 1128.78, 1128.78, 10320.26, 10320.26, 2837.1, 445.59, 2391.52, 16.33, 50636.60, 2595.59, 11.69, + 2583.90, 117.70, 116.68, 1.03, 82.64, 0.16, 82.47, 99.71, 0.00, 99.71, 13013.70, 2032.30, 10981.41, + 17478.85, 17308.09, 170.76, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 5045.58, + 5045.58, 0.00, 682.94, 682.94, 65622.00 + ] + + diff_exp = [6.48, 4.84, 4.84, -9.23, -9.23, 10.78, -0.83, 11.61, 0.09, 33.92, 94.13, 100.38, -6.26, -117.70, + -116.68, -1.03, -82.64, -0.16, -82.47, -82.30, 0.19, -82.49, -13013.70, -2032.30, + -10981.41, -17478.85, -17308.09, -170.76, 170.83, 169.81, 1.02, 81.11, 0.42, 80.69, 13836.68, + 1954.07, 11882.61, 17478.49, 17307.83, 170.67, 223.37, -5045.58, 5268.95, -48.46, -48.46, -8.05] + + df = pd.read_excel(self.result_excel, sheet_name="OverallMetrics", header=2) + for index, row in df.iterrows(): + self.assertEqual(duration_exp[index], round(row["Duration(ms)"], 2), + msg="pytorch npu vs npu compare results 'Duration(ms)" + "' column is wrong" + ) + self.assertEqual(diff_exp[index], round(row["Diff Duration(ms)"], 2), + msg="pytorch npu vs npu compare results 'Diff Duration(ms)" + "' column is wrong" + ) + + def test_kernel_compare(self): + headers = ["Order Id", "Kernel", "Input Shape", "Total Duration(us)", "Avg Duration(us)", "Max Duration(us)", + "Min Duration(us)", "Calls", "Total Duration(us).1", "Avg Duration(us).1", "Max Duration(us).1", + "Min Duration(us).1", "Calls.1", "Diff Total Ratio", "Diff Avg Ratio"] + df = pd.read_excel(self.result_excel, sheet_name="KernelCompare", header=2) + self.assertEqual(len(df), 706, msg="pytorch npu vs npu compare results quantity is wrong") + self.assertEqual(headers, df.columns.tolist(), msg="pytorch npu vs npu compare results headers is wrong") diff --git a/profiler/msprof_analyze/version.txt b/profiler/msprof_analyze/version.txt index f93ea0ca333052aa92d755e06d2a672b7f895426..c069720a95833aa20c1f985f38362ed236e4a1ad 100644 --- a/profiler/msprof_analyze/version.txt +++ b/profiler/msprof_analyze/version.txt @@ -1 +1 @@ -2.0.2 \ No newline at end of file +8.1.0.alpha1 \ No newline at end of file diff --git a/sample/transfer_to_npu/README.md b/sample/transfer_to_npu/README.md new file mode 100644 index 0000000000000000000000000000000000000000..167bc1ffaf7b1ffcc3e1264cb4cbdeeaa9149be9 --- /dev/null +++ b/sample/transfer_to_npu/README.md @@ -0,0 +1,45 @@ +# 迁移工具快速入门样例介绍 + +## 说明 + +本样例选用ResNet50模型。 + +## 环境准备 + +1. 准备一台基于Atlas 训练系列产品的训练服务器,并[安装NPU驱动和固件](https://www.hiascend.com/document/detail/zh/canncommercial/81RC1/softwareinst/instg/instg_0005.html?Mode=PmIns&InstallType=local&OS=Ubuntu&Software=cannToolKit)。 + +2. 安装开发套件包Ascend-cann-toolkit,具体请参考[安装CANN软件包](https://www.hiascend.com/document/detail/zh/canncommercial/81RC1/softwareinst/instg/instg_0008.html?Mode=PmIns&InstallType=local&OS=Ubuntu&Software=cannToolKit)。 + +3. 以安装PyTorch 2.1.0版本为例,具体操作请参考适配插件开发(PyTorch框架)。 + +4. 配置环境变量。
+安装CANN软件后,使用CANN运行用户进行编译、运行时,需要以CANN运行用户登录环境,执行source ${install_path}/set_env.sh命令设置环境变量。其中${install_path}为CANN软件的安装目录,例如:/usr/local/Ascend/ascend-toolkit。 + +5. 下载[main.py](main.py)文件,并上传至训练服务器的个人目录下。 + + +## 执行迁移 +1. 在训练脚本(main.py文件)中导入自动迁移的库代码。 +```Python + 42 + 43 import torch_npu + 44 from torch_npu.contrib import transfer_to_npu + 45 +# 在43 44行插入的代码为自动迁移的库代码,可以在NPU环境下直接执行训练 +``` + +2. 迁移完成后的训练脚本可在NPU上运行,执行以下训练命令。 +```Python +python main.py -a resnet50 -b 32 --gpu 1 --dummy +``` +如果训练正常进行,开始打印迭代日志,说明训练功能迁移成功,如下所示。 +```Python +Use GPU: 1 for training +=> creating model 'resnet50' +=> Dummy data is used! +Epoch: [0][ 1/40037] Time 8.287 ( 8.287) Data 0.504 ( 0.504) Loss 7.0919e+00 (7.0919e+00) Acc@1 0.00 ( 0.00) Acc@5 0.00 ( 0.00) +Epoch: [0][ 11/40037] Time 0.097 ( 1.268) Data 0.000 ( 0.479) Loss 1.5627e+01 (1.8089e+01) Acc@1 0.00 ( 0.00) Acc@5 3.12 ( 0.57) +Epoch: [0][ 21/40037] Time 0.096 ( 0.710) Data 0.000 ( 0.253) Loss 7.7462e+00 (1.4883e+01) Acc@1 0.00 ( 0.00) +``` + +3. 成功保存权重,说明保存权重功能迁移成功。 diff --git a/sample/transfer_to_npu/main.py b/sample/transfer_to_npu/main.py new file mode 100644 index 0000000000000000000000000000000000000000..7d4d994d425e2af7b6361a99235af970ca5a9480 --- /dev/null +++ b/sample/transfer_to_npu/main.py @@ -0,0 +1,519 @@ +# BSD 3-Clause License +# +# Copyright (c) 2017, +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +#* Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +#* Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +#* Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. + +import argparse +import os +import random +import shutil +import time +import warnings +from enum import Enum + +import torch +import torch.backends.cudnn as cudnn +import torch.distributed as dist +import torch.multiprocessing as mp +import torch.nn as nn +import torch.nn.parallel +import torch.optim +import torch.utils.data +import torch.utils.data.distributed +import torchvision.datasets as datasets +import torchvision.models as models +import torchvision.transforms as transforms +from torch.optim.lr_scheduler import StepLR +from torch.utils.data import Subset + +model_names = sorted(name for name in models.__dict__ + if name.islower() and not name.startswith("__") + and callable(models.__dict__[name])) + +parser = argparse.ArgumentParser(description='PyTorch ImageNet Training') +parser.add_argument('data', metavar='DIR', nargs='?', default='imagenet', + help='path to dataset (default: imagenet)') +parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18', + choices=model_names, + help='model architecture: ' + + ' | '.join(model_names) + + ' (default: resnet18)') +parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', + help='number of data loading workers (default: 4)') +parser.add_argument('--epochs', default=90, type=int, metavar='N', + help='number of total epochs to run') +parser.add_argument('--start-epoch', default=0, type=int, metavar='N', + help='manual epoch number (useful on restarts)') +parser.add_argument('-b', '--batch-size', default=256, type=int, + metavar='N', + help='mini-batch size (default: 256), this is the total ' + 'batch size of all GPUs on the current node when ' + 'using Data Parallel or Distributed Data Parallel') +parser.add_argument('--lr', '--learning-rate', default=0.1, type=float, + metavar='LR', help='initial learning rate', dest='lr') +parser.add_argument('--momentum', default=0.9, type=float, metavar='M', + help='momentum') +parser.add_argument('--wd', '--weight-decay', default=1e-4, type=float, + metavar='W', help='weight decay (default: 1e-4)', + dest='weight_decay') +parser.add_argument('-p', '--print-freq', default=10, type=int, + metavar='N', help='print frequency (default: 10)') +parser.add_argument('--resume', default='', type=str, metavar='PATH', + help='path to latest checkpoint (default: none)') +parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true', + help='evaluate model on validation set') +parser.add_argument('--pretrained', dest='pretrained', action='store_true', + help='use pre-trained model') +parser.add_argument('--world-size', default=-1, type=int, + help='number of nodes for distributed training') +parser.add_argument('--rank', default=-1, type=int, + help='node rank for distributed training') +parser.add_argument('--dist-backend', default='nccl', type=str, + help='distributed backend') +parser.add_argument('--seed', default=None, type=int, + help='seed for initializing training. ') +parser.add_argument('--gpu', default=None, type=int, + help='GPU id to use.') +parser.add_argument('--multiprocessing-distributed', action='store_true', + help='Use multi-processing distributed training to launch ' + 'N processes per node, which has N GPUs. This is the ' + 'fastest way to use PyTorch for either single node or ' + 'multi node data parallel training') +parser.add_argument('--dummy', action='store_true', help="use fake data to benchmark") + +best_acc1 = 0 + + +def main(): + args = parser.parse_args() + + if args.seed is not None: + random.seed(args.seed) + torch.manual_seed(args.seed) + cudnn.deterministic = True + cudnn.benchmark = False + warnings.warn('You have chosen to seed training. ' + 'This will turn on the CUDNN deterministic setting, ' + 'which can slow down your training considerably! ' + 'You may see unexpected behavior when restarting ' + 'from checkpoints.') + + if args.gpu is not None: + warnings.warn('You have chosen a specific GPU. This will completely ' + 'disable data parallelism.') + + args.distributed = args.world_size > 1 or args.multiprocessing_distributed + + if torch.cuda.is_available(): + ngpus_per_node = torch.cuda.device_count() + if ngpus_per_node == 1 and args.dist_backend == "nccl": + warnings.warn("nccl backend >=2.5 requires GPU count>1, perhaps use 'gloo'") + else: + ngpus_per_node = 1 + + if args.multiprocessing_distributed: + # Since we have ngpus_per_node processes per node, the total world_size + # needs to be adjusted accordingly + args.world_size = ngpus_per_node * args.world_size + # Use torch.multiprocessing.spawn to launch distributed processes: the + # main_worker process function + mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args)) + else: + # Simply call main_worker function + main_worker(args.gpu, ngpus_per_node, args) + + +def main_worker(gpu, ngpus_per_node, args): + global best_acc1 + args.gpu = gpu + + if args.gpu is not None: + print("Use GPU: {} for training".format(args.gpu)) + + # create model + if args.pretrained: + print("=> using pre-trained model '{}'".format(args.arch)) + model = models.__dict__[args.arch](pretrained=True) + else: + print("=> creating model '{}'".format(args.arch)) + model = models.__dict__[args.arch]() + + if not torch.cuda.is_available() and not torch.backends.mps.is_available(): + print('using CPU, this will be slow') + elif args.distributed: + # For multiprocessing distributed, DistributedDataParallel constructor + # should always set the single device scope, otherwise, + # DistributedDataParallel will use all available devices. + if torch.cuda.is_available(): + if args.gpu is not None: + torch.cuda.set_device(args.gpu) + model.cuda(args.gpu) + # When using a single GPU per process and per + # DistributedDataParallel, we need to divide the batch size + # ourselves based on the total number of GPUs of the current node. + args.batch_size = int(args.batch_size / ngpus_per_node) + args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node) + model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu]) + else: + model.cuda() + # DistributedDataParallel will divide and allocate batch_size to all + # available GPUs if device_ids are not set + model = torch.nn.parallel.DistributedDataParallel(model) + elif args.gpu is not None and torch.cuda.is_available(): + torch.cuda.set_device(args.gpu) + model = model.cuda(args.gpu) + elif torch.backends.mps.is_available(): + device = torch.device("mps") + model = model.to(device) + else: + # DataParallel will divide and allocate batch_size to all available GPUs + if args.arch.startswith('alexnet') or args.arch.startswith('vgg'): + model.features = torch.nn.DataParallel(model.features) + model.cuda() + else: + model = torch.nn.DataParallel(model).cuda() + + if torch.cuda.is_available(): + if args.gpu: + device = torch.device('cuda:{}'.format(args.gpu)) + else: + device = torch.device("cuda") + elif torch.backends.mps.is_available(): + device = torch.device("mps") + else: + device = torch.device("cpu") + # define loss function (criterion), optimizer, and learning rate scheduler + criterion = nn.CrossEntropyLoss().to(device) + + optimizer = torch.optim.SGD(model.parameters(), args.lr, + momentum=args.momentum, + weight_decay=args.weight_decay) + + """Sets the learning rate to the initial LR decayed by 10 every 30 epochs""" + scheduler = StepLR(optimizer, step_size=30, gamma=0.1) + + # optionally resume from a checkpoint + if args.resume: + if os.path.isfile(args.resume): + print("=> loading checkpoint '{}'".format(args.resume)) + if args.gpu is None: + checkpoint = torch.load(args.resume) + elif torch.cuda.is_available(): + # Map model to be loaded to specified single gpu. + loc = 'cuda:{}'.format(args.gpu) + checkpoint = torch.load(args.resume, map_location=loc) + args.start_epoch = checkpoint['epoch'] + best_acc1 = checkpoint['best_acc1'] + if args.gpu is not None: + # best_acc1 may be from a checkpoint from a different GPU + best_acc1 = best_acc1.to(args.gpu) + model.load_state_dict(checkpoint['state_dict']) + optimizer.load_state_dict(checkpoint['optimizer']) + scheduler.load_state_dict(checkpoint['scheduler']) + print("=> loaded checkpoint '{}' (epoch {})" + .format(args.resume, checkpoint['epoch'])) + else: + print("=> no checkpoint found at '{}'".format(args.resume)) + + + # Data loading code + if args.dummy: + print("=> Dummy data is used!") + train_dataset = datasets.FakeData(1281167, (3, 224, 224), 1000, transforms.ToTensor()) + val_dataset = datasets.FakeData(50000, (3, 224, 224), 1000, transforms.ToTensor()) + else: + traindir = os.path.join(args.data, 'train') + valdir = os.path.join(args.data, 'val') + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + + train_dataset = datasets.ImageFolder( + traindir, + transforms.Compose([ + transforms.RandomResizedCrop(224), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + normalize, + ])) + + val_dataset = datasets.ImageFolder( + valdir, + transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + normalize, + ])) + + if args.distributed: + train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset) + val_sampler = torch.utils.data.distributed.DistributedSampler(val_dataset, shuffle=False, drop_last=True) + else: + train_sampler = None + val_sampler = None + + train_loader = torch.utils.data.DataLoader( + train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), + num_workers=args.workers, pin_memory=True, sampler=train_sampler) + + val_loader = torch.utils.data.DataLoader( + val_dataset, batch_size=args.batch_size, shuffle=False, + num_workers=args.workers, pin_memory=True, sampler=val_sampler) + + if args.evaluate: + validate(val_loader, model, criterion, args) + return + + for epoch in range(args.start_epoch, args.epochs): + if args.distributed: + train_sampler.set_epoch(epoch) + + # train for one epoch + train(train_loader, model, criterion, optimizer, epoch, device, args) + + # evaluate on validation set + acc1 = validate(val_loader, model, criterion, args) + + scheduler.step() + + # remember best acc@1 and save checkpoint + is_best = acc1 > best_acc1 + best_acc1 = max(acc1, best_acc1) + + if not args.multiprocessing_distributed or (args.multiprocessing_distributed + and args.rank % ngpus_per_node == 0): + save_checkpoint({ + 'epoch': epoch + 1, + 'arch': args.arch, + 'state_dict': model.state_dict(), + 'best_acc1': best_acc1, + 'optimizer' : optimizer.state_dict(), + 'scheduler' : scheduler.state_dict() + }, is_best) + + +def train(train_loader, model, criterion, optimizer, epoch, device, args): + batch_time = AverageMeter('Time', ':6.3f') + data_time = AverageMeter('Data', ':6.3f') + losses = AverageMeter('Loss', ':.4e') + top1 = AverageMeter('Acc@1', ':6.2f') + top5 = AverageMeter('Acc@5', ':6.2f') + progress = ProgressMeter( + len(train_loader), + [batch_time, data_time, losses, top1, top5], + prefix="Epoch: [{}]".format(epoch)) + + # switch to train mode + model.train() + + end = time.time() + for i, (images, target) in enumerate(train_loader): + # measure data loading time + data_time.update(time.time() - end) + + # move data to the same device as model + images = images.to(device, non_blocking=True) + target = target.to(device, non_blocking=True) + + # compute output + output = model(images) + loss = criterion(output, target) + + # measure accuracy and record loss + acc1, acc5 = accuracy(output, target, topk=(1, 5)) + losses.update(loss.item(), images.size(0)) + top1.update(acc1[0], images.size(0)) + top5.update(acc5[0], images.size(0)) + + # compute gradient and do SGD step + optimizer.zero_grad() + loss.backward() + optimizer.step() + + # measure elapsed time + batch_time.update(time.time() - end) + end = time.time() + + if i % args.print_freq == 0: + progress.display(i + 1) + + +def validate(val_loader, model, criterion, args): + + def run_validate(loader, base_progress=0): + with torch.no_grad(): + end = time.time() + for i, (images, target) in enumerate(loader): + i = base_progress + i + if args.gpu is not None and torch.cuda.is_available(): + images = images.cuda(args.gpu, non_blocking=True) + if torch.backends.mps.is_available(): + images = images.to('mps') + target = target.to('mps') + if torch.cuda.is_available(): + target = target.cuda(args.gpu, non_blocking=True) + + # compute output + output = model(images) + loss = criterion(output, target) + + # measure accuracy and record loss + acc1, acc5 = accuracy(output, target, topk=(1, 5)) + losses.update(loss.item(), images.size(0)) + top1.update(acc1[0], images.size(0)) + top5.update(acc5[0], images.size(0)) + + # measure elapsed time + batch_time.update(time.time() - end) + end = time.time() + + if i % args.print_freq == 0: + progress.display(i + 1) + + batch_time = AverageMeter('Time', ':6.3f', Summary.NONE) + losses = AverageMeter('Loss', ':.4e', Summary.NONE) + top1 = AverageMeter('Acc@1', ':6.2f', Summary.AVERAGE) + top5 = AverageMeter('Acc@5', ':6.2f', Summary.AVERAGE) + progress = ProgressMeter( + len(val_loader) + (args.distributed and (len(val_loader.sampler) * args.world_size < len(val_loader.dataset))), + [batch_time, losses, top1, top5], + prefix='Test: ') + + # switch to evaluate mode + model.eval() + + run_validate(val_loader) + if args.distributed: + top1.all_reduce() + top5.all_reduce() + + if args.distributed and (len(val_loader.sampler) * args.world_size < len(val_loader.dataset)): + aux_val_dataset = Subset(val_loader.dataset, + range(len(val_loader.sampler) * args.world_size, len(val_loader.dataset))) + aux_val_loader = torch.utils.data.DataLoader( + aux_val_dataset, batch_size=args.batch_size, shuffle=False, + num_workers=args.workers, pin_memory=True) + run_validate(aux_val_loader, len(val_loader)) + + progress.display_summary() + + return top1.avg + + +def save_checkpoint(state, is_best, filename='checkpoint.pth.tar'): + torch.save(state, filename) + if is_best: + shutil.copyfile(filename, 'model_best.pth.tar') + +class Summary(Enum): + NONE = 0 + AVERAGE = 1 + SUM = 2 + COUNT = 3 + +class AverageMeter(object): + """Computes and stores the average and current value""" + def __init__(self, name, fmt=':f', summary_type=Summary.AVERAGE): + self.name = name + self.fmt = fmt + self.summary_type = summary_type + self.reset() + + def reset(self): + self.val = 0 + self.avg = 0 + self.sum = 0 + self.count = 0 + + def update(self, val, n=1): + self.val = val + self.sum += val * n + self.count += n + self.avg = self.sum / self.count + + def all_reduce(self): + if torch.cuda.is_available(): + device = torch.device("cuda") + elif torch.backends.mps.is_available(): + device = torch.device("mps") + else: + device = torch.device("cpu") + total = torch.tensor([self.sum, self.count], dtype=torch.float32, device=device) + dist.all_reduce(total, dist.ReduceOp.SUM, async_op=False) + self.sum, self.count = total.tolist() + self.avg = self.sum / self.count + + def __str__(self): + fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})' + return fmtstr.format(**self.__dict__) + + def summary(self): + fmtstr = '' + if self.summary_type is Summary.NONE: + fmtstr = '' + elif self.summary_type is Summary.AVERAGE: + fmtstr = '{name} {avg:.3f}' + elif self.summary_type is Summary.SUM: + fmtstr = '{name} {sum:.3f}' + elif self.summary_type is Summary.COUNT: + fmtstr = '{name} {count:.3f}' + else: + raise ValueError('invalid summary type %r' % self.summary_type) + + return fmtstr.format(**self.__dict__) + + +class ProgressMeter(object): + def __init__(self, num_batches, meters, prefix=""): + self.batch_fmtstr = self._get_batch_fmtstr(num_batches) + self.meters = meters + self.prefix = prefix + + def display(self, batch): + entries = [self.prefix + self.batch_fmtstr.format(batch)] + entries += [str(meter) for meter in self.meters] + print('\t'.join(entries)) + + def display_summary(self): + entries = [" *"] + entries += [meter.summary() for meter in self.meters] + print(' '.join(entries)) + + def _get_batch_fmtstr(self, num_batches): + num_digits = len(str(num_batches // 1)) + fmt = '{:' + str(num_digits) + 'd}' + return '[' + fmt + '/' + fmt.format(num_batches) + ']' + +def accuracy(output, target, topk=(1,)): + """Computes the accuracy over the k top predictions for the specified values of k""" + with torch.no_grad(): + maxk = max(topk) + batch_size = target.size(0) + + _, pred = output.topk(maxk, 1, True, True) + pred = pred.t() + correct = pred.eq(target.view(1, -1).expand_as(pred)) + + res = [] + for k in topk: + correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True) + res.append(correct_k.mul_(100.0 / batch_size)) + return res + + +if __name__ == '__main__': + main()