simplecov 0.22.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +173 -875
- data/exe/simplecov +8 -0
- data/lib/minitest/simplecov_plugin.rb +18 -7
- data/lib/simplecov/atomic_file.rb +67 -0
- data/lib/simplecov/autostart.rb +9 -0
- data/lib/simplecov/baseline/parser.rb +58 -0
- data/lib/simplecov/baseline.rb +170 -0
- data/lib/simplecov/cli/affected/changed_files.rb +57 -0
- data/lib/simplecov/cli/affected/selection.rb +117 -0
- data/lib/simplecov/cli/affected.rb +148 -0
- data/lib/simplecov/cli/annotations.rb +166 -0
- data/lib/simplecov/cli/badge/svg.rb +70 -0
- data/lib/simplecov/cli/badge.rb +62 -0
- data/lib/simplecov/cli/clean.rb +86 -0
- data/lib/simplecov/cli/command_helpers.rb +91 -0
- data/lib/simplecov/cli/completions/scripts.rb +114 -0
- data/lib/simplecov/cli/completions.rb +83 -0
- data/lib/simplecov/cli/coverage.rb +83 -0
- data/lib/simplecov/cli/coverage_file.rb +109 -0
- data/lib/simplecov/cli/dead_code/output.rb +100 -0
- data/lib/simplecov/cli/dead_code.rb +139 -0
- data/lib/simplecov/cli/diff/output.rb +45 -0
- data/lib/simplecov/cli/diff.rb +115 -0
- data/lib/simplecov/cli/dotfile.rb +156 -0
- data/lib/simplecov/cli/git.rb +41 -0
- data/lib/simplecov/cli/history/output.rb +135 -0
- data/lib/simplecov/cli/history.rb +67 -0
- data/lib/simplecov/cli/merge.rb +115 -0
- data/lib/simplecov/cli/open.rb +45 -0
- data/lib/simplecov/cli/patch/changed_lines.rb +149 -0
- data/lib/simplecov/cli/patch/output.rb +151 -0
- data/lib/simplecov/cli/patch.rb +175 -0
- data/lib/simplecov/cli/ratchet/output.rb +44 -0
- data/lib/simplecov/cli/ratchet.rb +83 -0
- data/lib/simplecov/cli/report.rb +91 -0
- data/lib/simplecov/cli/run.rb +35 -0
- data/lib/simplecov/cli/serve/report_preparer.rb +30 -0
- data/lib/simplecov/cli/serve/static_file_handler.rb +128 -0
- data/lib/simplecov/cli/serve.rb +88 -0
- data/lib/simplecov/cli/show/annotator.rb +87 -0
- data/lib/simplecov/cli/show/sweep.rb +36 -0
- data/lib/simplecov/cli/show.rb +133 -0
- data/lib/simplecov/cli/status/facts.rb +87 -0
- data/lib/simplecov/cli/status.rb +93 -0
- data/lib/simplecov/cli/tests/redundancy.rb +78 -0
- data/lib/simplecov/cli/tests.rb +148 -0
- data/lib/simplecov/cli/uncovered/misses.rb +33 -0
- data/lib/simplecov/cli/uncovered.rb +127 -0
- data/lib/simplecov/cli/usage.rb +153 -0
- data/lib/simplecov/cli/watch/live_report.rb +73 -0
- data/lib/simplecov/cli/watch/narrator.rb +55 -0
- data/lib/simplecov/cli/watch/poller.rb +45 -0
- data/lib/simplecov/cli/watch/session.rb +134 -0
- data/lib/simplecov/cli/watch/test_plan.rb +43 -0
- data/lib/simplecov/cli/watch.rb +85 -0
- data/lib/simplecov/cli.rb +114 -0
- data/lib/simplecov/color.rb +65 -0
- data/lib/simplecov/combine/branches_combiner.rb +44 -21
- data/lib/simplecov/combine/coverage_accumulator.rb +175 -0
- data/lib/simplecov/combine/identity_interner.rb +27 -0
- data/lib/simplecov/combine/interned_counts.rb +28 -0
- data/lib/simplecov/combine/lines_combiner.rb +35 -29
- data/lib/simplecov/combine/methods_combiner.rb +48 -0
- data/lib/simplecov/combine/results_combiner.rb +9 -49
- data/lib/simplecov/combine.rb +0 -24
- data/lib/simplecov/command_guesser.rb +99 -42
- data/lib/simplecov/configuration/baseline.rb +31 -0
- data/lib/simplecov/configuration/coverage.rb +184 -0
- data/lib/simplecov/configuration/coverage_criteria.rb +143 -0
- data/lib/simplecov/configuration/deprecations.rb +21 -0
- data/lib/simplecov/configuration/eval_coverage.rb +37 -0
- data/lib/simplecov/configuration/filters.rb +131 -0
- data/lib/simplecov/configuration/formatting.rb +129 -0
- data/lib/simplecov/configuration/groups.rb +48 -0
- data/lib/simplecov/configuration/history.rb +44 -0
- data/lib/simplecov/configuration/ignored_entries.rb +72 -0
- data/lib/simplecov/configuration/merging.rb +197 -0
- data/lib/simplecov/configuration/missed_caps.rb +51 -0
- data/lib/simplecov/configuration/production.rb +23 -0
- data/lib/simplecov/configuration/test_tracking.rb +48 -0
- data/lib/simplecov/configuration/thresholds.rb +150 -0
- data/lib/simplecov/configuration/view_coverage.rb +37 -0
- data/lib/simplecov/configuration.rb +100 -443
- data/lib/simplecov/configuration_error.rb +5 -0
- data/lib/simplecov/context_map/union.rb +81 -0
- data/lib/simplecov/context_map.rb +187 -0
- data/lib/simplecov/coverage_json.rb +21 -0
- data/lib/simplecov/coverage_statistics.rb +24 -28
- data/lib/simplecov/coverage_violations.rb +254 -0
- data/lib/simplecov/current_run.rb +61 -0
- data/lib/simplecov/defaults.rb +20 -28
- data/lib/simplecov/deprecation.rb +63 -0
- data/lib/simplecov/directive/erb.rb +44 -0
- data/lib/simplecov/directive/haml.rb +33 -0
- data/lib/simplecov/directive/indented_template.rb +37 -0
- data/lib/simplecov/directive/slim.rb +35 -0
- data/lib/simplecov/directive/template.rb +29 -0
- data/lib/simplecov/directive.rb +152 -0
- data/lib/simplecov/exit_codes/baseline_check.rb +46 -0
- data/lib/simplecov/exit_codes/check.rb +39 -0
- data/lib/simplecov/exit_codes/exit_code_handling.rb +24 -5
- data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +17 -67
- data/lib/simplecov/exit_codes/maximum_missed_check.rb +26 -0
- data/lib/simplecov/exit_codes/maximum_missed_per_file_check.rb +34 -0
- data/lib/simplecov/exit_codes/maximum_overall_coverage_check.rb +27 -0
- data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +20 -38
- data/lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb +28 -0
- data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +37 -34
- data/lib/simplecov/exit_codes.rb +26 -0
- data/lib/simplecov/exit_handling.rb +163 -0
- data/lib/simplecov/file_list.rb +63 -48
- data/lib/simplecov/filter.rb +98 -42
- data/lib/simplecov/formatter/base.rb +100 -0
- data/lib/simplecov/formatter/baseline_formatter.rb +98 -0
- data/lib/simplecov/formatter/coverage_json_writer.rb +95 -0
- data/lib/simplecov/formatter/html_formatter/public/index.html +93 -0
- data/lib/simplecov/formatter/html_formatter/viewer_data_validator.rb +153 -0
- data/lib/simplecov/formatter/html_formatter.rb +88 -0
- data/lib/simplecov/formatter/json_formatter/errors_formatter.rb +122 -0
- data/lib/simplecov/formatter/json_formatter/production_section_formatter.rb +48 -0
- data/lib/simplecov/formatter/json_formatter/result_hash_formatter.rb +132 -0
- data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +97 -0
- data/lib/simplecov/formatter/json_formatter.rb +40 -0
- data/lib/simplecov/formatter/multi_formatter.rb +8 -10
- data/lib/simplecov/formatter/simple_formatter.rb +12 -15
- data/lib/simplecov/formatter.rb +21 -1
- data/lib/simplecov/group_names.rb +33 -0
- data/lib/simplecov/history.rb +115 -0
- data/lib/simplecov/last_run.rb +16 -5
- data/lib/simplecov/lines_classifier.rb +67 -19
- data/lib/simplecov/load_global_config.rb +12 -4
- data/lib/simplecov/parallel_adapters/base.rb +50 -0
- data/lib/simplecov/parallel_adapters/generic.rb +33 -0
- data/lib/simplecov/parallel_adapters/parallel_tests.rb +72 -0
- data/lib/simplecov/parallel_adapters.rb +54 -0
- data/lib/simplecov/parallel_coordination.rb +124 -0
- data/lib/simplecov/parallel_result_merger/worker_payload.rb +33 -0
- data/lib/simplecov/parallel_result_merger.rb +171 -0
- data/lib/simplecov/process.rb +34 -12
- data/lib/simplecov/production/error.rb +11 -0
- data/lib/simplecov/production/file_sink.rb +130 -0
- data/lib/simplecov/production.rb +249 -0
- data/lib/simplecov/profiles/bundler_filter.rb +1 -1
- data/lib/simplecov/profiles/hidden_filter.rb +1 -1
- data/lib/simplecov/profiles/rails.rb +13 -10
- data/lib/simplecov/profiles/root_filter.rb +2 -5
- data/lib/simplecov/profiles/strict.rb +22 -0
- data/lib/simplecov/profiles/test_frameworks.rb +1 -4
- data/lib/simplecov/profiles.rb +26 -19
- data/lib/simplecov/report_deferral.rb +45 -0
- data/lib/simplecov/report_stamp.rb +25 -0
- data/lib/simplecov/result/filter_config.rb +19 -0
- data/lib/simplecov/result/missing_source_files_reporter.rb +48 -0
- data/lib/simplecov/result/serialization.rb +43 -0
- data/lib/simplecov/result/source_file_builder.rb +46 -0
- data/lib/simplecov/result.rb +123 -47
- data/lib/simplecov/result_adapter.rb +130 -11
- data/lib/simplecov/result_merger/contexts.rb +22 -0
- data/lib/simplecov/result_merger/legacy_format_adapter.rb +24 -0
- data/lib/simplecov/result_merger/resultset_file.rb +67 -0
- data/lib/simplecov/result_merger/resultset_run_identity.rb +65 -0
- data/lib/simplecov/result_merger/resultset_store.rb +62 -0
- data/lib/simplecov/result_merger/unloaded_files.rb +95 -0
- data/lib/simplecov/result_merger.rb +120 -124
- data/lib/simplecov/result_processing.rb +188 -0
- data/lib/simplecov/run_identity.rb +75 -0
- data/lib/simplecov/simulate_coverage.rb +72 -17
- data/lib/simplecov/source_file/branch.rb +8 -35
- data/lib/simplecov/source_file/branch_builder.rb +95 -0
- data/lib/simplecov/source_file/builder_context.rb +28 -0
- data/lib/simplecov/source_file/line.rb +17 -32
- data/lib/simplecov/source_file/line_builder.rb +37 -0
- data/lib/simplecov/source_file/method.rb +54 -0
- data/lib/simplecov/source_file/method_builder.rb +51 -0
- data/lib/simplecov/source_file/ruby_data_parser.rb +103 -0
- data/lib/simplecov/source_file/skip_chunks.rb +72 -0
- data/lib/simplecov/source_file/source_loader.rb +89 -0
- data/lib/simplecov/source_file/statistics.rb +76 -0
- data/lib/simplecov/source_file.rb +64 -260
- data/lib/simplecov/static_coverage_extractor/condition_folding.rb +155 -0
- data/lib/simplecov/static_coverage_extractor/location_conventions.rb +191 -0
- data/lib/simplecov/static_coverage_extractor/method_collector.rb +45 -0
- data/lib/simplecov/static_coverage_extractor/prism_compat.rb +46 -0
- data/lib/simplecov/static_coverage_extractor/value_position.rb +61 -0
- data/lib/simplecov/static_coverage_extractor/visitor.rb +163 -0
- data/lib/simplecov/static_coverage_extractor.rb +78 -0
- data/lib/simplecov/test_tracker/accessors.rb +34 -0
- data/lib/simplecov/test_tracker/constant_watch.rb +49 -0
- data/lib/simplecov/test_tracker/delta.rb +69 -0
- data/lib/simplecov/test_tracker/framework_hooks.rb +130 -0
- data/lib/simplecov/test_tracker.rb +162 -0
- data/lib/simplecov/unloaded_file_injector.rb +62 -0
- data/lib/simplecov/useless_results_remover.rb +17 -7
- data/lib/simplecov/version.rb +1 -1
- data/lib/simplecov/view_coverage/template_compiler.rb +83 -0
- data/lib/simplecov/view_coverage.rb +55 -0
- data/lib/simplecov-html.rb +5 -0
- data/lib/simplecov.rb +143 -394
- data/lib/simplecov_json_formatter.rb +5 -0
- data/man/simplecov.1 +354 -0
- data/sig/simplecov.rbs +1710 -0
- metadata +183 -61
- data/CHANGELOG.md +0 -191
- data/doc/alternate-formatters.md +0 -71
- data/doc/commercial-services.md +0 -25
- data/doc/editor-integration.md +0 -18
- data/lib/simplecov/combine/files_combiner.rb +0 -24
- data/lib/simplecov/default_formatter.rb +0 -20
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Code Coverage</title>
|
|
7
|
+
<style>*,*:before,*:after{box-sizing:border-box}*{margin:0;padding:0}html{-moz-text-size-adjust:none;-webkit-text-size-adjust:none;text-size-adjust:none}body{min-height:100vh;line-height:1.5;-webkit-font-smoothing:antialiased}img,picture,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit}h1,h2,h3,h4,h5,h6{overflow-wrap:break-word;text-wrap:balance}p{overflow-wrap:break-word;text-wrap:pretty}table{border-collapse:collapse;border-spacing:0}ul,ol{list-style:none}a{text-decoration-skip-ink:auto;color:currentColor}.hide{display:none}.hljs{color:#24292e}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media(prefers-color-scheme:dark){:root:not(.light-mode) .hljs{color:#c9d1d9}:root:not(.light-mode) .hljs-doctag,:root:not(.light-mode) .hljs-keyword,:root:not(.light-mode) .hljs-meta .hljs-keyword,:root:not(.light-mode) .hljs-template-tag,:root:not(.light-mode) .hljs-template-variable,:root:not(.light-mode) .hljs-type,:root:not(.light-mode) .hljs-variable.language_{color:#ff7b72}:root:not(.light-mode) .hljs-title,:root:not(.light-mode) .hljs-title.class_,:root:not(.light-mode) .hljs-title.class_.inherited__,:root:not(.light-mode) .hljs-title.function_{color:#d2a8ff}:root:not(.light-mode) .hljs-attr,:root:not(.light-mode) .hljs-attribute,:root:not(.light-mode) .hljs-literal,:root:not(.light-mode) .hljs-meta,:root:not(.light-mode) .hljs-number,:root:not(.light-mode) .hljs-operator,:root:not(.light-mode) .hljs-variable,:root:not(.light-mode) .hljs-selector-attr,:root:not(.light-mode) .hljs-selector-class,:root:not(.light-mode) .hljs-selector-id{color:#79c0ff}:root:not(.light-mode) .hljs-regexp,:root:not(.light-mode) .hljs-string,:root:not(.light-mode) .hljs-meta .hljs-string{color:#a5d6ff}:root:not(.light-mode) .hljs-built_in,:root:not(.light-mode) .hljs-symbol{color:#ffa657}:root:not(.light-mode) .hljs-comment,:root:not(.light-mode) .hljs-code,:root:not(.light-mode) .hljs-formula{color:#8b949e}:root:not(.light-mode) .hljs-name,:root:not(.light-mode) .hljs-quote,:root:not(.light-mode) .hljs-selector-tag,:root:not(.light-mode) .hljs-selector-pseudo{color:#7ee787}:root:not(.light-mode) .hljs-subst{color:#c9d1d9}:root:not(.light-mode) .hljs-section{color:#1f6feb}}.dark-mode .hljs{color:#c9d1d9}.dark-mode .hljs-doctag,.dark-mode .hljs-keyword,.dark-mode .hljs-meta .hljs-keyword,.dark-mode .hljs-template-tag,.dark-mode .hljs-template-variable,.dark-mode .hljs-type,.dark-mode .hljs-variable.language_{color:#ff7b72}.dark-mode .hljs-title,.dark-mode .hljs-title.class_,.dark-mode .hljs-title.class_.inherited__,.dark-mode .hljs-title.function_{color:#d2a8ff}.dark-mode .hljs-attr,.dark-mode .hljs-attribute,.dark-mode .hljs-literal,.dark-mode .hljs-meta,.dark-mode .hljs-number,.dark-mode .hljs-operator,.dark-mode .hljs-variable,.dark-mode .hljs-selector-attr,.dark-mode .hljs-selector-class,.dark-mode .hljs-selector-id{color:#79c0ff}.dark-mode .hljs-regexp,.dark-mode .hljs-string,.dark-mode .hljs-meta .hljs-string{color:#a5d6ff}.dark-mode .hljs-built_in,.dark-mode .hljs-symbol{color:#ffa657}.dark-mode .hljs-comment,.dark-mode .hljs-code,.dark-mode .hljs-formula{color:#8b949e}.dark-mode .hljs-name,.dark-mode .hljs-quote,.dark-mode .hljs-selector-tag,.dark-mode .hljs-selector-pseudo{color:#7ee787}.dark-mode .hljs-subst{color:#c9d1d9}.dark-mode .hljs-section{color:#1f6feb}:root{--aj: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--as: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;--f: 4px;--c: 8px;--aw: 12px;--o: 16px;--bc: 20px;--p: 24px;--bd: 32px;--ay: 8px;--ax: 12px;--au: 16px;--av: 34px;--az: var(--o);--bb: calc(var(--av) + var(--az));--m: #f0f1f3;--g: #fff;--ai: #f0f1f3;--a: #111;--h: #333;--e: #444;--aq: #f4f5f7;--b: #c0c5cc;--q: #999;--d: #0550ae;--ar: #033d8b;--u: #ddf4ff;--green: #116329;--red: #a40e26;--yellow: #7a5200;--at: #953800;--i: #ccf5d0;--j: #9ae6a4;--k: #ffd8d5;--l: #ffb8b3;--ab: #fff;--am: #f0f1f3;--af: #fff0a0;--ag: #eed860;--w: #ffd0a0;--x: #ffb060;--y: #b45309;--z: #e8d0ff;--aa: #d4b0ff;--r: #7b2d8e;--ac: #dfe5ee;--ad: #b6c4da;--s: #3f5578;--t: #0d7a80;--ae: #8a919a;--ao: #fff;--n: #c0c5cc;--ap: #444;--ah: #f0f1f3;--ak: #e0e3e8;--al: #333;--an: rgba(0, 0, 0, .5);--v: #d0d7de;--ba: 6px}@media(prefers-color-scheme:dark){:root:not(.light-mode){--m: #010409;--g: #0d1117;--ai: #161b22;--a: #f0f3f6;--h: #b0b8c4;--e: #9aa5b1;--aq: #161b22;--b: #3d444d;--q: #555e68;--d: #6cb6ff;--ar: #96ccff;--u: #121d2f;--green: #56d364;--red: #ff6b61;--yellow: #e3b341;--at: #f0883e;--i: #122d1e;--j: #1e4430;--k: #351418;--l: #4e1d20;--ab: #0d1117;--am: #161b22;--af: #302818;--ag: #443920;--w: #322218;--x: #483020;--y: #ffb86c;--z: #1e1830;--aa: #2a2044;--r: #dcb8ff;--ac: #1a2231;--ad: #28344c;--s: #9db2d9;--t: #39c5cf;--ae: #6e7681;--ao: #0d1117;--n: #3d444d;--ap: #9aa5b1;--ah: #161b22;--ak: #262c34;--al: #b0b8c4;--an: rgba(1, 4, 9, .8);--v: #3d444d}}.dark-mode{--m: #010409;--g: #0d1117;--ai: #161b22;--a: #f0f3f6;--h: #b0b8c4;--e: #9aa5b1;--aq: #161b22;--b: #3d444d;--q: #555e68;--d: #6cb6ff;--ar: #96ccff;--u: #121d2f;--green: #56d364;--red: #ff6b61;--yellow: #e3b341;--at: #f0883e;--i: #122d1e;--j: #1e4430;--k: #351418;--l: #4e1d20;--ab: #0d1117;--am: #161b22;--af: #302818;--ag: #443920;--w: #322218;--x: #483020;--y: #ffb86c;--z: #1e1830;--aa: #2a2044;--r: #dcb8ff;--ac: #1a2231;--ad: #28344c;--s: #9db2d9;--t: #39c5cf;--ae: #6e7681;--ao: #0d1117;--n: #3d444d;--ap: #9aa5b1;--ah: #161b22;--ak: #262c34;--al: #b0b8c4;--an: rgba(1, 4, 9, .8);--v: #3d444d}.colorblind-mode{--green: #0060a8;--red: #c2410c;--i: #d3eaf7;--j: #a5d2ee;--k: #ffe0cc;--l: #ffc39a}@media screen and (prefers-color-scheme:dark){.colorblind-mode:not(.light-mode){--green: #6cb6ff;--red: #f0883e;--i: #0e2a45;--j: #12385c;--k: #3a2410;--l: #52331a}}@media screen{.colorblind-mode.dark-mode{--green: #6cb6ff;--red: #f0883e;--i: #0e2a45;--j: #12385c;--k: #3a2410;--l: #52331a}}html{scrollbar-gutter:stable}body{font-family:var(--aj);font-size:18px;color:var(--a);background:var(--m);padding:var(--p)}a{color:var(--d);text-decoration:none;transition:color .15s}a:hover{color:var(--ar)}strong,b{font-weight:600}#loading{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:var(--m);z-index:9999}#loading-inner{width:280px;text-align:center}#loading-bar-track{width:100%;height:6px;background:var(--v);border-radius:6px;overflow:hidden}#loading-bar-fill{width:0%;height:100%;background:var(--d);border-radius:6px;transition:width .15s ease-out}#loading-text{margin-top:var(--aw);font-size:18px;color:var(--e)}#sort-overlay{position:fixed;inset:0;z-index:9998;display:flex;align-items:center;justify-content:center;background:var(--an)}#sort-overlay-label{padding:var(--c) var(--o);border:1px solid var(--b);border-radius:6px;background:var(--m);font-size:16px;color:var(--e)}#wrapper{margin:0 auto}.tab-bar{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--o);margin-bottom:-1px;position:relative;z-index:1}abbr.timeago{text-decoration:none;border:none}.group_tabs{display:flex;align-self:flex-end;gap:var(--f);overflow-x:auto;padding-right:var(--p);mask-image:linear-gradient(to right,#000 calc(100% - var(--p)),transparent)}.group_tabs.is-scrolled{mask-image:linear-gradient(to right,transparent,#000 var(--p),#000 calc(100% - var(--p)),transparent)}.group_tabs li a{display:block;padding:var(--c) var(--o);font-size:18px;font-weight:500;color:var(--h);background:transparent;border:1px solid var(--b);border-bottom:none;border-radius:var(--ax) var(--ax) 0 0;white-space:nowrap;transition:color .15s,background .15s,border-color .15s}.group_tabs li a:hover{color:var(--a);background:var(--ai);border-color:var(--q);text-decoration:none}.group_tabs li.active a{color:var(--d);background:var(--g);border-color:var(--b);font-weight:600}#content{background:var(--g);border:1px solid var(--b);border-radius:0 var(--au) var(--au) var(--au);padding:var(--p)}.file_list_container h2{font-size:24px;font-weight:600;color:var(--a);margin:0}.file_list_container h2 .covered_percent{font-weight:600}.summary-stats{display:flex;flex-direction:column;gap:var(--f);font-size:18px;color:var(--h)}.summary-stats b{color:var(--a)}.summary-stats .missed-branch-text b,.summary-stats .missed-method-text-color b,.summary-stats .green b,.summary-stats .red b{color:inherit}.summary-stats .green{color:var(--green)}.summary-stats .red{color:var(--red)}.coverage-disabled{color:var(--e);font-style:italic}.th-with-filter{display:flex;align-items:center;gap:var(--c)}table.file_list th.cell--coverage .th-with-filter{white-space:nowrap;justify-content:flex-end}.th-with-filter .th-label{white-space:nowrap}.col-filter--name{width:100%;min-width:200px;border:1px solid var(--b);border-radius:999px;padding:var(--f) var(--o);font-size:14px;background:var(--g);color:var(--a);outline:none}.col-filter--name:focus{border-color:var(--d)}.col-filter__coverage{display:flex;gap:var(--f)}.col-filter__op{border:1px solid var(--b);border-radius:var(--ay);padding:var(--f) var(--f);font-size:14px;background:var(--g);color:var(--a);cursor:pointer}.col-filter__value{border:1px solid var(--b);border-radius:var(--ay);padding:var(--f) var(--c);font-size:14px;background:var(--g);color:var(--a);width:60px;outline:none}.col-filter__value:focus{border-color:var(--d)}.file_list--responsive{overflow-x:auto}table.file_list{width:100%;font-size:18px}table.file_list{border-collapse:separate;border-spacing:0}table.file_list thead th{font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--e);background:var(--g);padding:var(--c) var(--c);border-bottom:2px solid var(--q);white-space:nowrap}table.file_list tbody tr{background:var(--g);cursor:pointer}table.file_list tbody tr:nth-child(2n){background:var(--aq)}table.file_list tbody tr:hover{background:var(--u)}table.file_list tbody tr.keyboard-focus{background:var(--u);outline:2px solid var(--d);outline-offset:-2px}table.file_list tbody td{padding:var(--c) var(--c);border-bottom:1px solid var(--b);color:var(--a)}table.file_list td.cell--number{text-align:right;font-variant-numeric:tabular-nums;color:var(--a)}table.file_list th.cell--left,table.file_list th.cell--coverage{text-align:left}table.file_list th.cell--number{text-align:right}table.file_list th.cell--numerator{text-align:right;padding-right:0}table.file_list th.cell--denominator{text-align:left;padding-left:0}table.file_list td.strong{font-weight:600;color:var(--a)}table.file_list th.cell--production,table.file_list td.cell--production{text-align:right;white-space:nowrap}table.file_list td.t-file__production--never{color:var(--e)}table.file_list td.t-file__name{white-space:nowrap}a.src_link{color:var(--d);font-weight:500;word-break:break-all}table.file_list td.cell--coverage{white-space:nowrap}.coverage-cell{display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-end;gap:10px}.coverage-cell .coverage-pct{flex:0 0 4.5em;font-variant-numeric:tabular-nums}tr.t-window-hidden{display:none}tr.t-show-all td{padding:var(--aw);text-align:center;color:var(--e);cursor:pointer}.coverage-cell .bar-sizer{flex:0 0 auto;width:var(--bar-sizer-width, 240px);min-width:160px;max-width:240px}table.file_list td.cell--numerator{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;padding-left:var(--f);padding-right:0}table.file_list td.cell--denominator{text-align:left;font-variant-numeric:tabular-nums;white-space:nowrap;padding-left:0;padding-right:var(--f)}table.file_list .totals-row td.cell--numerator{color:var(--a);padding-right:0}table.file_list .totals-row td.cell--denominator{color:var(--a);padding-left:0}.coverage-cell__fraction{font-variant-numeric:tabular-nums;color:var(--h);font-size:14px;white-space:nowrap}.coverage-bar{display:flex;width:100%;height:var(--ba);background:var(--v);border-radius:6px;overflow:hidden}.coverage-bar__fill{flex:none;height:100%;border-radius:6px}.coverage-bar__fill--green{background:var(--green)}.coverage-bar__fill--yellow{background:var(--yellow)}.coverage-bar__fill--red{background:var(--red)}.coverage-bar__fill--split{border-radius:6px 0 0 6px}.coverage-bar__fill--outside{background:var(--s);border-radius:0 6px 6px 0}.green,table.file_list td.green{color:var(--green)}.red,table.file_list td.red{color:var(--red)}.yellow,table.file_list td.yellow{color:var(--yellow)}.missed-branch-text{color:var(--y)}.missed-method-text-color{color:var(--r)}dialog.source-dialog{position:fixed;inset:0;width:100%;height:100%;max-width:100%;max-height:100%;border:none;padding:0;background:var(--m);color:var(--a);overflow:hidden}dialog.source-dialog::backdrop{background:var(--an)}dialog.source-dialog[open]{display:flex;flex-direction:column}.source-dialog__header{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:flex-start;padding:var(--p);background:var(--m);border-bottom:1px solid var(--b);flex-shrink:0}.source-dialog__title{display:contents;min-width:0}.source-dialog__title h2{grid-column:1;grid-row:1;font-size:22px;font-weight:700;color:var(--a);margin-bottom:var(--c);word-break:break-all}.source-dialog__title .summary-stats{display:contents}.source-dialog__title .t-line-summary{grid-column:1;grid-row:2}.source-dialog__title .t-branch-summary{grid-column:1;grid-row:3}.source-dialog__title .t-method-summary{grid-column:1;grid-row:4}.source-dialog__title>.t-missed-method-list{grid-column:1 / -1;grid-row:5}.source-legend{grid-column:2 / 3;grid-row:2 / 5;display:grid;grid-template-rows:subgrid;grid-template-columns:repeat(4,auto);column-gap:var(--o);justify-content:end;justify-items:start;align-items:baseline}.source-legend__row{display:contents}.source-legend__row--line .source-legend__item{grid-row:1}.source-legend__row--branch .source-legend__item{grid-row:2;grid-column:4}.source-legend__row--method .source-legend__item{grid-row:3;grid-column:4}.source-legend__row--line .source-legend__item:nth-last-child(1){grid-column:4}.source-legend__row--line .source-legend__item:nth-last-child(2){grid-column:3}.source-legend__row--line .source-legend__item:nth-last-child(3){grid-column:2}.source-legend__row--line .source-legend__item:nth-last-child(4){grid-column:1}.source-legend__item{display:flex;align-items:center;gap:var(--f);font-size:13px;color:var(--h);white-space:nowrap}.source-legend__swatch{display:inline-block;width:16px;height:16px;border-radius:3px;border:1px solid var(--b)}.source-legend__swatch--covered{background:var(--i);border-color:var(--j);color:var(--green)}.source-legend__swatch--missed{background:var(--k);border-color:var(--l);color:var(--red)}.source-legend__swatch--skipped{background:var(--af);border-color:var(--ag);color:var(--h)}.source-legend__swatch--missed-branch{background:var(--w);border-color:var(--x);color:var(--y)}.source-legend__swatch--missed-method{background:var(--z);border-color:var(--aa);color:var(--r)}.source-legend__swatch--outside-tests{background:var(--ac);border-color:var(--ad);color:var(--s)}.source-legend__swatch--production-never{background:var(--i);border-color:var(--j);box-shadow:inset 4px 0 0 var(--ae)}.source-legend__swatch--production-ran{background:var(--k);border-color:var(--l);box-shadow:inset 4px 0 0 var(--t)}.source-dialog__toggles{display:flex;align-items:center;gap:var(--c);flex-shrink:0;margin-left:var(--o);align-self:flex-start;justify-self:end}.source-dialog__close{appearance:none;background:none;border:1px solid var(--b);border-radius:50%;width:var(--av);height:var(--av);font-size:0;color:var(--h);cursor:pointer;position:relative;flex-shrink:0;margin-left:var(--az);transition:color .15s,border-color .15s}.source-dialog__close:before,.source-dialog__close:after{content:"";position:absolute;top:50%;left:50%;width:14px;height:2px;background:currentColor;border-radius:1px}.source-dialog__close:before{transform:translate(-50%,-50%) rotate(45deg)}.source-dialog__close:after{transform:translate(-50%,-50%) rotate(-45deg)}.source-dialog__close:hover{color:var(--a);border-color:var(--q)}.source-dialog__body{flex:1;overflow:auto}.source_table .header{padding:var(--o) var(--p);background:var(--g)}.source_table .header h2{font-size:22px;font-weight:700;color:var(--a);margin-bottom:var(--c)}table.file_list .totals-row td{padding:var(--c) var(--c);font-weight:600;border-bottom:2px solid var(--q);background:var(--ai)}.totals-row .t-file-count{font-size:18px;font-weight:700;color:var(--a)}.t-missed-method-toggle{color:var(--r);font-weight:600;cursor:pointer;text-decoration:none}.t-missed-method-toggle:hover{text-decoration:underline;color:var(--r)}.t-missed-method-list ul{padding-left:2em;margin-top:var(--f);max-height:200px;overflow-y:auto}.t-missed-method-list li{list-style:none}.source_table pre{margin:0;padding:0;white-space:normal;color:var(--a);font-family:var(--as);font-size:16px;line-height:24px;background:var(--ao);border:1px solid var(--n);border-top:none}.source_table code{color:inherit;font-family:var(--as)}.source_table pre ol{margin:0;padding:0;list-style:none;counter-reset:linenumber}.source_table pre li{display:flex;counter-increment:linenumber;background:var(--ab)}.source_table pre li:before{content:counter(linenumber);flex-shrink:0;width:50px;padding:0 8px;text-align:right;color:var(--ap);background:var(--ah);border-right:1px solid var(--n);-webkit-user-select:none;user-select:none;cursor:pointer}.source_table pre li:hover:before{color:var(--a)}.source_table pre li:hover{cursor:pointer}.source_table pre li code{order:1;flex:1;min-width:0;padding:0 12px;white-space:pre-wrap}.source_table pre .hits{order:2;flex-shrink:0;padding:0 var(--c);background:var(--ak);color:var(--al);font-family:var(--as);font-size:14px;text-align:center;line-height:24px;border-left:1px solid var(--n);-webkit-user-select:none;user-select:none}.source_table pre .hits:after{content:attr(data-content)}.source_table .covered{background-color:var(--i)}.source_table .missed{background-color:var(--k)}.source_table .never{background-color:var(--ab)}.source_table .skipped{background-color:var(--af)}.source_table .missed-branch{background-color:var(--w)}.source_table .missed-method{background-color:var(--z)}.source_table .covered:before{background-color:var(--j)}.source_table .missed:before{background-color:var(--l)}.source_table .never:before{background-color:var(--am)}.source_table .skipped:before{background-color:var(--ag)}.source_table .missed-branch:before{background-color:var(--x)}.source_table .missed-method:before{background-color:var(--aa)}.source_table .outside-tests{background-color:var(--ac)}.source_table .outside-tests:before{background-color:var(--ad)}.outside-tests-text{color:var(--s)}.source_table .covered.production-never:before,.source_table .outside-tests.production-never:before{box-shadow:inset 4px 0 0 var(--ae)}.source_table .missed.production-ran:before,.source_table .missed-branch.production-ran:before,.source_table .missed-method.production-ran:before{box-shadow:inset 4px 0 0 var(--t)}.source_table pre .hits--production{color:var(--t)}.source_table pre button.hits--tests{appearance:none;border:0;border-left:1px solid var(--n);cursor:pointer;display:flex;align-items:flex-start;justify-content:center}.source_table pre button.hits--tests:hover:after,.source_table pre button.hits--tests[aria-expanded=true]:after{text-decoration:underline}.source_table pre .hits--tests-none{color:var(--s)}.source_table pre li.tests-peek{counter-increment:none;display:block;padding:6px 12px 8px 58px;background:var(--ah);border-top:1px solid var(--n);border-bottom:1px solid var(--n)}.source_table pre li.tests-peek:before{content:none}.source_table pre .tests-peek li{counter-increment:none;display:block;background:transparent}.source_table pre .tests-peek li:before{content:none}.tests-peek__title{font-family:var(--aj);font-size:13px;font-weight:600;color:var(--h);margin-bottom:4px}.tests-peek__note{font-family:var(--aj);font-size:13px;color:var(--e)}.tests-peek__list{margin:0;padding:0;list-style:none;columns:30ch;column-gap:24px;max-height:240px;overflow-y:auto}.tests-peek__list code{font-size:13px;-webkit-user-select:all;user-select:all}.toolbar{display:flex;align-items:flex-start;gap:var(--c);flex-shrink:0;margin-right:var(--bb)}.toolbar-toggle{appearance:none;background:transparent;color:var(--h);border:1px solid var(--b);border-radius:999px;padding:var(--f) var(--o);font-size:16px;font-family:var(--aj);cursor:pointer;white-space:nowrap;transition:color .15s,border-color .15s,background .15s}.toolbar-toggle:hover{color:var(--a);background:var(--g);border-color:var(--q)}.toolbar-toggle[aria-pressed=true]{background:var(--u);color:var(--d);border-color:var(--d)}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible,.source_table pre li:focus-visible{outline:2px solid var(--d);outline-offset:2px;border-radius:3px}#footer,.source-dialog__footer{color:var(--e);font-size:16px;text-align:center}#footer{margin-top:var(--bc)}.source-dialog__footer{flex-shrink:0;padding:var(--aw) var(--p);background:var(--m);border-top:1px solid var(--b)}#footer a,.source-dialog__footer a{color:var(--h);text-decoration:underline}#footer a:hover,.source-dialog__footer a:hover{color:var(--a)}#footer,.source-dialog__footer{max-height:10em;overflow-y:auto}.footer-runs{display:inline-block;vertical-align:top}.footer-runs summary{cursor:pointer}.footer-runs__list{display:block;max-height:6em;overflow-y:auto}table.file_list thead th.sorting,table.file_list thead th.sorting_asc,table.file_list thead th.sorting_desc{cursor:pointer;position:relative;padding-right:12px}table.file_list thead th.sorting:after,table.file_list thead th.sorting_asc:after,table.file_list thead th.sorting_desc:after{position:absolute;right:2px;top:50%;transform:translateY(-50%);font-size:14px;color:var(--e)}table.file_list thead th.sorting:after{content:"\2195"}table.file_list thead th.sorting_asc:after{content:"\2191"}table.file_list thead th.sorting_desc:after{content:"\2193"}@media print{:root,.dark-mode{--m: #fff;--g: #fff;--ai: #f4f5f7;--a: #111;--h: #333;--e: #444;--aq: #f4f5f7;--b: #c0c5cc;--q: #999;--d: #0550ae;--green: #116329;--red: #a40e26;--yellow: #7a5200;--at: #953800;--v: #d0d7de;--i: #ccf5d0;--j: #9ae6a4;--k: #ffd8d5;--l: #ffb8b3;--ab: #fff;--am: #f0f1f3;--af: #fff0a0;--ag: #eed860;--w: #ffd0a0;--x: #ffb060;--y: #b45309;--z: #e8d0ff;--aa: #d4b0ff;--r: #7b2d8e;--ac: #dfe5ee;--ad: #b6c4da;--s: #3f5578;--t: #0d7a80;--ae: #8a919a;--ao: #fff;--n: #c0c5cc;--ap: #444;--ah: #f0f1f3;--ak: #e0e3e8;--al: #333}.colorblind-mode{--green: #0060a8;--red: #c2410c;--i: #d3eaf7;--j: #a5d2ee;--k: #ffe0cc;--l: #ffc39a}body{padding:0;font-size:12pt}#loading,#sort-overlay,.toolbar,.source-dialog__toggles,.tab-bar,.source_files,.col-filter--name,.col-filter__coverage,tr.t-show-all,table.file_list thead th.sorting:after,table.file_list thead th.sorting_asc:after,table.file_list thead th.sorting_desc:after{display:none!important}#wrapper,.file_list_container{display:block!important}body:has(.source-dialog[open]) #wrapper{display:none!important}#content{border:none;border-radius:0;padding:0}.file_list_container .group_name{display:inline!important;font-size:16pt;font-weight:700}.file_list_container .covered_percent{display:inline!important;font-weight:600}.file_list_container+.file_list_container{margin-top:24pt}dialog.source-dialog{display:none}dialog.source-dialog[open]{display:block!important;position:static;width:100%;height:auto;max-height:none;overflow:visible;background:#fff}.source-dialog__close{display:none!important}.source-dialog__header{display:block;border-bottom:none;padding:0 0 8pt}.source-dialog__title h2{word-break:normal;overflow-wrap:break-word}.source-legend{justify-content:flex-start}.source-dialog__body{overflow:visible}.source_table pre{font-size:8pt;line-height:1.4}.source_table pre li{-webkit-print-color-adjust:exact;print-color-adjust:exact}.source_table pre li:before{-webkit-print-color-adjust:exact;print-color-adjust:exact}.source_table pre .hits{-webkit-print-color-adjust:exact;print-color-adjust:exact}.coverage-bar{border:1px solid var(--b);-webkit-print-color-adjust:exact;print-color-adjust:exact}.coverage-bar__fill{-webkit-print-color-adjust:exact;print-color-adjust:exact}table.file_list tbody tr:nth-child(2n){-webkit-print-color-adjust:exact;print-color-adjust:exact}table.file_list{font-size:10pt}table.file_list thead th{font-size:9pt}table.file_list{page-break-inside:auto}table.file_list tr{page-break-inside:avoid}table.file_list thead{display:table-header-group}#footer,.source-dialog__footer{font-size:10pt;margin-top:12pt}#footer a:after,.source-dialog__footer a:after{content:" (" attr(href) ")";font-size:9pt;color:var(--e)}}
|
|
8
|
+
</style>
|
|
9
|
+
<script>
|
|
10
|
+
// Apply the saved dark/light and colorblind preferences before paint to
|
|
11
|
+
// avoid a flash of the wrong palette.
|
|
12
|
+
try {
|
|
13
|
+
const pref = localStorage.getItem('simplecov-dark-mode');
|
|
14
|
+
if (pref === 'dark' || pref === 'light') {
|
|
15
|
+
document.documentElement.classList.add(`${pref}-mode`);
|
|
16
|
+
}
|
|
17
|
+
if (localStorage.getItem('simplecov-colorblind-mode') === 'on') {
|
|
18
|
+
document.documentElement.classList.add('colorblind-mode');
|
|
19
|
+
}
|
|
20
|
+
} catch (_error) {
|
|
21
|
+
// localStorage can be unavailable in locked-down browser contexts.
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
</head>
|
|
25
|
+
|
|
26
|
+
<body>
|
|
27
|
+
<div id="loading" style="display: none">
|
|
28
|
+
<div id="loading-inner">
|
|
29
|
+
<div id="loading-bar-track">
|
|
30
|
+
<div id="loading-bar-fill"></div>
|
|
31
|
+
</div>
|
|
32
|
+
<div id="loading-text">Loading...</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div id="wrapper" class="hide">
|
|
37
|
+
<div class="tab-bar">
|
|
38
|
+
<ul class="group_tabs" role="tablist"></ul>
|
|
39
|
+
<div class="toolbar">
|
|
40
|
+
<button class="toolbar-toggle" type="button" data-toggle="colorblind" aria-pressed="false" title="Use a colorblind-friendly palette and coverage symbols">🎨 Colorblind</button>
|
|
41
|
+
<button class="toolbar-toggle" type="button" data-toggle="dark"></button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div id="content"></div>
|
|
46
|
+
|
|
47
|
+
<div id="footer"></div>
|
|
48
|
+
|
|
49
|
+
<div class="source_files" style="display:none"></div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<dialog id="source-dialog" class="source-dialog">
|
|
53
|
+
<div class="source-dialog__header">
|
|
54
|
+
<div class="source-dialog__title" id="source-dialog-title"></div>
|
|
55
|
+
<div class="source-legend" id="source-legend"></div>
|
|
56
|
+
<div class="source-dialog__toggles">
|
|
57
|
+
<button class="toolbar-toggle" type="button" data-toggle="colorblind" aria-pressed="false" title="Use a colorblind-friendly palette and coverage symbols">🎨 Colorblind</button>
|
|
58
|
+
<button class="toolbar-toggle" type="button" data-toggle="dark"></button>
|
|
59
|
+
</div>
|
|
60
|
+
<button class="source-dialog__close" aria-label="Close" title="Close">×</button>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="source-dialog__body" id="source-dialog-body" tabindex="0"></div>
|
|
63
|
+
<div class="source-dialog__footer" id="source-dialog-footer"></div>
|
|
64
|
+
</dialog>
|
|
65
|
+
|
|
66
|
+
<!-- SIMPLECOV_COVERAGE_DATA -->
|
|
67
|
+
<script>"use strict";(()=>{var Qn=Object.create;var Lt=Object.defineProperty;var er=Object.getOwnPropertyDescriptor;var tr=Object.getOwnPropertyNames;var nr=Object.getPrototypeOf,rr=Object.prototype.hasOwnProperty;var or=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}};var ir=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of tr(t))!rr.call(e,o)&&o!==n&&Lt(e,o,{get:()=>t[o],enumerable:!(r=er(t,o))||r.enumerable});return e};var sr=(e,t,n)=>(n=e!=null?Qn(nr(e)):{},ir(t||!e||!e.__esModule?Lt(n,"default",{value:e,enumerable:!0}):n,e));var le=(e,t,n)=>new Promise((r,o)=>{var s=a=>{try{c(n.next(a))}catch(d){o(d)}},i=a=>{try{c(n.throw(a))}catch(d){o(d)}},c=a=>a.done?r(a.value):Promise.resolve(a.value).then(s,i);c((n=n.apply(e,t)).next())});var Jt=or((ii,Yt)=>{function Pt(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{let n=e[t],r=typeof n;(r==="object"||r==="function")&&!Object.isFrozen(n)&&Pt(n)}),e}var ke=class{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}};function Ft(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function V(e,...t){let n=Object.create(null);for(let r in e)n[r]=e[r];return t.forEach(function(r){for(let o in r)n[o]=r[o]}),n}var ur="</span>",Ot=e=>!!e.scope,dr=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){let n=e.split(".");return[`${t}${n.shift()}`,...n.map((r,o)=>`${r}${"_".repeat(o+1)}`)].join(" ")}return`${t}${e}`},Qe=class{constructor(t,n){this.buffer="",this.classPrefix=n.classPrefix,t.walk(this)}addText(t){this.buffer+=Ft(t)}openNode(t){if(!Ot(t))return;let n=dr(t.scope,{prefix:this.classPrefix});this.span(n)}closeNode(t){Ot(t)&&(this.buffer+=ur)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}},kt=(e={})=>{let t={children:[]};return Object.assign(t,e),t},et=class e{constructor(){this.rootNode=kt(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){let n=kt({scope:t});this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,n){return typeof n=="string"?t.addText(n):n.children&&(t.openNode(n),n.children.forEach(r=>this._walk(t,r)),t.closeNode(n)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(n=>typeof n=="string")?t.children=[t.children.join("")]:t.children.forEach(n=>{e._collapse(n)}))}},tt=class extends et{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,n){let r=t.root;n&&(r.scope=`language:${n}`),this.add(r)}toHTML(){return new Qe(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}};function Se(e){return e?typeof e=="string"?e:e.source:null}function qt(e){return re("(?=",e,")")}function fr(e){return re("(?:",e,")*")}function gr(e){return re("(?:",e,")?")}function re(...e){return e.map(n=>Se(n)).join("")}function pr(e){let t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function He(...e){return"("+(pr(e).capture?"":"?:")+e.map(r=>Se(r)).join("|")+")"}function Wt(e){return new RegExp(e.toString()+"|").exec("").length-1}function mr(e,t){let n=e&&e.exec(t);return n&&n.index===0}var hr=new RegExp(He(/\[(?:[^\\\]]|\\.)*\]/,/\(\?<(?![=!])[^>]+>/,/\(\?'[^']+'/,/\(\??/,/\\([1-9][0-9]*)/,/\\./));function rt(e,{joinWith:t}){let n=0;return e.map(r=>{n+=1;let o=n,s=Se(r),i="";for(;s.length>0;){let c=hr.exec(s);if(!c){i+=s;break}i+=s.substring(0,c.index),s=s.substring(c.index+c[0].length),c[0][0]==="\\"&&c[1]?i+="\\"+String(Number(c[1])+o):(i+=c[0],(c[0]==="("||/^\(\?[<']/.test(c[0]))&&n++)}return i}).map(r=>`(${r})`).join(t)}var br=/\b\B/,zt="[a-zA-Z]\\w*",ot="[a-zA-Z_]\\w*",Ut="\\b\\d+(\\.\\d+)?",jt="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Gt="\\b(0b[01]+)",vr="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",Er=(e={})=>{let t=/^#![ ]*\//;return e.binary&&(e.begin=re(t,/.*\b/,e.binary,/\b.*/)),V({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(n,r)=>{n.index!==0&&r.ignoreMatch()}},e)},Me={begin:"\\\\[\\s\\S]",relevance:0},_r={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[Me]},yr={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[Me]},Sr={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},De=function(e,t,n={}){let r=V({scope:"comment",begin:e,end:t,contains:[]},n);r.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});let o=He("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return r.contains.push({begin:re(/[ ]+/,"(",o,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),r},Mr=De("//","$"),xr=De("/\\*","\\*/"),wr=De("#","$"),Lr={scope:"number",begin:Ut,relevance:0},Tr={scope:"number",begin:jt,relevance:0},Cr={scope:"number",begin:Gt,relevance:0},Ar={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[Me,{begin:/\[/,end:/\]/,relevance:0,contains:[Me]}]},Nr={scope:"title",begin:zt,relevance:0},Rr={scope:"title",begin:ot,relevance:0},$r={begin:"\\.\\s*"+ot,relevance:0},Or=function(e){return Object.assign(e,{"on:begin":(t,n)=>{n.data._beginMatch=t[1]},"on:end":(t,n)=>{n.data._beginMatch!==t[1]&&n.ignoreMatch()}})},Oe=Object.freeze({__proto__:null,APOS_STRING_MODE:_r,BACKSLASH_ESCAPE:Me,BINARY_NUMBER_MODE:Cr,BINARY_NUMBER_RE:Gt,COMMENT:De,C_BLOCK_COMMENT_MODE:xr,C_LINE_COMMENT_MODE:Mr,C_NUMBER_MODE:Tr,C_NUMBER_RE:jt,END_SAME_AS_BEGIN:Or,HASH_COMMENT_MODE:wr,IDENT_RE:zt,MATCH_NOTHING_RE:br,METHOD_GUARD:$r,NUMBER_MODE:Lr,NUMBER_RE:Ut,PHRASAL_WORDS_MODE:Sr,QUOTE_STRING_MODE:yr,REGEXP_MODE:Ar,RE_STARTERS_RE:vr,SHEBANG:Er,TITLE_MODE:Nr,UNDERSCORE_IDENT_RE:ot,UNDERSCORE_TITLE_MODE:Rr});function kr(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function Ir(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function Hr(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=kr,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Dr(e,t){Array.isArray(e.illegal)&&(e.illegal=He(...e.illegal))}function Br(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function Pr(e,t){e.relevance===void 0&&(e.relevance=1)}var Fr=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");let n=Object.assign({},e);Object.keys(e).forEach(r=>{delete e[r]}),e.keywords=n.keywords,e.begin=re(n.beforeMatch,qt(n.begin)),e.starts={relevance:0,contains:[Object.assign(n,{endsParent:!0})]},e.relevance=0,delete n.beforeMatch},qr=["of","and","for","in","not","or","if","then","parent","list","value"],Wr="keyword";function Kt(e,t,n=Wr){let r=Object.create(null);return typeof e=="string"?o(n,e.split(" ")):Array.isArray(e)?o(n,e):Object.keys(e).forEach(function(s){Object.assign(r,Kt(e[s],t,s))}),r;function o(s,i){t&&(i=i.map(c=>c.toLowerCase())),i.forEach(function(c){let a=c.split("|");r[a[0]]=[s,zr(a[0],a[1])]})}}function zr(e,t){return t?Number(t):Ur(e)?0:1}function Ur(e){return qr.includes(e.toLowerCase())}var It={},ne=e=>{console.error(e)},Ht=(e,...t)=>{console.log(`WARN: ${e}`,...t)},de=(e,t)=>{It[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),It[`${e}/${t}`]=!0)},Ie=new Error;function Zt(e,t,{key:n}){let r=0,o=e[n],s={},i={};for(let c=1;c<=t.length;c++)i[c+r]=o[c],s[c+r]=!0,r+=Wt(t[c-1]);e[n]=i,e[n]._emit=s,e[n]._multi=!0}function jr(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw ne("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),Ie;if(typeof e.beginScope!="object"||e.beginScope===null)throw ne("beginScope must be object"),Ie;Zt(e,e.begin,{key:"beginScope"}),e.begin=rt(e.begin,{joinWith:""})}}function Gr(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw ne("skip, excludeEnd, returnEnd not compatible with endScope: {}"),Ie;if(typeof e.endScope!="object"||e.endScope===null)throw ne("endScope must be object"),Ie;Zt(e,e.end,{key:"endScope"}),e.end=rt(e.end,{joinWith:""})}}function Kr(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function Zr(e){Kr(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),jr(e),Gr(e)}function Xr(e){function t(i,c){return new RegExp(Se(i),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(c?"g":""))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(c,a){a.position=this.position++,this.matchIndexes[this.matchAt]=a,this.regexes.push([a,c]),this.matchAt+=Wt(c)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);let c=this.regexes.map(a=>a[1]);this.matcherRe=t(rt(c,{joinWith:"|"}),!0),this.lastIndex=0}exec(c){this.matcherRe.lastIndex=this.lastIndex;let a=this.matcherRe.exec(c);if(!a)return null;let d=a.findIndex((m,_)=>_>0&&m!==void 0),f=this.matchIndexes[d];return a.splice(0,d),Object.assign(a,f)}}class r{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(c){if(this.multiRegexes[c])return this.multiRegexes[c];let a=new n;return this.rules.slice(c).forEach(([d,f])=>a.addRule(d,f)),a.compile(),this.multiRegexes[c]=a,a}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(c,a){this.rules.push([c,a]),a.type==="begin"&&this.count++}exec(c){let a=this.getMatcher(this.regexIndex);a.lastIndex=this.lastIndex;let d=a.exec(c);if(this.resumingScanAtSamePosition()&&!(d&&d.index===this.lastIndex)){let f=this.getMatcher(0);f.lastIndex=this.lastIndex+1,d=f.exec(c)}return d&&(this.regexIndex+=d.position+1,this.regexIndex===this.count&&this.considerAll()),d}}function o(i){let c=new r;return i.contains.forEach(a=>c.addRule(a.begin,{rule:a,type:"begin"})),i.terminatorEnd&&c.addRule(i.terminatorEnd,{type:"end"}),i.illegal&&c.addRule(i.illegal,{type:"illegal"}),c}function s(i,c){let a=i;if(i.isCompiled)return a;[Ir,Br,Zr,Fr].forEach(f=>f(i,c)),e.compilerExtensions.forEach(f=>f(i,c)),i.__beforeBegin=null,[Hr,Dr,Pr].forEach(f=>f(i,c)),i.isCompiled=!0;let d=null;return typeof i.keywords=="object"&&i.keywords.$pattern&&(i.keywords=Object.assign({},i.keywords),d=i.keywords.$pattern,delete i.keywords.$pattern),d=d||/\w+/,i.keywords&&(i.keywords=Kt(i.keywords,e.case_insensitive)),a.keywordPatternRe=t(d,!0),c&&(i.begin||(i.begin=/\B|\b/),a.beginRe=t(a.begin),!i.end&&!i.endsWithParent&&(i.end=/\B|\b/),i.end&&(a.endRe=t(a.end)),a.terminatorEnd=Se(a.end)||"",i.endsWithParent&&c.terminatorEnd&&(a.terminatorEnd+=(i.end?"|":"")+c.terminatorEnd)),i.illegal&&(a.illegalRe=t(i.illegal)),i.contains||(i.contains=[]),i.contains=[].concat(...i.contains.map(function(f){return Vr(f==="self"?i:f)})),i.contains.forEach(function(f){s(f,a)}),i.starts&&s(i.starts,c),a.matcher=o(a),a}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=V(e.classNameAliases||{}),s(e)}function Xt(e){return e?e.endsWithParent||Xt(e.starts):!1}function Vr(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return V(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Xt(e)?V(e,{starts:e.starts?V(e.starts):null}):Object.isFrozen(e)?V(e):e}var Yr="11.12.0",nt=class extends Error{constructor(t,n){super(t),this.name="HTMLInjectionError",this.html=n}},Je=Ft,Dt=V,Bt=Symbol("nomatch"),Jr=7,Vt=function(e){let t=Object.create(null),n=Object.create(null),r=[],o=!0,s="Could not find the language '{}', did you forget to load/include a language module?",i={disableAutodetect:!0,name:"Plain text",contains:[]},c={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:tt};function a(l){return c.noHighlightRe.test(l)}function d(l){let g=l.className+" ";g+=l.parentNode?l.parentNode.className:"";let E=c.languageDetectRe.exec(g);if(E){let M=N(E[1]);return M||(Ht(s.replace("{}",E[1])),Ht("Falling back to no-highlight mode for this block.",l)),M?E[1]:"no-highlight"}return g.split(/\s+/).find(M=>a(M)||N(M))}function f(l,g,E){let M="",C="";typeof g=="object"?(M=l,E=g.ignoreIllegals,C=g.language):(de("10.7.0","highlight(lang, code, ...args) has been deprecated."),de("10.7.0",`Please use highlight(code, options) instead.
|
|
68
|
+
https://github.com/highlightjs/highlight.js/issues/2277`),C=l,M=g),E===void 0&&(E=!0);let P={code:M,language:C};ee("before:highlight",P);let X=P.result?P.result:m(P.language,P.code,E);return X.code=P.code,ee("after:highlight",X),X}function m(l,g,E,M){let C=Object.create(null);function P(u,p){return u.keywords[p]}function X(){if(!h.keywords){A.addText(x);return}let u=0;h.keywordPatternRe.lastIndex=0;let p=h.keywordPatternRe.exec(x),b="";for(;p;){b+=x.substring(u,p.index);let S=z.case_insensitive?p[0].toLowerCase():p[0],R=P(h,S);if(R){let[G,Yn]=R;if(A.addText(b),b="",C[S]=(C[S]||0)+1,C[S]<=Jr&&($e+=Yn),G.startsWith("_"))b+=p[0];else{let Jn=z.classNameAliases[G]||G;W(p[0],Jn)}}else b+=p[0];u=h.keywordPatternRe.lastIndex,p=h.keywordPatternRe.exec(x)}b+=x.substring(u),A.addText(b)}function Ne(){if(x==="")return;let u=null;if(typeof h.subLanguage=="string"){if(!t[h.subLanguage]){A.addText(x);return}u=m(h.subLanguage,x,!0,wt[h.subLanguage]),wt[h.subLanguage]=u._top}else u=L(x,h.subLanguage.length?h.subLanguage:null);h.relevance>0&&($e+=u.relevance),A.__addSublanguage(u._emitter,u.language)}function H(){h.subLanguage!=null?Ne():X(),x=""}function W(u,p){u!==""&&(A.startScope(p),A.addText(u),A.endScope())}function yt(u,p){let b=1,S=p.length-1;for(;b<=S;){if(!u._emit[b]){b++;continue}let R=z.classNameAliases[u[b]]||u[b],G=p[b];R?W(G,R):(x=G,X(),x=""),b++}}function St(u,p){return u.scope&&typeof u.scope=="string"&&A.openNode(z.classNameAliases[u.scope]||u.scope),u.beginScope&&(u.beginScope._wrap?(W(x,z.classNameAliases[u.beginScope._wrap]||u.beginScope._wrap),x=""):u.beginScope._multi&&(yt(u.beginScope,p),x="")),h=Object.create(u,{parent:{value:h}}),h}function Mt(u,p,b){let S=mr(u.endRe,b);if(S){if(u["on:end"]){let R=new ke(u);u["on:end"](p,R),R.isMatchIgnored&&(S=!1)}if(S){for(;u.endsParent&&u.parent;)u=u.parent;return u}}if(u.endsWithParent)return Mt(u.parent,p,b)}function Gn(u){return h.matcher.regexIndex===0?(x+=u[0],1):(Ve=!0,0)}function Kn(u){let p=u[0],b=u.rule,S=new ke(b),R=[b.__beforeBegin,b["on:begin"]];for(let G of R)if(G&&(G(u,S),S.isMatchIgnored))return Gn(p);return b.skip?x+=p:(b.excludeBegin&&(x+=p),H(),!b.returnBegin&&!b.excludeBegin&&(x=p)),St(b,u),b.returnBegin?0:p.length}function Zn(u){let p=u[0],b=g.substring(u.index),S=Mt(h,u,b);if(!S)return Bt;let R=h;h.endScope&&h.endScope._wrap?(H(),W(p,h.endScope._wrap)):h.endScope&&h.endScope._multi?(H(),yt(h.endScope,u)):R.skip?x+=p:(R.returnEnd||R.excludeEnd||(x+=p),H(),R.excludeEnd&&(x=p));do h.scope&&A.closeNode(),!h.skip&&!h.subLanguage&&($e+=h.relevance),h=h.parent;while(h!==S.parent);return S.starts&&St(S.starts,u),R.returnEnd?0:p.length}function Xn(){let u=[];for(let p=h;p!==z;p=p.parent)p.scope&&u.unshift(p.scope);u.forEach(p=>A.openNode(p))}let Re={};function xt(u,p){let b=p&&p[0];if(x+=u,b==null)return H(),0;if(Re.type==="begin"&&p.type==="end"&&Re.index===p.index&&b===""){if(x+=g.slice(p.index,p.index+1),!o){let S=new Error(`0 width match regex (${l})`);throw S.languageName=l,S.badRule=Re.rule,S}return 1}if(Re=p,p.type==="begin")return Kn(p);if(p.type==="illegal"&&!E){let S=new Error('Illegal lexeme "'+b+'" for mode "'+(h.scope||"<unnamed>")+'"');throw S.mode=h,S}else if(p.type==="end"){let S=Zn(p);if(S!==Bt)return S}if(p.type==="illegal"&&b==="")return p.index===g.length||(x+=`
|
|
69
|
+
`),1;if(Xe>1e5&&Xe>p.index*3)throw new Error("potential infinite loop, way more iterations than matches");return x+=b,b.length}let z=N(l);if(!z)throw ne(s.replace("{}",l)),new Error('Unknown language: "'+l+'"');let Vn=Xr(z),Ze="",h=M||Vn,wt={},A=new c.__emitter(c);Xn();let x="",$e=0,te=0,Xe=0,Ve=!1;try{if(z.__emitTokens)z.__emitTokens(g,A);else{for(h.matcher.considerAll();;){Xe++,Ve?Ve=!1:h.matcher.considerAll(),h.matcher.lastIndex=te;let u=h.matcher.exec(g);if(!u)break;let p=g.substring(te,u.index),b=xt(p,u);te=u.index+b}xt(g.substring(te))}return A.finalize(),Ze=A.toHTML(),{language:l,value:Ze,relevance:$e,illegal:!1,_emitter:A,_top:h}}catch(u){if(u.message&&u.message.includes("Illegal"))return{language:l,value:Je(g),illegal:!0,relevance:0,_illegalBy:{message:u.message,index:te,context:g.slice(te-100,te+100),mode:u.mode,resultSoFar:Ze},_emitter:A};if(o)return{language:l,value:Je(g),illegal:!1,relevance:0,errorRaised:u,_emitter:A,_top:h};throw u}}function _(l){let g={value:Je(l),illegal:!1,relevance:0,_top:i,_emitter:new c.__emitter(c)};return g._emitter.addText(l),g}function L(l,g){g=g||c.languages||Object.keys(t);let E=_(l),M=g.filter(N).filter(Q).map(H=>m(H,l,!1));M.unshift(E);let C=M.sort((H,W)=>{if(H.relevance!==W.relevance)return W.relevance-H.relevance;if(H.language&&W.language){if(N(H.language).supersetOf===W.language)return 1;if(N(W.language).supersetOf===H.language)return-1}return 0}),[P,X]=C,Ne=P;return Ne.secondBest=X,Ne}function w(l,g,E){let M=g&&n[g]||E;l.classList.add("hljs"),l.classList.add(`language-${M}`)}function v(l){let g=null,E=d(l);if(a(E))return;if(ee("before:highlightElement",{el:l,language:E}),l.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",l);return}if(l.children.length>0&&(c.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(l)),c.throwUnescapedHTML))throw new nt("One of your code blocks includes unescaped HTML.",l.innerHTML);g=l;let M=g.textContent,C=E?f(M,{language:E,ignoreIllegals:!0}):L(M);l.innerHTML=C.value,l.dataset.highlighted="yes",w(l,E,C.language),l.result={language:C.language,re:C.relevance,relevance:C.relevance},C.secondBest&&(l.secondBest={language:C.secondBest.language,relevance:C.secondBest.relevance}),ee("after:highlightElement",{el:l,result:C,text:M})}function k(l){c=Dt(c,l)}let J=()=>{j(),de("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function Ce(){j(),de("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let Z=!1;function j(){function l(){j()}if(document.readyState==="loading"){Z||window.addEventListener("DOMContentLoaded",l,!1),Z=!0;return}document.querySelectorAll(c.cssSelector).forEach(v)}function Ee(l,g){let E=null;try{E=g(e)}catch(M){if(ne("Language definition for '{}' could not be registered.".replace("{}",l)),o)ne(M);else throw M;E=i}E.name||(E.name=l),t[l]=E,E.rawDefinition=g.bind(null,e),E.aliases&&ce(E.aliases,{languageName:l})}function q(l){delete t[l];for(let g of Object.keys(n))n[g]===l&&delete n[g]}function _e(){return Object.keys(t)}function N(l){return l=(l||"").toLowerCase(),t[l]||t[n[l]]}function ce(l,{languageName:g}){typeof l=="string"&&(l=[l]),l.forEach(E=>{n[E.toLowerCase()]=g})}function Q(l){let g=N(l);return g&&!g.disableAutodetect}function Ae(l){l["before:highlightBlock"]&&!l["before:highlightElement"]&&(l["before:highlightElement"]=g=>{l["before:highlightBlock"](Object.assign({block:g.el},g))}),l["after:highlightBlock"]&&!l["after:highlightElement"]&&(l["after:highlightElement"]=g=>{l["after:highlightBlock"](Object.assign({block:g.el},g))})}function I(l){Ae(l),r.push(l)}function ae(l){let g=r.indexOf(l);g!==-1&&r.splice(g,1)}function ee(l,g){let E=l;r.forEach(function(M){M[E]&&M[E](g)})}function ye(l){return de("10.7.0","highlightBlock will be removed entirely in v12.0"),de("10.7.0","Please use highlightElement now."),v(l)}Object.assign(e,{highlight:f,highlightAuto:L,highlightAll:j,highlightElement:v,highlightBlock:ye,configure:k,initHighlighting:J,initHighlightingOnLoad:Ce,registerLanguage:Ee,unregisterLanguage:q,listLanguages:_e,getLanguage:N,registerAliases:ce,autoDetection:Q,inherit:Dt,addPlugin:I,removePlugin:ae}),e.debugMode=function(){o=!1},e.safeMode=function(){o=!0},e.versionString=Yr,e.regex={concat:re,lookahead:qt,either:He,optional:gr,anyNumberOfTimes:fr};for(let l in Oe)typeof Oe[l]=="object"&&Pt(Oe[l]);return Object.assign(e,Oe),e},fe=Vt({});fe.newInstance=()=>Vt({});Yt.exports=fe;fe.HighlightJS=fe;fe.default=fe});function $(e,t){return(t||document).querySelector(e)}function y(e,t){return Array.from((t||document).querySelectorAll(e))}function U(e,t,n,r){typeof n=="function"?e.addEventListener(t,n):e.addEventListener(t,function(o){let s=o.target.closest(n);s&&e.contains(s)&&r&&r.call(s,o)})}var cr={"&":"&","<":"<",">":">",'"':""","'":"'"};function T(e){return e.replace(/[&<>"']/g,t=>cr[t])}function Tt(e){return le(this,null,function*(){let t=new TextEncoder().encode(e),n=yield crypto.subtle.digest("SHA-1",t);return Array.from(new Uint8Array(n,0,4),r=>r.toString(16).padStart(2,"0")).join("")})}var ar=90,lr=75;function F(e){return e>=ar?"green":e>=lr?"yellow":"red"}function O(e){return e.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}function D(e){return(Math.floor(e*100)/100).toFixed(2)}function Ct(e){return"g-"+e.replace(/[^a-zA-Z0-9-]/gu,t=>`_${t.codePointAt(0).toString(16)}_`)}var At=[[31536e3,"year"],[2592e3,"month"],[86400,"day"],[3600,"hour"],[60,"minute"],[1,"second"]];function Nt(e){let t=Math.floor((Date.now()-e.getTime())/1e3);for(let[n,r]of At){let o=Math.floor(t/n);if(o>=1)return o===1?`about 1 ${r} ago`:`${o} ${r}s ago`}return"just now"}function Rt(e){let t=(Date.now()-e.getTime())/1e3;for(let[n]of At){let r=Math.floor(t/n);if(r>=1){let o=(r+1)*n;return Math.max((o-t)*1e3+500,1e3)}}return 1e3}var Ye=new Map;function ue(e){let t=Ye.get(e);if(t===void 0)throw new Error(`File ID was not precomputed for ${e}`);return t}function $t(e){return le(this,null,function*(){Ye.clear();let t=[...new Set(e)],n=yield Promise.all(t.map(Tt)),r=new Map;t.forEach((o,s)=>{let i=n[s],c=r.get(i)||[];c.push(o),r.set(i,c)});for(let[o,s]of r)s.sort().forEach((i,c)=>{Ye.set(i,c===0?o:`${o}-${c}`)})})}var Qt=sr(Jt(),1);var ge=Qt.default;function en(e){let t=e.regex,n="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",r=t.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),o=t.concat(r,/(::\w+)*/),i={"variable.constant":["__FILE__","__LINE__","__ENCODING__"],"variable.language":["self","super"],keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield",...["include","extend","prepend","public","private","protected","raise","throw"]],built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"],literal:["true","false","nil"]},c={className:"doctag",begin:"@[A-Za-z]+"},a={begin:"#<",end:">"},d=[e.COMMENT("#","$",{contains:[c]}),e.COMMENT("^=begin","^=end",{contains:[c],relevance:10}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],f={className:"subst",begin:/#\{/,end:/\}/,keywords:i},m={className:"string",contains:[e.BACKSLASH_ESCAPE,f],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?</,end:/>/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:t.concat(/<<[-~]?'?/,t.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,f]})]}]},_="[1-9](_?[0-9])*|0",L="[0-9](_?[0-9])*",w={className:"number",relevance:0,variants:[{begin:`\\b(${_})(\\.(${L}))?([eE][+-]?(${L})|r)?i?\\b`},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},v={variants:[{match:/\(\)/},{className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0,keywords:i}]},q=[m,{variants:[{match:[/class\s+/,o,/\s+<\s+/,o]},{match:[/\b(class|module)\s+/,o]}],scope:{2:"title.class",4:"title.class.inherited"},keywords:i},{match:[/(include|extend)\s+/,o],scope:{2:"title.class"},keywords:i},{relevance:0,match:[o,/\.new[. (]/],scope:{1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},{relevance:0,match:r,scope:"title.class"},{match:[/def/,/\s+/,n],scope:{1:"keyword",3:"title.function"},contains:[v]},{begin:"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[m,{begin:n}],relevance:0},w,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|(?!=)/,end:/\|/,excludeBegin:!0,excludeEnd:!0,relevance:0,keywords:i},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,f],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(a,d),relevance:0}].concat(a,d);f.contains=q,v.contains=q;let Q=[{begin:/^\s*=>/,starts:{end:"$",contains:q}},{className:"meta.prompt",begin:"^("+"[>?]>"+"|"+"[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]"+"|"+"(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>"+")(?=[ ])",starts:{end:"$",keywords:i,contains:q}}];return d.unshift(a),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:i,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(Q).concat(d).concat(q)}}function tn(e){return{name:"HAML",case_insensitive:!0,contains:[{className:"meta",begin:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",relevance:10},e.COMMENT("^\\s*(!=#|=#|-#|/).*$",null,{relevance:0}),{begin:"^\\s*(-|=|!=)(?!#)",end:/$/,subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0},{className:"tag",begin:"^\\s*%",contains:[{className:"selector-tag",begin:"\\w+"},{className:"selector-id",begin:"#[\\w-]+"},{className:"selector-class",begin:"\\.[\\w-]+"},{begin:/\{\s*/,end:/\s*\}/,contains:[{begin:":\\w+\\s*=>",end:",\\s+",returnBegin:!0,endsWithParent:!0,contains:[{className:"attr",begin:":\\w+"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:"\\w+",relevance:0}]}]},{begin:"\\(\\s*",end:"\\s*\\)",excludeEnd:!0,contains:[{begin:"\\w+\\s*=",end:"\\s+",returnBegin:!0,endsWithParent:!0,contains:[{className:"attr",begin:"\\w+",relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:"\\w+",relevance:0}]}]}]},{begin:"^\\s*[=~]\\s*"},{begin:/#\{/,end:/\}/,subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0}]}}var Qr={endsWithParent:!0,relevance:0,contains:[{className:"attr",begin:/[A-Za-z_:][-A-Za-z0-9_:.]*/,relevance:0},{className:"string",relevance:0,variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]}]};function it(e){return{name:"ERB",contains:[e.COMMENT("<%#","%>"),{begin:/<%[%=-]?/,end:/[%-]?%>/,subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0},{className:"tag",begin:/<\/?(?=[A-Za-z])/,end:/\/?>/,contains:[{className:"name",begin:/[A-Za-z][^\s/>]*/,relevance:0,starts:Qr}]}]}}function st(e){return{name:"Slim",contains:[e.COMMENT(/^\s*\/!?/,/$/),{begin:/^\s*(?:-|={1,2})[<>']*/,end:/$/,subLanguage:"ruby",excludeBegin:!0,relevance:0},{className:"name",begin:/^\s*[A-Za-z][A-Za-z0-9_-]*/,relevance:0,starts:{end:/\s/,relevance:0,contains:[{className:"selector-class",begin:/\.[A-Za-z][A-Za-z0-9_-]*/,relevance:0},{className:"selector-id",begin:/#[A-Za-z][A-Za-z0-9_-]*/,relevance:0}]}},{className:"selector-class",begin:/^\s*\.[A-Za-z][A-Za-z0-9_-]*/,relevance:0},{className:"selector-id",begin:/^\s*#[A-Za-z][A-Za-z0-9_-]*/,relevance:0}]}}function eo(e){if(e==="oneshot_line")return"line";if(e==="line"||e==="branch"||e==="method")return e}function nn(e){let t=eo(e.primary_coverage);return t==="branch"&&e.branch_coverage||t==="method"&&e.method_coverage?t:e.line_coverage?"line":e.branch_coverage?"branch":"method"}function to(e,t){return t==="line"?e.lines:t==="branch"?e.branches:e.methods}function Be(e,t){return to(e,t)||e.lines||e.branches||e.methods}function Pe(e,t){let n=Array.from({length:t},()=>[]);for(let[r,o]of Object.entries(e||{})){let s=Number(r);Array.from(o).reverse().forEach((i,c)=>{let a=parseInt(i,16);for(let d of[0,1,2,3]){if(!(a&1<<d))continue;let f=c*4+d;f<t&&n[f].push(s)}})}return{perLine:n}}function rn(e,t){if(!t)return 0;let n=[];for(let o of Object.values(e||{}))Array.from(o).reverse().forEach((s,i)=>{n[i]=(n[i]||0)|parseInt(s,16)});let r=0;return t.forEach((o,s)=>{typeof o!="number"||o<=0||(n[s>>2]||0)&1<<(s&3)||r++}),r}function on(e,t,n){let r=e.perLine[n-1];return r?r.map(o=>t[o]).sort():[]}function at(e,t){let n=F(e);return t?`<div class="bar-sizer"><div class="coverage-bar"><div class="coverage-bar__fill coverage-bar__fill--${n} coverage-bar__fill--split" style="width: ${D(e-t)}%"></div><div class="coverage-bar__fill coverage-bar__fill--outside" style="width: ${D(t)}%"></div></div></div>`:`<div class="bar-sizer"><div class="coverage-bar"><div class="coverage-bar__fill coverage-bar__fill--${n}" style="width: ${D(e)}%"></div></div></div>`}function oe(e,t,n,r,o,s){let i=F(e),c=D(e),a=s===void 0||n===0?void 0:s*100/n,d=`<div class="coverage-cell">${at(e,a)}<span class="coverage-pct">${c}%</span></div>`;if(o)return`<td class="cell--coverage strong t-totals__${r}-pct ${i}">${d}</td><td class="cell--numerator strong t-totals__${r}-num">${O(t)}/</td><td class="cell--denominator strong t-totals__${r}-den">${O(n)}</td>`;let f=a===void 0?"":` data-order-2="${D(e-a)}"`,m=` data-order="${D(e)}"${f}`;return`<td class="cell--coverage cell--${r}-pct ${i}"${m}>${d}</td><td class="cell--numerator" data-order="${t}">${O(t)}/</td><td class="cell--denominator" data-order="${n}">${O(n)}</td>`}function Fe(e,t,n,r){return`<th class="cell--coverage" data-sort-key="${t}-percent">
|
|
70
|
+
<div class="th-with-filter">
|
|
71
|
+
<span class="th-label">${e}</span>
|
|
72
|
+
<div class="col-filter__coverage">
|
|
73
|
+
<select class="col-filter__op" data-type="${t}"><option value="lt"><</option><option value="lte" selected>≤</option><option value="eq">=</option><option value="gte">≥</option><option value="gt">></option></select>
|
|
74
|
+
<span class="col-filter__pct-wrap"><input type="number" class="col-filter__value" min="0" max="100" data-type="${t}" value="100" step="any"></span>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</th>
|
|
78
|
+
<th class="cell--numerator" data-sort-key="${t}-covered">${n}</th>
|
|
79
|
+
<th class="cell--denominator" data-sort-key="${t}-total">${r}</th>`}function sn(e,t,n){return n!==void 0?n:t>0?e*100/t:100}function ct(e){let{type:t,label:n,covered:r,total:o,enabled:s,toggle:i}=e;if(!s)return`<div class="t-${t}-summary">
|
|
80
|
+
${n}: <span class="coverage-disabled">disabled</span>
|
|
81
|
+
</div>`;let c=o-r,a=sn(r,o,e.percent),d=F(a),f=e.suffix||"covered",m=e.missedClass||"red",_=`<div class="t-${t}-summary">
|
|
82
|
+
${n}: <span class="${d}"><b>${D(a)}%</b></span><span class="coverage-cell__fraction"> ${r}/${o} ${f}</span>`;if(c>0){let L=i?`<a href="#" class="t-missed-method-toggle"><b>${c}</b> missed</a>`:`<span class="${m}"><b>${c}</b> missed</span>`;_+=`<span class="coverage-cell__fraction">,</span>
|
|
83
|
+
${L}`}return _+=`
|
|
84
|
+
</div>`,_}function no(e,t,n,r,o){let s=sn(e,t,o),i=t-e,c=`<div class="t-line-summary">
|
|
85
|
+
Line coverage: <span class="${F(s)}"><b>${D(s)}%</b></span><span class="coverage-cell__fraction"> ${n}/${t} relevant lines covered by tests</span>`;return r>0&&(c+=`<span class="coverage-cell__fraction">,</span>
|
|
86
|
+
<span class="coverage-cell__fraction outside-tests-text">${r}/${t} relevant lines covered outside tests</span>`),i>0&&(c+=`<span class="coverage-cell__fraction">,</span>
|
|
87
|
+
<span class="red"><b>${i}</b> missed</span>`),c+`
|
|
88
|
+
</div>`}function cn(e){return'<div class="summary-stats">'+(e.coveredByTests===void 0||!e.lineCoverage?ct({type:"line",label:"Line coverage",covered:e.coveredLines,total:e.totalLines,enabled:e.lineCoverage,percent:e.linePercent,suffix:"relevant lines covered"}):no(e.coveredLines,e.totalLines,e.coveredByTests,e.coveredOutsideTests||0,e.linePercent))+ct({type:"branch",label:"Branch coverage",covered:e.coveredBranches,total:e.totalBranches,enabled:e.branchCoverage,percent:e.branchPercent,missedClass:"missed-branch-text"})+ct({type:"method",label:"Method coverage",covered:e.coveredMethods,total:e.totalMethods,enabled:e.methodCoverage,percent:e.methodPercent,missedClass:"missed-method-text-color",toggle:e.showMethodToggle})+"</div>"}function ro(e,t){let{containerId:n,title:r,filenames:o,stats:s,lineCoverage:i,branchCoverage:c,methodCoverage:a,primaryCoverage:d}=e,f=i?s.lines:void 0,m=c?s.branches:void 0,_=a?s.methods:void 0,L=Be(s,d),w=L?L.percent:100,v=[`<div class="file_list_container" id="${n}" data-total-files="${o.length}">`,`<span class="group_name hide">${T(r)}</span>`,`<span class="covered_percent hide"><span class="${F(w)}">${D(w)}%</span></span>`,'<div class="file_list--responsive"><table class="file_list"><thead><tr>','<th class="cell--left" data-sort-key="file"><div class="th-with-filter"><span class="th-label">File Name</span><input type="search" class="col-filter col-filter--name" placeholder="Filter paths\u2026"></div></th>'];f&&v.push(Fe("Line Coverage","line","Covered","Lines")),c&&v.push(Fe("Branch Coverage","branch","Covered","Branches")),a&&v.push(Fe("Method Coverage","method","Covered","Methods")),e.production&&v.push('<th class="cell--production" data-sort-key="production"><span class="th-label">Last Run in Production</span></th>'),v.push("</tr>");let k=o.length===1?"file":"files";return v.push(`<tr class="totals-row"><td class="strong t-file-count">${O(o.length)} ${k}</td>`),f&&v.push(oe(f.percent,f.covered,f.total,"line",!0,t)),m&&v.push(oe(m.percent,m.covered,m.total,"branch",!0)),_&&v.push(oe(_.percent,_.covered,_.total,"method",!0)),e.production&&v.push('<td class="cell--production"></td>'),v.push("</tr></thead><tbody>"),v.join("")}function oo(e,t){let n=t.files[e];if(!n)return'<td class="cell--production t-file__production t-file__production--never" data-order="-1">never</td>';let r=String(n.last_seen),o=Date.parse(r);return Number.isNaN(o)?'<td class="cell--production t-file__production" data-order="0">ran</td>':`<td class="cell--production t-file__production" data-order="${o}"><abbr class="timeago" title="${T(r)}">${T(r.slice(0,10))}</abbr></td>`}function io(e){let{filename:t,coverage:n,lineCoverage:r,branchCoverage:o,methodCoverage:s,outsideLines:i,production:c}=e,a=ue(t),d=[];r&&(d.push(`data-covered-lines="${n.covered_lines||0}"`,`data-relevant-lines="${n.total_lines||0}"`),i!==void 0&&d.push(`data-covered-outside-lines="${i}"`)),o&&d.push(`data-covered-branches="${n.covered_branches||0}"`,`data-total-branches="${n.total_branches||0}"`),s&&d.push(`data-covered-methods="${n.covered_methods||0}"`,`data-total-methods="${n.total_methods||0}"`);let f=[`<tr class="t-file" ${d.join(" ")}>`,`<td class="strong t-file__name"><a href="#${a}" class="src_link" title="${T(t)}">${T(t)}</a></td>`];if(r){let m=n.lines_covered_percent===void 0?100:n.lines_covered_percent;f.push(oe(m,n.covered_lines||0,n.total_lines||0,"line",!1,i))}if(o){let m=n.branches_covered_percent===void 0?100:n.branches_covered_percent;f.push(oe(m,n.covered_branches||0,n.total_branches||0,"branch",!1))}if(s){let m=n.methods_covered_percent===void 0?100:n.methods_covered_percent;f.push(oe(m,n.covered_methods||0,n.total_methods||0,"method",!1))}return c&&f.push(oo(t,c)),f.push("</tr>"),f.join("")}function lt(e){let{filenames:t,allCoverage:n,lineCoverage:r,branchCoverage:o,methodCoverage:s,contextsEnabled:i,production:c}=e,a=i&&r?new Map(t.flatMap(m=>{let _=n[m];return _?[[m,rn(_.contexts,_.lines)]]:[]})):void 0,d=a?[...a.values()].reduce((m,_)=>m+_,0):void 0,f=[ro(e,d)];for(let m of t){let _=n[m];_&&f.push(io({filename:m,coverage:_,lineCoverage:r,branchCoverage:o,methodCoverage:s,outsideLines:a==null?void 0:a.get(m),production:c}))}return f.push("</tbody></table></div></div>"),f.join("")}function so(e){let{lineIndex:t,lineCov:n,branchesReport:r,missedMethodLines:o,branchCoverage:s,methodCoverage:i}=e,c=t+1;if(n==="ignored")return"skipped";if(s){let a=r[c];if(a&&a.some(([,d])=>d===0))return"missed-branch"}return i&&o.has(c)?"missed-method":n==null?"never":n===0?"missed":"covered"}function co(e){let t={};if(!e)return t;for(let{coverage:n,report_line:r,type:o}of e){if(n==="ignored")continue;(t[r]||(t[r]=[])).push([o,n])}return t}function ao(e){let t=new Set;if(!e)return t;for(let n of e)if(n.coverage===0&&n.start_line&&n.end_line)for(let r=n.start_line;r<=n.end_line;r++)t.add(r);return t}var lo={erb:"erb",haml:"haml",slim:"slim"};function uo(e){return lo[e.split(".").pop().toLowerCase()]||"ruby"}function fo(e){let{index:t,source:n,language:r,lineCov:o,status:s,branchCoverage:i,lineBranches:c,testCount:a,productionRan:d}=e,f=t+1,m=typeof o=="number"?o:null,_=m===null?"":` data-hits="${m}"`,w=[`<li class="${s}${d===void 0?"":d?" production-ran":" production-never"}"${_} data-linenumber="${f}">`];if(m?w.push(`<span class="hits" data-content="${m}"></span>`):o==="ignored"&&w.push('<span class="hits" data-content="skipped"></span>'),d&&o===0&&w.push('<span class="hits hits--production" data-content="runs in production"></span>'),a!==void 0){let v=a===0?" hits--tests-none":"",k=a===1?"1 test":`${a} tests`;w.push(`<button type="button" class="hits hits--tests${v}" data-content="${k}" data-tests-line="${f}" title="List the tests covering this line" aria-expanded="false"></button>`)}if(i&&c)for(let[v,k]of c){let J=T(v);w.push(`<span class="hits" data-content="${J}: ${k}" title="${J} branch hit ${k} times"></span>`)}return w.push(`<code class="${r}">${T(n)}</code></li>`),w.join("")}function go(e,t,n){let r=`<div class="t-production-summary">
|
|
89
|
+
Production: <b>${e}</b>/${t} relevant lines ran`,o=n&&n.last_seen;return o&&(r+=`<span class="coverage-cell__fraction">, last run <span title="${T(o)}">${T(o.slice(0,10))}</span></span>`),r+`
|
|
90
|
+
</div>`}function an(e,t,n,r,o,s,i){var ce,Q,Ae;let c=ue(e),a=n&&t.covered_lines||0,d=n&&t.total_lines||0,f=r&&t.covered_branches||0,m=r&&t.total_branches||0,_=o&&t.covered_methods||0,L=o&&t.total_methods||0,w=(Q=(ce=t.methods)==null?void 0:ce.filter(I=>I.coverage===0))!=null?Q:[],v=o&&w.length>0,k=co(t.branches),J=ao(t.methods),Ce=uo(e),Z=s?Pe(t.contexts,t.source.length):null,j=0,Ee=i===void 0?null:new Set(i==null?void 0:i.lines),q=0,_e=[];for(let I=0;I<t.source.length;I++){let ae=(Ae=t.lines)==null?void 0:Ae[I],ee=typeof ae=="number"?ae:null,ye=so({lineIndex:I,lineCov:ae,branchesReport:k,missedMethodLines:J,branchCoverage:r,methodCoverage:o}),l;Z&&ee&&(l=Z.perLine[I].length,l===0&&(j++,ye==="covered"&&(ye="outside-tests")));let g;Ee&&ee!==null&&(g=Ee.has(I+1),g&&q++),_e.push(fo({index:I,source:t.source[I],language:Ce,lineCov:ae,status:ye,branchCoverage:r,lineBranches:r?k[I+1]:void 0,testCount:l,productionRan:g}))}let N=[`<div class="source_table" id="${c}">`,'<div class="header">',`<h2>${T(e)}</h2>`,cn({coveredLines:a,totalLines:d,coveredBranches:f,totalBranches:m,coveredMethods:_,totalMethods:L,lineCoverage:n,branchCoverage:r,methodCoverage:o,showMethodToggle:v,coveredByTests:Z?a-j:void 0,coveredOutsideTests:Z?j:void 0,linePercent:n?t.lines_covered_percent:void 0,branchPercent:r?t.branches_covered_percent:void 0,methodPercent:o?t.methods_covered_percent:void 0})];return i!==void 0&&N.push('<div class="summary-stats summary-stats--production">',go(q,d,i),"</div>"),v&&N.push('<div class="t-missed-method-list" style="display: none"><ul>',w.map(I=>`<li><tt>${T(I.name)}</tt></li>`).join(""),"</ul></div>"),N.push("</div>","<pre><ol>"),N.push(..._e),N.push("</ol></pre></div>"),N.join("")}ge.registerLanguage("ruby",en);ge.registerLanguage("erb",it);ge.registerLanguage("haml",tn);ge.registerLanguage("slim",st);var ln;function xe(){let e=getComputedStyle(document.documentElement).getPropertyValue(`--${ln}`).trim(),t=document.createElement("canvas");t.width=t.height=16;let n=t.getContext("2d");if(!e||!n)return;n.fillStyle=e,n.fillRect(0,0,16,16);let r=document.querySelector('link[rel="icon"]');r||(r=document.createElement("link"),r.rel="icon",r.type="image/png",document.head.appendChild(r)),r.href=t.toDataURL("image/png")}var un;function dn(){return un}var po=3;function mo(e){let t=e.command_names&&e.command_names.length?e.command_names:[e.command_name];return t.length<=po?T(t.join(", ")):`<details class="footer-runs"><summary>${T(t[0])} and ${t.length-1} other runs</summary><span class="footer-runs__list">${T(t.join(", "))}</span></details>`}function fn(e){let t=e.meta,n=t.line_coverage,r=t.branch_coverage,o=t.method_coverage,s=nn(t);document.title=`Code coverage for ${t.project_name}`;let i=Object.keys(e.coverage),c=Be(e.total,s),a=c&&c.total>0?c.percent:100;ln=F(a),xe(),r&&document.body.setAttribute("data-branch-coverage","true");let d=document.getElementById("content"),f=[lt({containerId:"g-total",title:"All Files",filenames:i,stats:e.total,allCoverage:e.coverage,lineCoverage:n,branchCoverage:r,methodCoverage:o,primaryCoverage:s,contextsEnabled:!!e.contexts,production:e.production})];for(let v of Object.keys(e.groups)){let k=e.groups[v];f.push(lt({containerId:Ct(`group-${v}`),title:v,filenames:k.files||[],stats:k,allCoverage:e.coverage,lineCoverage:n,branchCoverage:r,methodCoverage:o,primaryCoverage:s,contextsEnabled:!!e.contexts,production:e.production}))}d.innerHTML=f.join("");let m={};for(let v of i)m[ue(v)]=v;un={idToFilename:m,coverage:e.coverage,lineCoverage:n,branchCoverage:r,methodCoverage:o,contexts:e.contexts||null,production:e.production||null};let _=new Date(t.timestamp),L=`Generated <abbr class="timeago" title="${_.toISOString()}">${_.toISOString()}</abbr> by <a href="https://github.com/simplecov-ruby/simplecov">simplecov</a> v${T(t.simplecov_version)} using ${mo(t)}`;document.getElementById("footer").innerHTML=L,document.getElementById("source-dialog-footer").innerHTML=L;let w=[];if(n){let v=e.contexts?[K("covered","Covered by tests"),K("outside-tests","Covered outside tests")]:[K("covered","Covered")];w.push(qe("line",[...v,K("skipped","Skipped"),K("missed","Missed line")]))}e.production&&n&&w.push(qe("production",[K("production-never","Never ran in production"),K("production-ran","Untested, runs in production")])),r&&w.push(qe("branch",[K("missed-branch","Missed branch")])),o&&w.push(qe("method",[K("missed-method","Missed method")])),document.getElementById("source-legend").innerHTML=w.join("")}function qe(e,t){return`<div class="source-legend__row source-legend__row--${e}">${t.join("")}</div>`}function K(e,t){return`<span class="source-legend__item"><span class="source-legend__swatch source-legend__swatch--${e}"></span>${t}</span>`}function gn(e){let t=document.getElementById(e);if(t)return t;let{idToFilename:n,coverage:r,lineCoverage:o,branchCoverage:s,methodCoverage:i,contexts:c,production:a}=dn(),d=n[e];if(!d)return null;let f=an(d,r[d],o,s,i,c||void 0,a?a.files[d]||null:void 0),m=document.querySelector(".source_files"),_=document.createElement("div");_.innerHTML=f;let L=_.firstElementChild;return m.appendChild(L),y("pre code",L).forEach(w=>ge.highlightElement(w)),L}function pn(e,t){let{contexts:n,idToFilename:r,coverage:o}=dn();if(!n)return null;let s=r[e];if(!s)return null;let i=o[s],c=Pe(i.contexts,i.source.length);return on(c,n,t)}var ut=1e3,ho="t-window-hidden",mn=new WeakSet;function bo(e,t){let n=e.querySelector("tr.t-show-all");if(!n){n=document.createElement("tr"),n.className="t-show-all";let r=document.createElement("td");r.colSpan=t,n.appendChild(r),n.addEventListener("click",o=>{o.preventDefault(),mn.add(e),pe(e.closest("table"))})}return n}function pe(e){let t=e.querySelector("tbody");if(!t)return;let n=t.querySelectorAll("tr.t-file"),r=mn.has(t),o=0;if(n.forEach(i=>{let c=i.style.display==="none";c||(o+=1),i.classList.toggle(ho,!r&&!c&&o>ut)}),r||o<=ut){let i=t.querySelector("tr.t-show-all");i&&(i.style.display="none");return}let s=bo(t,n[0].children.length);s.style.removeProperty("display"),s.firstElementChild.innerHTML=`Showing the first ${O(ut)} of ${O(o)} files. <a href="#" class="t-show-all__link">Show all</a>`,t.appendChild(s)}function We(e){try{return localStorage.getItem(e)}catch(t){return null}}function we(e,t){try{localStorage.setItem(e,t)}catch(n){}}var ft=new WeakMap,En="simplecov-sort";function vo(){var e;try{return(e=JSON.parse(String(We(En))))!=null?e:{}}catch(t){return{}}}function Eo(){let e=vo();return e.direction!=="asc"&&e.direction!=="desc"?null:{column:e.column,direction:e.direction}}function _o(e){we(En,JSON.stringify(e))}function yo(e,t){let n=0,r=e.children;for(let o=0;o<r.length;o++)if(r[o].style.display!=="none"){if(n===t)return o;n+=1}return-1}function hn(e){if(!e)return"";let t=e.getAttribute("data-order");if(t!==null)return Number.parseFloat(t);let n=e.textContent.trim(),r=Number.parseFloat(n);return Number.isNaN(r)?n:r}function So(e){return Number.parseFloat(String(e==null?void 0:e.getAttribute("data-order-2")))}var Mo=new Intl.Collator(void 0,{sensitivity:"accent"});function bn(e,t){return typeof e=="number"&&typeof t=="number"?e-t:Mo.compare(String(e),String(t))}function _n(e,t,n){let r=e.map(s=>({row:s,value:hn(s.children[t]),tiebreak:So(s.children[t]),filename:hn(s.children[0])})),o=(s,i)=>bn(s.value,i.value)||s.tiebreak-i.tiebreak||bn(s.filename,i.filename);return r.sort(n==="asc"?o:(s,i)=>o(i,s)),r.map(({row:s})=>s)}function dt(e,t,n){ft.set(e,{colIndex:t,direction:n});let r=0;y("thead tr:first-child th",e).forEach(o=>{let s=Number.parseInt(o.getAttribute("colspan")||"1",10);o.classList.remove("sorting_asc","sorting_desc","sorting");let i=t>=r&&t<r+s;o.classList.add(i?n==="asc"?"sorting_asc":"sorting_desc":"sorting"),r+=s})}function yn(e,t){let n=document.createDocumentFragment();t.forEach(r=>n.appendChild(r)),e.appendChild(n)}function vn(e,t,n){let r=ft.get(e),o=e.querySelector("tbody"),s=Array.from(o.querySelectorAll("tr.t-file"));if(s.length===0){dt(e,t,n);return}r&&r.colIndex===t?s.reverse():s=_n(s,yo(s[0],t),n),yn(o,s),pe(e),dt(e,t,n)}var xo=500,me=null;function wo(){me||(me=document.createElement("div"),me.id="sort-overlay",me.innerHTML='<span id="sort-overlay-label">Sorting\u2026</span>',document.body.appendChild(me));let e=me;return e.style.transition="none",e.style.opacity="1",e.style.display="flex",e}function Lo(e){e.style.transition="opacity 0.15s",e.style.opacity="0",setTimeout(()=>{e.style.display="none"},150)}function To(e,t){let n=Sn(e,t),r=ft.get(e),o=r&&r.colIndex===n&&r.direction==="asc"?"desc":"asc",s=t.getAttribute("data-sort-key");if(s&&_o({column:s,direction:o}),e.querySelectorAll("tbody tr.t-file").length<xo){vn(e,n,o);return}let c=wo();requestAnimationFrame(()=>requestAnimationFrame(()=>{vn(e,n,o),Lo(c)}))}function Sn(e,t){let n=0;for(let r of y("thead tr:first-child th",e)){let o=Number.parseInt(r.getAttribute("colspan")||"1",10);if(r===t)return n+o-1;n+=o}return n}function Co(e,t){let n=Array.from(e.children),r=n.findIndex(s=>s.classList.contains(`cell--${t}-pct`)),o=r===-1?n.findIndex(s=>s.hasAttribute("data-order")):r;return o===-1?null:o}function Ao(e,t,n){let r=e.querySelector("tbody");if(!r)return;let o=Array.from(r.querySelectorAll("tr.t-file"));if(o.length===0)return;let s=n&&y("thead tr:first-child th[data-sort-key]",e).find(a=>a.getAttribute("data-sort-key")===n.column),i=s?Sn(e,s):Co(o[0],t);if(i===null)return;let c=s?n.direction:"asc";yn(r,_n(o,i,c)),dt(e,i,c)}function Mn(e){let t=Eo();y("table.file_list").forEach(n=>{y("thead tr:first-child th",n).forEach(r=>{r.classList.add("sorting"),r.style.cursor="pointer",r.addEventListener("click",()=>To(n,r))}),Ao(n,e,t),pe(n)})}var Le=null;function ze(){Le=null}function xn(){if(Le)return Le;let e=y(".file_list_container").filter(t=>t.style.display!=="none");return e.length?(Le=y("tbody tr.t-file",e[0]).filter(t=>t.style.display!=="none"),Le):[]}var No=240,Ro=160;function wn(e,t){e.style.setProperty("--bar-sizer-width",t+"px")}var $o=8;function Oo(e,t){let n=Ro,r=No;for(;r-n>$o;){let o=Math.ceil((n+r)/2);wn(e,o),e.offsetWidth,e.scrollWidth<=t?n=o:r=o-1}return n}function pt(){y(".file_list_container").forEach(e=>{if(e.style.display==="none"||e.offsetWidth===0)return;let t=$("table.file_list",e);if(!t||!$(".bar-sizer",t))return;let n=t.closest(".file_list--responsive");n&&(n.style.visibility="hidden",wn(t,Oo(t,n.clientWidth)),n.style.visibility="")})}var gt=0;function he(){gt||(gt=requestAnimationFrame(()=>{gt=0,pt()}))}var Ue={line:{covered:"coveredLines",total:"relevantLines"},branch:{covered:"coveredBranches",total:"totalBranches"},method:{covered:"coveredMethods",total:"totalMethods"}};function Ln(e){let t=y("tbody tr.t-file",e).filter(s=>s.style.display!=="none");function n(s){return t.reduce((i,c)=>i+(Number(c.dataset[s])||0),0)}let r=$(".t-file-count",e),o=Number(e.getAttribute("data-total-files"));if(r){let s=t.length===1?" file":" files";r.textContent=t.length===o?O(o)+s:O(t.length)+"/"+O(o)+s}for(let s of Object.keys(Ue)){let i=Ue[s],c=s==="line"?n("coveredOutsideLines"):0;ko(e,`.t-totals__${s}`,n(i.covered),n(i.total),c)}}function ko(e,t,n,r,o){let s=$(t+"-pct",e),i=$(t+"-num",e),c=$(t+"-den",e);if(r===0){s&&(s.innerHTML="",s.classList.remove("green","yellow","red")),i&&(i.textContent=""),c&&(c.textContent="");return}let a=n*100/r;s&&(s.innerHTML=`<div class="coverage-cell">${at(a,o*100/r)}<span class="coverage-pct">${D(a)}%</span></div>`,s.classList.remove("green","yellow","red"),s.classList.add(F(a))),i&&(i.textContent=O(n)+"/"),c&&(c.textContent=O(r))}var Io={gt:(e,t)=>e>t,gte:(e,t)=>e>=t,eq:(e,t)=>e===t,lte:(e,t)=>e<=t,lt:(e,t)=>e<t};function Ho(e,t,n){let r=Io[e];return r?r(t,n):!0}function Do(e){let t=[];for(let n of y(".col-filter__value",e)){let r=n,o=Number.parseFloat(r.value);if(Number.isNaN(o))continue;let s=r.dataset.type,i=s&&Ue[s],c=$(`.col-filter__op[data-type="${s}"]`,e);i&&c&&t.push({attrs:i,op:c.value,threshold:o})}return t}var Tn=new WeakMap;function Bo(e){let t=Tn.get(e);return t===void 0&&(t=e.children[0].textContent.toLowerCase(),Tn.set(e,t)),t}function Po(e){let t=$("table.file_list",e);if(!t)return;let n=$(".col-filter--name",e),r=n?n.value.trim().toLowerCase():"",o=Do(e);y("tbody tr.t-file",t).forEach(s=>{let i=s,c=(!r||Bo(s).includes(r))&&o.every(a=>{let d=Number(i.dataset[a.attrs.covered])||0,f=Number(i.dataset[a.attrs.total])||0,m=f>0?d*100/f:100;return Ho(a.op,m,a.threshold)});i.style.display=c?"":"none"}),pe(t),ze(),Ln(e),he()}function An(e){let t=Number.parseFloat(e.value),n=e.closest(".col-filter__coverage"),r=n?n.querySelector(".col-filter__op"):null;if(!r)return;let o=r.querySelector('option[value="gt"]'),s=r.querySelector('option[value="lt"]');if(o&&(o.disabled=t>=100),s&&(s.disabled=t<=0),r.selectedOptions[0]&&r.selectedOptions[0].disabled){let i=r.querySelector("option:not(:disabled)");i&&(r.value=i.value)}}function Cn(){this.classList.contains("col-filter__value")&&An(this),Po(this.closest(".file_list_container"))}function Nn(){y(".col-filter__value").forEach(e=>An(e)),y(".col-filter--name, .col-filter__op, .col-filter__value, .col-filter__coverage").forEach(e=>{e.addEventListener("click",t=>t.stopPropagation())}),U(document,"input",".col-filter--name, .col-filter__op, .col-filter__value",Cn),U(document,"change",".col-filter__op, .col-filter__value",Cn)}var B=null;function Rn(){return B!==null}function be(e){B&&B.classList.remove("keyboard-focus"),B=e,B&&(B.classList.add("keyboard-focus"),B.scrollIntoView({block:"nearest"}))}function mt(e){let t=xn();if(!t.length)return;if(!B||t.indexOf(B)===-1){be(e===1?t[0]:t[t.length-1]);return}let n=t.indexOf(B)+e;n>=0&&n<t.length&&be(t[n])}function $n(){if(!B)return;let e=B.querySelector("a.src_link");e&&(window.location.hash=e.getAttribute("href"))}var Y,ie,ht,Te=null,je=null;function bt(){return Y.open}function vt(){return ie}function kn(){if(!Te)return;je&&(Te.prepend(je),je=null);let e=document.querySelector(".source_files");e&&e.appendChild(Te),Te=null}function Fo(e,t){kn();let n=gn(e);if(!n)return;let r=n.querySelector(".header");r&&(je=r,ht.innerHTML=r.innerHTML,r.remove()),Te=n,ie.appendChild(n),Y.open||Y.showModal(),document.documentElement.style.overflow="hidden",ie.focus();let o=ie.querySelector(`li[data-linenumber="${t}"]`);o&&(ie.scrollTop=o.offsetTop)}function On(e){if(be(null),ze(),kn(),Y.close(),ie.innerHTML="",ht.innerHTML="",document.documentElement.style.overflow="",e){let n=document.querySelector(".group_tabs a."+e);n&&(y(".group_tabs li").forEach(r=>r.classList.remove("active")),n.parentElement.classList.add("active"),y(".file_list_container").forEach(r=>r.style.display="none"),document.getElementById(e).style.display="")}let t=document.getElementById("wrapper");t&&!t.classList.contains("hide")&&he()}function Ke(){let e=window.location.hash.substring(1);if(!e){let t=document.querySelector(".group_tabs a");t&&On(t.getAttribute("href").replace("#",""));return}if(e.charAt(0)==="_")On(e.substring(1));else{let t=e.split("-L");if(!document.querySelector(".group_tabs li.active")){let n=document.querySelector(".group_tabs li");n&&n.classList.add("active")}Fo(t[0],t[1])}}function Ge(){let e=document.querySelector(".group_tabs li.active a");e&&(window.location.hash=e.getAttribute("href").replace("#","#_"))}function In(){Y=document.getElementById("source-dialog"),ie=document.getElementById("source-dialog-body"),ht=document.getElementById("source-dialog-title"),Y.querySelector(".source-dialog__close").addEventListener("click",Ge),Y.addEventListener("click",e=>{e.target===Y&&Ge()})}var se=null,ve=null;function qo(e){return e.length===0?'<div class="tests-peek__title">No recorded test covers this line</div><div class="tests-peek__note">It ran outside any test: at load time, in suite setup, or from a helper.</div>':`<div class="tests-peek__title">${e.length===1?"Covered by 1 test":`Covered by ${e.length} tests`}</div><ul class="tests-peek__list">${e.map(n=>`<li><code>${T(n)}</code></li>`).join("")}</ul>`}function Et(){se&&se.remove(),ve&&ve.setAttribute("aria-expanded","false"),se=null,ve=null}function Hn(e,t){let n=e.closest("li"),r=e.closest(".source_table");if(!n||!r)return;let o=ve===e;if(Et(),o)return;let s=Number(e.getAttribute("data-tests-line")),i=t(r.id,s);if(!i)return;let c=document.createElement("li");c.className="tests-peek",c.innerHTML=qo(i),n.after(c),e.setAttribute("aria-expanded","true"),se=c,ve=e}function Dn(){document.addEventListener("keydown",e=>{!se||e.key!=="Escape"||(e.preventDefault(),e.stopPropagation(),Et())},!0),document.addEventListener("click",e=>{if(!se)return;let t=e.target;se.contains(t)||ve.contains(t)||Et()},!0)}function Wo(){return y(".source-dialog .source_table li.missed, .source-dialog .source_table li.missed-branch, .source-dialog .source_table li.missed-method")}function _t(e){let t=Wo();if(!t.length)return;let n=vt(),r=n.scrollTop+n.clientHeight/2,o=e===1?t.find(s=>s.offsetTop>r)||t[0]:t.findLast(s=>s.offsetTop<r-10)||t[t.length-1];n.scrollTop=o.offsetTop-n.clientHeight/3}function Bn(){U(document,"click",".t-missed-method-toggle",function(e){e.preventDefault();let t=this.closest(".header")||this.closest(".source-dialog__title")||this.closest(".source-dialog__header"),n=t?t.querySelector(".t-missed-method-list"):null;n&&(n.style.display=n.style.display==="none"?"":"none")}),U(document,"click","table.file_list tbody tr",function(){let e=this.querySelector("a.src_link");e&&(window.location.hash=e.getAttribute("href"))}),U(document,"click","button.hits--tests",function(e){e.preventDefault(),Hn(this,pn)}),U(document,"click",".source-dialog .source_table li[data-linenumber]",function(e){if(e.target.closest(".hits--tests, .tests-peek"))return;e.preventDefault(),vt().scrollTop=this.offsetTop;let t=this.dataset.linenumber,n=window.location.hash.substring(1).replace(/-L.*/,"");window.location.replace(window.location.href.replace(/#.*/,"#"+n+"-L"+t))}),window.addEventListener("hashchange",Ke),Dn()}var Pn="simplecov-dark-mode",zo="simplecov-colorblind-mode";function Uo(){return We(Pn)}function Fn(e){return Array.from(document.querySelectorAll(`[data-toggle="${e}"]`))}function qn(){let e=Fn("colorblind"),t=document.documentElement,n=()=>{let r=String(t.classList.contains("colorblind-mode"));e.forEach(o=>o.setAttribute("aria-pressed",r))};n(),e.forEach(r=>r.addEventListener("click",()=>{let o=t.classList.toggle("colorblind-mode");we(zo,o?"on":"off"),n(),xe()}))}function Wn(){let e=Fn("dark"),t=document.documentElement;function n(){return t.classList.contains("dark-mode")||!t.classList.contains("light-mode")&&window.matchMedia("(prefers-color-scheme: dark)").matches}function r(){let o=n();e.forEach(s=>{s.textContent=o?"\u2600\uFE0F Light":"\u{1F319} Dark",s.setAttribute("aria-label",o?"Switch to light mode":"Switch to dark mode")})}r(),e.forEach(o=>o.addEventListener("click",()=>{let s=n();t.classList.toggle("light-mode",s),t.classList.toggle("dark-mode",!s),we(Pn,s?"light":"dark"),r(),xe()})),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{Uo()||r(),xe()})}function jo(){let e=y(".file_list_container").find(t=>t.style.display!=="none");e&&$(".col-filter--name",e).focus()}function Go(e,t){bt()?(e.preventDefault(),Ge()):t?e.target.blur():be(null)}function Ko(e){e.key==="n"&&!e.shiftKey&&(e.preventDefault(),_t(1)),(e.key==="N"||e.key==="n"&&e.shiftKey||e.key==="p")&&(e.preventDefault(),_t(-1))}function Zo(e){e.key==="j"&&(e.preventDefault(),mt(1)),e.key==="k"&&(e.preventDefault(),mt(-1)),e.key==="Enter"&&Rn()&&(e.preventDefault(),$n())}function zn(e){let t=e.target instanceof Element&&e.target.matches("input, select, textarea");e.key==="/"&&!t?(e.preventDefault(),jo()):e.key==="Escape"?Go(e,t):t||(bt()?Ko(e):Zo(e))}function Un(){let e=$(".group_tabs");if(!e)return;let t=()=>{e.classList.toggle("is-scrolled",e.scrollLeft>0)};e.addEventListener("scroll",t),window.addEventListener("resize",t),t()}function jn(){let e=1/0;y("abbr.timeago").forEach(t=>{let n=t.getAttribute("title");if(!n)return;let r=new Date(n);Number.isNaN(r.getTime())||(t.textContent=Nt(r),e=Math.min(e,Rt(r)))}),e<1/0&&setTimeout(jn,e)}function Xo(){y(".file_list_container").forEach(e=>e.style.display="none"),y(".file_list_container").forEach(e=>{let t=document.createElement("li");t.setAttribute("role","tab");let n=document.createElement("a");n.href="#"+e.id,n.className=e.id,n.innerHTML=`${e.querySelector(".group_name").innerHTML} (${e.querySelector(".covered_percent").innerHTML})`,t.appendChild(n),document.querySelector(".group_tabs").appendChild(t)}),U(document.querySelector(".group_tabs"),"click","a",function(e){e.preventDefault(),window.location.hash=this.getAttribute("href").replace("#","#_")})}function Vo(e){e.style.transition="opacity 0.3s",e.style.opacity="0",setTimeout(()=>{e.style.display="none"},300),document.getElementById("wrapper").classList.remove("hide"),pt()}function Yo(){return le(this,null,function*(){let e=window.SIMPLECOV_DATA,t=document.getElementById("loading");t.style.display="",yield $t(Object.keys(e.coverage)),fn(e),jn(),Wn(),qn(),Mn(e.meta.primary_coverage),Nn(),document.addEventListener("keydown",zn),In(),Bn(),Xo(),Un(),window.addEventListener("resize",he),Ke(),Vo(t)})}document.addEventListener("DOMContentLoaded",Yo);})();
|
|
91
|
+
</script>
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
|
|
5
|
+
module SimpleCov
|
|
6
|
+
module Formatter
|
|
7
|
+
class HTMLFormatter
|
|
8
|
+
module ViewerDataValidator
|
|
9
|
+
META_STRINGS = %w[simplecov_version command_name project_name timestamp].freeze
|
|
10
|
+
COVERAGE_FLAGS = {
|
|
11
|
+
"line_coverage" => "lines",
|
|
12
|
+
"branch_coverage" => "branches",
|
|
13
|
+
"method_coverage" => "methods"
|
|
14
|
+
}.freeze
|
|
15
|
+
STAT_FIELDS = %w[covered missed total percent strength].freeze
|
|
16
|
+
private_constant :META_STRINGS, :COVERAGE_FLAGS, :STAT_FIELDS
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def call(data)
|
|
20
|
+
%w[meta total coverage groups].each { |key| validate_section!(data, key) }
|
|
21
|
+
meta = data.fetch("meta")
|
|
22
|
+
validate_meta!(meta)
|
|
23
|
+
validate_statistics!(data.fetch("total"), meta, "total")
|
|
24
|
+
data.fetch("coverage").each { |filename, file| validate_file!(filename, file) }
|
|
25
|
+
data.fetch("groups").each { |name, group| validate_group!(name, group, meta) }
|
|
26
|
+
validate_contexts!(data)
|
|
27
|
+
validate_production!(data)
|
|
28
|
+
data
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def validate_section!(data, key)
|
|
34
|
+
return if data[key].instance_of?(Hash)
|
|
35
|
+
|
|
36
|
+
raise CoverageJSON::Error, "#{key.inspect} must be an object"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def validate_file!(filename, file)
|
|
40
|
+
unless file.instance_of?(Hash)
|
|
41
|
+
raise CoverageJSON::Error, "coverage entry #{filename.inspect} must be an object"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
source = file["source"]
|
|
45
|
+
return if source.instance_of?(Array) && source.all?(String)
|
|
46
|
+
|
|
47
|
+
raise CoverageJSON::Error,
|
|
48
|
+
"coverage entry #{filename.inspect} must include an array of source strings; " \
|
|
49
|
+
"regenerate with source_in_json true"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def validate_contexts!(data)
|
|
53
|
+
contexts = data["contexts"]
|
|
54
|
+
valid = contexts.nil? || (contexts.instance_of?(Array) && contexts.all?(String))
|
|
55
|
+
raise CoverageJSON::Error, '"contexts" must be an array of strings' unless valid
|
|
56
|
+
|
|
57
|
+
count = Array(contexts).size
|
|
58
|
+
data.fetch("coverage").each { |filename, file| validate_context_table!(filename, file["contexts"], count) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def validate_context_table!(filename, table, count)
|
|
62
|
+
return if table.nil? || (table.instance_of?(Hash) && table.all? do |key, value|
|
|
63
|
+
context_entry?(key, value, count)
|
|
64
|
+
end)
|
|
65
|
+
|
|
66
|
+
raise CoverageJSON::Error,
|
|
67
|
+
"coverage entry #{filename.inspect} contexts must map recorded context indices to hex bitmaps"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def context_entry?(key, value, count)
|
|
71
|
+
key.instance_of?(String) && key.match?(/\A\d+\z/) && Integer(key) < count &&
|
|
72
|
+
value.instance_of?(String) && value.match?(/\A\h+\z/)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def validate_production!(data)
|
|
76
|
+
production = data["production"]
|
|
77
|
+
return if production.nil?
|
|
78
|
+
|
|
79
|
+
raise CoverageJSON::Error, '"production" must be an object' unless production.instance_of?(Hash)
|
|
80
|
+
|
|
81
|
+
files = validate_type!(production, "files", Hash, "production")
|
|
82
|
+
files.each { |filename, entry| validate_production_file!(filename, entry) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def validate_production_file!(filename, entry)
|
|
86
|
+
unless production_lines?(entry)
|
|
87
|
+
raise CoverageJSON::Error,
|
|
88
|
+
"production entry #{filename.inspect} must list sorted line numbers"
|
|
89
|
+
end
|
|
90
|
+
last_seen = entry["last_seen"]
|
|
91
|
+
return if last_seen.nil? || last_seen.instance_of?(String)
|
|
92
|
+
|
|
93
|
+
raise CoverageJSON::Error, "production entry #{filename.inspect} last_seen must be a string"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def production_lines?(entry)
|
|
97
|
+
lines = entry["lines"] if entry.instance_of?(Hash)
|
|
98
|
+
lines.instance_of?(Array) && lines.all? { |line| line.instance_of?(Integer) && line.positive? }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def validate_meta!(meta)
|
|
102
|
+
META_STRINGS.each { |key| validate_type!(meta, key, String, "meta") }
|
|
103
|
+
validate_command_names!(meta)
|
|
104
|
+
Time.iso8601(meta.fetch("timestamp"))
|
|
105
|
+
COVERAGE_FLAGS.each_key { |key| validate_boolean!(meta, key) }
|
|
106
|
+
rescue ArgumentError
|
|
107
|
+
raise CoverageJSON::Error, "meta.timestamp must be an ISO 8601 date-time"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def validate_command_names!(meta)
|
|
111
|
+
names = meta["command_names"]
|
|
112
|
+
return if names.nil? || (names.instance_of?(Array) && names.all?(String))
|
|
113
|
+
|
|
114
|
+
raise CoverageJSON::Error, "meta.command_names must be an array of strings"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def validate_statistics!(statistics, meta, location)
|
|
118
|
+
COVERAGE_FLAGS.each do |flag, criterion|
|
|
119
|
+
next unless meta.fetch(flag)
|
|
120
|
+
|
|
121
|
+
values = validate_type!(statistics, criterion, Hash, location)
|
|
122
|
+
STAT_FIELDS.each { |field| validate_type!(values, field, Numeric, "#{location}.#{criterion}") }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def validate_group!(name, group, meta)
|
|
127
|
+
raise CoverageJSON::Error, "group #{name.inspect} must be an object" unless group.instance_of?(Hash)
|
|
128
|
+
|
|
129
|
+
files = group["files"]
|
|
130
|
+
unless files.instance_of?(Array) && files.all?(String)
|
|
131
|
+
raise CoverageJSON::Error, "group #{name.inspect}.files must be an array of strings"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
validate_statistics!(group, meta, "group #{name.inspect}")
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def validate_type!(object, key, type, location)
|
|
138
|
+
value = object[key]
|
|
139
|
+
return value if value.is_a?(type)
|
|
140
|
+
|
|
141
|
+
raise CoverageJSON::Error, "#{location}.#{key} must be a #{type.name.downcase}"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def validate_boolean!(meta, key)
|
|
145
|
+
return if [true, false].include?(meta[key])
|
|
146
|
+
|
|
147
|
+
raise CoverageJSON::Error, "meta.#{key} must be a boolean"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
require_relative "base"
|
|
6
|
+
require_relative "../atomic_file"
|
|
7
|
+
require_relative "../coverage_json"
|
|
8
|
+
require_relative "json_formatter"
|
|
9
|
+
|
|
10
|
+
module SimpleCov
|
|
11
|
+
module Formatter
|
|
12
|
+
# Generates a single self-contained HTML coverage report. The compiled
|
|
13
|
+
# template already carries the viewer app's JS and CSS inline, so the report
|
|
14
|
+
# can be mailed, uploaded as one CI artifact, or opened from anywhere
|
|
15
|
+
# without sibling files. A coverage.json is written alongside from the same
|
|
16
|
+
# in-memory hash.
|
|
17
|
+
class HTMLFormatter < Base
|
|
18
|
+
DATA_MARKER = "<!-- SIMPLECOV_COVERAGE_DATA -->"
|
|
19
|
+
|
|
20
|
+
LEGACY_REPORT_FILES = %w[
|
|
21
|
+
coverage_data.js application.js application.css
|
|
22
|
+
favicon_green.png favicon_red.png favicon_yellow.png
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
def format(result)
|
|
26
|
+
viewer_hash = JSONFormatter.build_hash(result, include_source: true)
|
|
27
|
+
json_hash = SimpleCov.source_in_json ? viewer_hash : source_less_hash(viewer_hash)
|
|
28
|
+
write_report_files(json_hash, viewer_hash, result)
|
|
29
|
+
emit_status(result)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Generates HTML from a pre-existing coverage.json without a live Result or
|
|
33
|
+
# even a running test suite. The round-trip through parse/generate compacts
|
|
34
|
+
# the input and rejects invalid JSON here rather than at view time.
|
|
35
|
+
def format_from_json(json_path, output_dir)
|
|
36
|
+
data = ViewerDataValidator.call(CoverageJSON.load(json_path))
|
|
37
|
+
json = JSON.generate(data)
|
|
38
|
+
AtomicFile.write(File.join(output_dir, "index.html"), render_report(json), binary: true)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def entry_point_filename
|
|
44
|
+
"index.html"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The inlined report data feeds the client-side viewer, which renders source
|
|
48
|
+
# from the embedded array, so it always needs `source` regardless of
|
|
49
|
+
# `SimpleCov.source_in_json`. The side-file `coverage.json` honors the
|
|
50
|
+
# setting, and stays pretty-printed for human readers while the embedded
|
|
51
|
+
# copy is serialized compactly.
|
|
52
|
+
def source_less_hash(hash)
|
|
53
|
+
coverage = hash.fetch(:coverage).transform_values { |file| file.except(:source) }
|
|
54
|
+
hash.merge(coverage: coverage)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def write_report_files(json_hash, viewer_hash, result)
|
|
58
|
+
CoverageJSONWriter.write(output_path, json_hash, result)
|
|
59
|
+
AtomicFile.write(File.join(output_path, "index.html"), render_report(JSON.generate(viewer_hash)), binary: true)
|
|
60
|
+
FileUtils.rm_f(LEGACY_REPORT_FILES.map { |name| File.join(output_path, name) })
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# `<` is escaped as \u003c, valid JSON since `<` can only occur inside
|
|
64
|
+
# strings, so embedded source text containing "</script>" cannot terminate
|
|
65
|
+
# the surrounding element. Block forms keep gsub/sub from interpreting
|
|
66
|
+
# backslashes in the JSON as replacement-string back-references.
|
|
67
|
+
#
|
|
68
|
+
# The template is read as UTF-8 explicitly, not the locale's
|
|
69
|
+
# `Encoding.default_external`: substituting a UTF-8 payload into a template
|
|
70
|
+
# tagged US-ASCII raises Encoding::CompatibilityError.
|
|
71
|
+
def render_report(json)
|
|
72
|
+
template = File.read(File.join(public_dir, "index.html"), encoding: Encoding::UTF_8)
|
|
73
|
+
unless template.include?(DATA_MARKER)
|
|
74
|
+
raise "SimpleCov's HTML template is missing its #{DATA_MARKER.inspect} marker"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
data_script = "<script>window.SIMPLECOV_DATA = #{json.gsub("<") { '\u003c' }};</script>"
|
|
78
|
+
template.sub(DATA_MARKER) { data_script }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def public_dir
|
|
82
|
+
"#{__dir__}/html_formatter/public/"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
require_relative "html_formatter/viewer_data_validator"
|