coverband 5.1.1 → 5.2.1.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87c963a2d00531451c8759262e428dc9a6f46d136639672e4149550facf01da6
4
- data.tar.gz: 26b11c7ad8c5fd3f1cd93167b5c9ee1d0118cd984f462702d593680d55995e99
3
+ metadata.gz: 52f9e6cca57c574c40b8b730d8ad826c08f1b858ac63155d87776e2f62db4da2
4
+ data.tar.gz: 5e152167cc24ed7672753772a6d59b2b1a8919d80d01d0a589b5419d46af7a80
5
5
  SHA512:
6
- metadata.gz: 51e48c5cb61f1dafc5b7f25c57d6a25ecea36579956267f99d1c9b4343a579d469c4d46e6ea32244ebbf91af08ed0dc427653a6aa0b2f1a245995751c2ec46c4
7
- data.tar.gz: 25aad7fbe0940710f58f20a64cd2b6364151861ae239c88322253dd567ddb9e2986e8268ec7d3117c8f8de8218f18aa42d04c1dcb9613bdcacff0f157d8237c6
6
+ metadata.gz: 4ff7894bca759987524adaad9e8964660e26f863eb2495a56ddbc1169875a1587392066dd9d3529239d5486c68cfc20a6333bc966de7b702b2198e9e1f7deae0
7
+ data.tar.gz: a3268efa84fbf7318dbe6fefa9af6ddacff4b36e6c5244560ff30957548787db8d8bbf124019549cd28beb16d23ec5a40073ee1922d746daee925dcf8bffc80c
@@ -0,0 +1,16 @@
1
+ name: Create diagram
2
+ on:
3
+ workflow_dispatch: {}
4
+ push:
5
+ branches:
6
+ - main
7
+ jobs:
8
+ get_data:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout code
12
+ uses: actions/checkout@master
13
+ - name: Update diagram
14
+ uses: githubocto/repo-visualizer@main
15
+ with:
16
+ excluded_paths: "ignore,.github"
@@ -3,9 +3,9 @@ name: CI
3
3
  on:
4
4
  # Triggers the workflow on push or pull request events but only for the master branch
5
5
  push:
6
- branches: [master]
6
+ branches: [main]
7
7
  pull_request:
8
- branches: [master]
8
+ branches: [main]
9
9
  jobs:
10
10
  test:
11
11
  strategy:
@@ -17,12 +17,12 @@ jobs:
17
17
  # remove until I sort out CI issues for truffle
18
18
  # truffleruby,
19
19
  # truffleruby-head,
20
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0, jruby, jruby-head]
20
+ ruby: [2.3, 2.4, 2.5, 2.6, 2.7, "3.0", jruby, jruby-head]
21
21
  redis-version: [4, 5, 6]
22
22
  runs-on: ${{ matrix.os }}-latest
23
23
  steps:
24
24
  - uses: actions/checkout@v2
25
- - uses: supercharge/redis-github-action@1.1.0
25
+ - uses: supercharge/redis-github-action@1.2.0
26
26
  - uses: ruby/setup-ruby@v1
27
27
  with:
28
28
  ruby-version: ${{ matrix.ruby }}
data/README.md CHANGED
@@ -284,7 +284,7 @@ Between the release of 4.0 and 4.1 our data format changed. This resets all your
284
284
 
285
285
  ### Adding Rake Tasks outside of Rails
286
286
 
287
- Rails apps should automaticallly include the tasks via the Railtie.
287
+ Rails apps should automatically include the tasks via the Railtie.
288
288
 
289
289
  For non Rails apps, either add the below to your `Rakefile` or to a file included in your `Rakefile` such as `lib/tasks/coverband.rake` if you want to break it up that way.
290
290
 
@@ -427,6 +427,12 @@ What is the coverage data in Redis?
427
427
 
428
428
  `Coverband.configuration.store.coverage`
429
429
 
430
+ ### Diagram
431
+
432
+ A diagram of the code.
433
+
434
+ ![Visualization of this repo](./diagram.svg)
435
+
430
436
  ## Logo
431
437
 
432
438
  The Coverband logo was created by [Dave Woodall](http://davewoodall.com). Thanks Dave!
data/changes.md CHANGED
@@ -1,3 +1,22 @@
1
+ ### Coverband 5.2.1
2
+
3
+ - fix for `can't add a new key into hash during iteration` https://github.com/danmayer/coverband/issues/436
4
+
5
+ ### Coverband 5.2.0
6
+
7
+ - (Fumiaki MATSUSHIMA) Fix CI setting for Ruby 3.0
8
+ - (Fumiaki MATSUSHIMA) Avoid calling coverage with the same type twice on get_coverage_report
9
+ - (kei-s) Fix filling zero for not loaded files
10
+ - (wonda-tea-coffee) cleanup readme / fix typos
11
+ - support deferred eager loading data
12
+ - (Donatas Stundys) Fix disabling views tracking
13
+ - (Simon) Improve View tracker to track render collection too
14
+
15
+ ### Coverband 5.1.1
16
+
17
+ - Fix early report error
18
+ - Improved view tracker perf Hosam Aly
19
+
1
20
  ### Coverband 5.1.0
2
21
 
3
22
  - add support for dead method detection rake task
@@ -93,7 +112,7 @@
93
112
  - larger changes
94
113
  - reduce memory usage
95
114
  - fix issue where reports didn't include files with 0 activity
96
- - updated runtime relavent lines and runtime percentages
115
+ - updated runtime relevant lines and runtime percentages
97
116
  - add Oneshot coverage support for Ruby 2.6.0 thanks @zwalker
98
117
  - I would consider this our test oneshot release, please report any issues
99
118
  - improved control over memory vs functionality
@@ -125,7 +144,7 @@
125
144
 
126
145
  ### Coverband 4.2.0
127
146
 
128
- **NOTE:** This release introduces load time and runtime Coverage. To get the full benifit of this feature you need to reset you coverage data (`rake coverband:clear` or clear via the web UI). Until you clear the combined result is still correct, but your runtime data will be mixed with previous data. This is due to an additive change in how we store coverage. We didn't reset by default as the coverage history for some folks may be more important than runtime breakdown.
147
+ **NOTE:** This release introduces load time and runtime Coverage. To get the full benefit of this feature you need to reset you coverage data (`rake coverband:clear` or clear via the web UI). Until you clear the combined result is still correct, but your runtime data will be mixed with previous data. This is due to an additive change in how we store coverage. We didn't reset by default as the coverage history for some folks may be more important than runtime breakdown.
129
148
 
130
149
  - loadtime vs runtime coverage
131
150
  - This fixes the coverage last seen date to exclude just load time data
data/coverband.gemspec CHANGED
@@ -23,6 +23,14 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.required_ruby_version = '>= 2.3'
25
25
 
26
+ spec.metadata = {
27
+ "homepage_uri" => "https://github.com/danmayer/coverband",
28
+ "bug_tracker_uri" => "https://github.com/danmayer/coverband/issues",
29
+ "documentation_uri" => "https://github.com/danmayer/coverband",
30
+ "changelog_uri" => "https://github.com/danmayer/coverband/blob/main/changes.md",
31
+ "source_code_uri" => "https://github.com/danmayer/coverband",
32
+ }
33
+
26
34
  spec.add_development_dependency "benchmark-ips"
27
35
  spec.add_development_dependency "capybara"
28
36
  spec.add_development_dependency "m"
data/diagram.svg ADDED
@@ -0,0 +1 @@
1
+ <svg width="1000" height="1000" style="background:white;font-family:sans-serif;overflow:visible" xmlns="http://www.w3.org/2000/svg"><defs><filter id="glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="4" result="coloredBlur"></feGaussianBlur><feMerge><feMergeNode in="coloredBlur"></feMergeNode><feMergeNode in="SourceGraphic"></feMergeNode></feMerge></filter></defs><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(320.00612713573406, 687.2198622231437)"><circle r="41.02836011911288" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(661.4430539975464, 565.1971458820385)"><circle r="305.55664287251915" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#89e051;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(288.90225953017944, 583.342381404345)"><circle r="51.431002761270165" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(198.2674333465526, 337.65351269934234)"><circle r="194.44335712748088" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(208.8559603568583, 675.5911309430885)"><circle r="54.71139231128383" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(467.62285005827374, 199.5050980291588)"><circle r="92.27321821656155" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(310.0453070999502, 685.7487861972327)"><circle style="transition:all 0.5s ease-out" r="13.301469568224098" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(345.97079193669504, 685.9103241587441)"><circle style="transition:all 0.5s ease-out" r="12.030692758975125" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(328.9012592327577, 706.7811828362729)"><circle style="transition:all 0.5s ease-out" r="11.745793973078548" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(328.9906330367501, 668.2014287736802)"><circle style="transition:all 0.5s ease-out" r="9.31760069097745" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(309.01852998732795, 660.327472933539)"><circle style="transition:all 0.5s ease-out" r="8.977923069056143" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(305.71931566689, 710.3858020752415)"><circle style="transition:all 0.5s ease-out" r="8.512461619911566" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(345.66018068614113, 666.4351119642287)"><circle style="transition:all 0.5s ease-out" r="4.2452658347361085" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(344.7727563464441, 702.5702159887434)"><circle style="transition:all 0.5s ease-out" r="1.4748230405423377" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(703.8139667594772, 527.1557713436447)"><circle style="transition:all 0.5s ease-out" r="16.536067250557842" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(778.8621990400645, 570.0854043526708)"><circle r="61.70172260960654" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(717.5497323686651, 693.1410767346827)"><circle r="61.86175651346099" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(725.4786248202122, 443.3503603598813)"><circle r="61.70172260960655" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(815.9255796199952, 665.2156778676149)"><circle r="26.457891906861885" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(830.9874716327288, 473.39307041316243)"><circle r="34.077322847649405" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(896.6002602399889, 619.8132053020164)"><circle r="52.168797786598724" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(853.6314842076881, 527.4166478938434)"><circle style="transition:all 0.5s ease-out" r="15.964332930227892" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(526.6781412802869, 561.9831724861978)"><circle r="155.78475878682949" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(917.8142998307578, 514.6164507209025)"><circle r="41.243377971831976" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(856.6144727025027, 560.7986085603115)"><circle style="transition:all 0.5s ease-out" r="8.027776443517636" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(871.1979721299496, 548.2872313784734)"><circle style="transition:all 0.5s ease-out" r="8.008399692008762" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(851.9451419704934, 574.3018675351781)"><circle style="transition:all 0.5s ease-out" r="3.073460851218337" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(718.5717760925035, 611.372467138263)"><circle style="transition:all 0.5s ease-out" r="2.7982799722851834" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(792.2671086813739, 498.57330372624637)"><circle style="transition:all 0.5s ease-out" r="2.3911113739020915" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(728.3581505248196, 518.041146589911)"><circle style="transition:all 0.5s ease-out" r="2.173265009607865" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(271.09659053239136, 583.342381404345)"><circle r="29.927086668478605" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(320.67846974615975, 583.342381404345)"><circle style="transition:all 0.5s ease-out" r="15.956545450286352" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#89e051;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(304.5879348819669, 601.0046961046318)"><circle style="transition:all 0.5s ease-out" r="4.2379400901324145" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(24.10530148796255, 337.65351269934234)"><circle style="transition:all 0.5s ease-out" r="16.582978173887366" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(216.6995350679417, 337.65351269934234)"><circle r="172.31300831108828" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(39.162058795060716, 354.5160683323725)"><circle style="transition:all 0.5s ease-out" r="2.325227860290965" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(181.6174925329217, 668.8661822807057)"><circle style="transition:all 0.5s ease-out" r="23.655037168334218" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(235.25964076788532, 666.0924002361269)"><circle style="transition:all 0.5s ease-out" r="23.65109608528102" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(210.66402066765136, 709.4689523573954)"><circle r="17.785357089538007" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(217.5175141387861, 634.3371548057266)"><circle style="transition:all 0.5s ease-out" r="9.557945701792354" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(196.00848014520005, 637.0406468104854)"><circle style="transition:all 0.5s ease-out" r="8.050966987092512" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(207.80242421434411, 655.7034054899063)"><circle style="transition:all 0.5s ease-out" r="2.590703843132601" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(208.55003338501703, 680.6847390060004)"><circle style="transition:all 0.5s ease-out" r="2.578681950686416" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(235.94393651106697, 695.4894819767502)"><circle style="transition:all 0.5s ease-out" r="2.5666037486861444" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(211.85180233036147, 648.3994953853786)"><circle style="transition:all 0.5s ease-out" r="2.5544684383925436" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(232.6083316194594, 636.799561572871)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(203.0751171993935, 648.8406831768349)"><circle style="transition:all 0.5s ease-out" r="2.517711580516173" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#f1e05a;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(414.79764353617486, 225.18973221407245)"><circle style="transition:all 0.5s ease-out" r="30.53479061320098" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#563d7c;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(512.7910567200302, 234.72113105345306)"><circle style="transition:all 0.5s ease-out" r="30.531737592085197" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(459.1689427145097, 257.52296748208977)"><circle style="transition:all 0.5s ease-out" r="21.235110665819438" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#f1e05a;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(463.62162140235665, 209.85675505439912)"><circle style="transition:all 0.5s ease-out" r="17.643364541120967" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(429.97707922932756, 163.47274453132013)"><circle r="24.555321990630024" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(500.1865499855529, 164.97508910938438)"><circle r="31.81043206832132" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(450.8113175809985, 229.50956510873348)"><circle style="transition:all 0.5s ease-out" r="2.614581802674051" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(477.0786898934024, 228.88295829986134)"><circle style="transition:all 0.5s ease-out" r="2.578681950686416" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(469.5034581256702, 232.54388794737457)"><circle style="transition:all 0.5s ease-out" r="2.5666037486861444" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(432.1882475860826, 257.02682062638047)"><circle style="transition:all 0.5s ease-out" r="2.5544684383925436" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(476.72794923767975, 237.1965299803462)"><circle style="transition:all 0.5s ease-out" r="2.542275202002629" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(320.1615724594394, 804.9875239262728)"><circle style="transition:all 0.5s ease-out" r="30.541913142306747" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(392.23035259112, 805.8219336390632)"><circle style="transition:all 0.5s ease-out" r="29.283952850675167" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(367.34422716445727, 852.8636618355339)"><circle style="transition:all 0.5s ease-out" r="14.435195443346567" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(357.5205254400021, 775.1921244857833)"><circle style="transition:all 0.5s ease-out" r="13.861991692422615" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(331.95801662079356, 760.1979925812761)"><circle style="transition:all 0.5s ease-out" r="12.576210123344019" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(343.2575132663266, 841.0833119950216)"><circle style="transition:all 0.5s ease-out" r="9.162913064921083" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#cb171e;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(381.75146532305627, 765.7569764071274)"><circle style="transition:all 0.5s ease-out" r="8.943245754961069" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(356.66117873557556, 825.4561565122851)"><circle style="transition:all 0.5s ease-out" r="8.226589586727627" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#199f4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(323.5059960183611, 846.7736839717282)"><circle style="transition:all 0.5s ease-out" r="8.192524887250588" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(398.08984669972006, 769.2095819314433)"><circle style="transition:all 0.5s ease-out" r="4.555951844425858" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000000;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(392.4529209350979, 842.494046836109)"><circle style="transition:all 0.5s ease-out" r="4.1937168964290805" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(356.73506157778695, 803.2215968544747)"><circle style="transition:all 0.5s ease-out" r="3.278905824283532" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(314.742802057446, 768.344908753919)"><circle style="transition:all 0.5s ease-out" r="3.269415483613904" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(369.17410173034506, 832.4259130160951)"><circle style="transition:all 0.5s ease-out" r="2.896494951407224" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(382.798077666883, 839.6427821647144)"><circle style="transition:all 0.5s ease-out" r="2.6733437869089967" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#083fa1;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(359.28695687171626, 794.6203582125373)"><circle style="transition:all 0.5s ease-out" r="2.4929059353720087" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(352.7091556518035, 792.7536887180717)"><circle style="transition:all 0.5s ease-out" r="1.142393014924692" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(753.5596362032686, 535.6407941484)"><circle style="transition:all 0.5s ease-out" r="15.962386416420713" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(798.663927272489, 548.1192330205217)"><circle r="19.787384039127627" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(766.2883984415773, 588.9606368525184)"><circle r="36.021888760704144" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(769.0371260106745, 545.4545693588735)"><circle style="transition:all 0.5s ease-out" r="3.755941507256401" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(778.6753794152045, 548.3701311197663)"><circle style="transition:all 0.5s ease-out" r="3.113638515318736" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(696.0239805223454, 656.0331535622186)"><circle style="transition:all 0.5s ease-out" r="15.962386416420713" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(737.5020999043074, 671.8422464849526)"><circle r="20.304869232203533" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(703.4897781061118, 711.1561413592167)"><circle r="36.00951663875224" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(711.4775362285071, 668.637710226765)"><circle style="transition:all 0.5s ease-out" r="3.755941507256401" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(719.0744447884382, 673.369965605528)"><circle style="transition:all 0.5s ease-out" r="1.9943247482976065" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(700.1760619834164, 408.90575015561035)"><circle style="transition:all 0.5s ease-out" r="15.962386416420713" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(745.2803530526367, 421.38418902773225)"><circle r="19.787384039127627" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(712.9048242217251, 462.2255928597289)"><circle r="36.021888760704144" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(715.6535517908222, 418.7195253660841)"><circle style="transition:all 0.5s ease-out" r="3.755941507256401" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(725.2918051953521, 421.6350871269768)"><circle style="transition:all 0.5s ease-out" r="3.113638515318736" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(803.6657752472271, 665.2156778676149)"><circle style="transition:all 0.5s ease-out" r="10.499840439090226" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(828.2745436065871, 665.2156778676149)"><circle style="transition:all 0.5s ease-out" r="10.41068082526645" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(814.8825126291322, 471.90146473333544)"><circle style="transition:all 0.5s ease-out" r="14.205189639172145" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(842.9458791781934, 471.90146473333544)"><circle style="transition:all 0.5s ease-out" r="10.15992981488562" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(832.663483767615, 493.57336789975994)"><circle style="transition:all 0.5s ease-out" r="10.129299869346372" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(832.4682487822087, 451.839688777434)"><circle style="transition:all 0.5s ease-out" r="8.774887248983598" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(884.8899766088306, 619.8145418044999)"><circle r="37.45851407917242" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(936.6061057709903, 619.8692027466999)"><circle style="transition:all 0.5s ease-out" r="9.162913064921083" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(931.2311553367786, 633.1154808281372)"><circle style="transition:all 0.5s ease-out" r="3.0633340993018727" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(930.7492409079523, 607.9361807812561)"><circle style="transition:all 0.5s ease-out" r="2.2297228532018036" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(927.9986814777565, 601.2905429812851)"><circle style="transition:all 0.5s ease-out" r="1.7627506917617402" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(927.1411380544627, 639.8270113763991)"><circle style="transition:all 0.5s ease-out" r="1.596238641642071" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(924.6831244424144, 596.1969734465586)"><circle style="transition:all 0.5s ease-out" r="1.1148614266009016" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(509.4249285356709, 562.1946222515398)"><circle style="transition:all 0.5s ease-out" r="16.91506025174909" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(594.3124503916213, 565.9835650658096)"><circle r="57.33198252525729" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(458.0907571193274, 593.129206614701)"><circle r="35.252814814403905" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(414.88568361282705, 523.3619964530683)"><circle r="34.50902657809285" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(524.6137748126333, 653.8856447809602)"><circle r="42.50018379580438" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(504.25999184598646, 488.51027072087953)"><circle r="49.115071088006374" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(583.0010716685043, 639.976747361837)"><circle style="transition:all 0.5s ease-out" r="9.751055021892693" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(527.6526899395637, 545.4475095935842)"><circle style="transition:all 0.5s ease-out" r="4.670457772978104" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(907.9869266011095, 514.4932006928734)"><circle style="transition:all 0.5s ease-out" r="26.6938896210276" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#89e051;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(946.8516863127405, 512.6733510830553)"><circle style="transition:all 0.5s ease-out" r="9.002117708299163" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#89e051;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(941.3453524686072, 531.7603643529651)"><circle style="transition:all 0.5s ease-out" r="7.663405315177631" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(934.2807649769983, 492.7714582676559)"><circle style="transition:all 0.5s ease-out" r="4.201119756376969" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(937.438579361238, 501.8101004126548)"><circle style="transition:all 0.5s ease-out" r="2.173265009607865" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000000;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(930.215575674129, 536.031153298642)"><circle style="transition:all 0.5s ease-out" r="1.057650415057044" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(259.5187438703285, 583.342381404345)"><circle style="transition:all 0.5s ease-out" r="14.65099291141227" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(287.5967069913054, 583.342381404345)"><circle style="transition:all 0.5s ease-out" r="9.728723114561118" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(277.2354541695483, 598.6899217127464)"><circle style="transition:all 0.5s ease-out" r="5.090657974259925" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#000080;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(276.74830482283, 571.9396680396128)"><circle style="transition:all 0.5s ease-out" r="2.3118258589796876" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(145.25770319262406, 347.7543374102044)"><circle style="transition:all 0.5s ease-out" r="23.17598217176223" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(238.1868617862446, 347.7543374102044)"><circle r="66.05492932685485" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(150.4031362089642, 415.6689140940736)"><circle r="41.23498602070316" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(157.28916806113872, 295.9475676297178)"><circle r="26.311271971547786" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(227.17287036599689, 461.4004553176366)"><circle r="44.42540354143982" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(207.22035577093106, 225.65294906289324)"><circle r="56.21377770158369" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(127.76804995506325, 318.54725671525404)"><circle style="transition:all 0.5s ease-out" r="7.169001089524915" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(248.68869763442007, 274.54949216731)"><circle style="transition:all 0.5s ease-out" r="4.201119756376969" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(207.52084777414646, 708.694654095818)"><circle style="transition:all 0.5s ease-out" r="2.5666037486861444" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(215.57240372456067, 710.7954246705635)"><circle style="transition:all 0.5s ease-out" r="2.5544684383925436" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(209.7443295886597, 716.7004755537)"><circle style="transition:all 0.5s ease-out" r="2.542275202002629" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(213.36419138389064, 702.8048897808061)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(200.14763069230088, 704.9177037219811)"><circle style="transition:all 0.5s ease-out" r="2.517711580516173" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ff9900;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(201.69567670979723, 714.5676526516689)"><circle style="transition:all 0.5s ease-out" r="2.5053394585642716" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(221.3206479684425, 704.8812717823117)"><circle style="transition:all 0.5s ease-out" r="2.4929059353720087" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(425.64221289616967, 162.4417101302195)"><circle style="transition:all 0.5s ease-out" r="2.6382436587484763" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(434.10386655575115, 162.67105152186505)"><circle style="transition:all 0.5s ease-out" r="2.6264393773510966" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(429.68911749605496, 169.8654956810905)"><circle style="transition:all 0.5s ease-out" r="2.614581802674051" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(430.08317061578765, 155.26282973053543)"><circle style="transition:all 0.5s ease-out" r="2.602670206316613" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(421.694430184682, 154.9880144338188)"><circle style="transition:all 0.5s ease-out" r="2.590703843132601" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(421.2980568094946, 169.65093653011388)"><circle style="transition:all 0.5s ease-out" r="2.578681950686416" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(438.44925132512213, 155.48975873655468)"><circle style="transition:all 0.5s ease-out" r="2.5666037486861444" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(438.3144201485417, 169.9172836272831)"><circle style="transition:all 0.5s ease-out" r="2.5544684383925436" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(417.27084542557867, 162.04988626374876)"><circle style="transition:all 0.5s ease-out" r="2.542275202002629" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(413.00481685301054, 169.1373344007977)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(442.4476913074979, 162.74504497757232)"><circle style="transition:all 0.5s ease-out" r="2.517711580516173" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(446.5766610043661, 169.85631614604367)"><circle style="transition:all 0.5s ease-out" r="2.5053394585642716" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(434.49575079210956, 148.23812350808512)"><circle style="transition:all 0.5s ease-out" r="2.4929059353720087" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(495.7269340955641, 164.9374030222777)"><circle style="transition:all 0.5s ease-out" r="23.652409852596865" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(525.607614245171, 164.9374030222777)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(524.3065986094563, 173.5735652300114)"><circle style="transition:all 0.5s ease-out" r="2.5053394585642716" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(524.297809462657, 156.31514541142144)"><circle style="transition:all 0.5s ease-out" r="2.4929059353720087" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(794.3115613128424, 548.388436942926)"><circle style="transition:all 0.5s ease-out" r="4.480300593536103" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(806.090997584447, 549.4891618456534)"><circle style="transition:all 0.5s ease-out" r="4.149022367647345" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#cb171e;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(799.6722206022181, 557.8141231135595)"><circle style="transition:all 0.5s ease-out" r="3.1631430262014573" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(801.3136512701137, 540.2001579826486)"><circle style="transition:all 0.5s ease-out" r="3.09361490881202" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(788.3084762609665, 539.7064741966078)"><circle style="transition:all 0.5s ease-out" r="2.874959374230404" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(788.3068341671309, 556.6463946748052)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(809.9366658474975, 540.5975789120288)"><circle style="transition:all 0.5s ease-out" r="2.3385530574052478" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(749.1121721239189, 588.9606368525184)"><circle r="9.230219996036654" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(780.3263396611185, 588.9606368525184)"><circle r="12.368505094153935" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(729.4399067074291, 672.5408595467397)"><circle style="transition:all 0.5s ease-out" r="7.059811018784864" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(748.672961964086, 671.6170669833243)"><circle style="transition:all 0.5s ease-out" r="6.13173784630496" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(740.2393797952969, 682.438649202839)"><circle style="transition:all 0.5s ease-out" r="4.38921382574377" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(739.2477133163064, 661.9911233336304)"><circle style="transition:all 0.5s ease-out" r="4.141526386154246" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(730.0658421306389, 660.3025268945792)"><circle style="transition:all 0.5s ease-out" r="1.9943247482976065" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(686.3259239104052, 711.1561413592167)"><circle r="9.230219996036654" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(717.5277193256529, 711.1561413592167)"><circle r="12.35613297220203" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(740.9279870929902, 421.6533929501368)"><circle style="transition:all 0.5s ease-out" r="4.480300593536103" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(752.7074233645948, 422.7541178528639)"><circle style="transition:all 0.5s ease-out" r="4.149022367647345" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#cb171e;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(746.2886463823661, 431.0790791207701)"><circle style="transition:all 0.5s ease-out" r="3.1631430262014573" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(747.9300770502614, 413.46511398985916)"><circle style="transition:all 0.5s ease-out" r="3.09361490881202" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(734.9249020411144, 412.9714302038184)"><circle style="transition:all 0.5s ease-out" r="2.874959374230404" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(734.9232599472784, 429.9113506820158)"><circle style="transition:all 0.5s ease-out" r="2.530023202006531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(756.553091627645, 413.86253491923924)"><circle style="transition:all 0.5s ease-out" r="2.3385530574052478" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(695.7285979040666, 462.2255928597289)"><circle r="9.230219996036654" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(726.9427654412663, 462.2255928597289)"><circle r="12.368505094153935" style="transition:all 0.5s ease-out" stroke="#290819" stroke-opacity="0.2" stroke-width="1" fill="white"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(867.086255074948, 619.8145418044999)"><circle style="transition:all 0.5s ease-out" r="15.956545450286352" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(902.6956456066187, 619.8145418044999)"><circle style="transition:all 0.5s ease-out" r="15.954597986380852" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(580.3985974226803, 567.2505525402743)"><circle style="transition:all 0.5s ease-out" r="16.95542600234146" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(615.5545821073408, 566.3818509002894)"><circle style="transition:all 0.5s ease-out" r="15.011351401347813" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(600.5794310987294, 595.879613408147)"><circle style="transition:all 0.5s ease-out" r="14.869927924942006" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(599.1052831344834, 539.3232677931717)"><circle style="transition:all 0.5s ease-out" r="13.454765530328514" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(569.36668124332, 535.6573946180355)"><circle style="transition:all 0.5s ease-out" r="13.308475873460122" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(568.5312068735408, 596.4887631787901)"><circle style="transition:all 0.5s ease-out" r="11.399424014161312" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(626.7590081078288, 539.4140266471192)"><circle style="transition:all 0.5s ease-out" r="10.99142553315067" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(628.5411640038969, 591.6545739409814)"><circle style="transition:all 0.5s ease-out" r="10.202657254057275" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(552.5682365265502, 555.9939497900814)"><circle style="transition:all 0.5s ease-out" r="9.865106326893764" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(553.1673695732865, 578.277624832587)"><circle style="transition:all 0.5s ease-out" r="9.223751960876431" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(639.3524486248735, 557.3512787898463)"><circle style="transition:all 0.5s ease-out" r="7.242310074972877" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(639.12974698968, 574.5259712391785)"><circle style="transition:all 0.5s ease-out" r="6.730846025504424" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(443.1279472755571, 589.7088549887079)"><circle style="transition:all 0.5s ease-out" r="16.20580608641313" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(476.178386647584, 589.7088549887079)"><circle style="transition:all 0.5s ease-out" r="13.146386190610224" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(462.3452575333221, 613.5371221746896)"><circle style="transition:all 0.5s ease-out" r="10.707894333070794" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(462.00715344906456, 570.4633844599538)"><circle style="transition:all 0.5s ease-out" r="7.055408267487435" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(405.5669969338585, 526.6734910382361)"><circle style="transition:all 0.5s ease-out" r="10.371806971074559" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(436.4675237211515, 522.2722882384153)"><circle style="transition:all 0.5s ease-out" r="9.899693259955423" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(423.6077246539719, 540.2193604303922)"><circle style="transition:all 0.5s ease-out" r="8.988300174892293" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(419.1810429974093, 509.1329499380173)"><circle style="transition:all 0.5s ease-out" r="8.62487812269121" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(399.72855800316916, 506.0403913677029)"><circle style="transition:all 0.5s ease-out" r="7.871426975209228" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(408.7064085222642, 542.8940167350438)"><circle style="transition:all 0.5s ease-out" r="2.949646081084676" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(506.42345303817325, 644.0395112565723)"><circle style="transition:all 0.5s ease-out" r="18.117784515166804" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(544.6851078263724, 644.0395112565723)"><circle style="transition:all 0.5s ease-out" r="16.445623178028775" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(527.1882488770407, 676.1313150264031)"><circle style="transition:all 0.5s ease-out" r="16.40779100650647" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(485.9731269470969, 488.27720333997144)"><circle style="transition:all 0.5s ease-out" r="19.06380440921506" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(534.2784964584923, 486.02063368609726)"><circle style="transition:all 0.5s ease-out" r="15.99350220894569" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(513.5526324378004, 512.4812144881761)"><circle style="transition:all 0.5s ease-out" r="14.426582557470393" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(511.1976439682404, 467.82133526899156)"><circle style="transition:all 0.5s ease-out" r="10.208746575550782" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(490.83327163021863, 456.4822124281175)"><circle style="transition:all 0.5s ease-out" r="9.899693259955423" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(488.9917656387054, 517.9160951748636)"><circle style="transition:all 0.5s ease-out" r="7.528410829904972" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(218.93456647739896, 348.95346774867727)"><circle style="transition:all 0.5s ease-out" r="23.242922355571967" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(263.9351146143282, 348.95346774867727)"><circle style="transition:all 0.5s ease-out" r="18.059378686353792" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(245.79475504059423, 379.18737663918176)"><circle style="transition:all 0.5s ease-out" r="13.500875211505324" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(245.67652815520734, 319.99725473301277)"><circle style="transition:all 0.5s ease-out" r="12.474497315139766" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(219.20676560046564, 309.8311201792327)"><circle style="transition:all 0.5s ease-out" r="12.182125038859112" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(217.85334832909015, 387.9696099446971)"><circle style="transition:all 0.5s ease-out" r="12.089951267952136" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(273.5461571960082, 316.7072627926079)"><circle style="transition:all 0.5s ease-out" r="11.890403485981688" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(274.11469022449046, 380.2367931703688)"><circle style="transition:all 0.5s ease-out" r="11.14024966740788" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(194.96164799158748, 320.20519148937746)"><circle style="transition:all 0.5s ease-out" r="10.490958576139553" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(194.7097295808662, 376.751245947732)"><circle style="transition:all 0.5s ease-out" r="9.931031398674971" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(239.82245273904243, 294.9614051717944)"><circle style="transition:all 0.5s ease-out" r="9.538419745338016" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(236.49583067150013, 402.33674439957764)"><circle style="transition:all 0.5s ease-out" r="7.7480863976366114" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(286.93538480073465, 333.5474011873252)"><circle style="transition:all 0.5s ease-out" r="5.925569762880476" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(285.9540780332441, 364.2512866572633)"><circle style="transition:all 0.5s ease-out" r="5.0539018402358575" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(132.7815798274131, 415.6689140940736)"><circle style="transition:all 0.5s ease-out" r="19.915182544148596" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(172.16744230061454, 415.6689140940736)"><circle style="transition:all 0.5s ease-out" r="15.772432834049347" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(155.7260393865442, 439.3651503492228)"><circle style="transition:all 0.5s ease-out" r="9.3708065521022" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(155.31546154243387, 397.2863936896255)"><circle style="transition:all 0.5s ease-out" r="5.467369551490778" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(149.09952327779519, 295.90826067905243)"><circle style="transition:all 0.5s ease-out" r="10.208746575550782" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(169.93751279456075, 295.90826067905243)"><circle style="transition:all 0.5s ease-out" r="6.930995846211308" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(162.46249084986022, 311.26251712993724)"><circle style="transition:all 0.5s ease-out" r="6.447909755686791" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(162.12403303662282, 283.19141081459196)"><circle style="transition:all 0.5s ease-out" r="4.2961962953012955" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(151.30362831345965, 278.2281554238702)"><circle style="transition:all 0.5s ease-out" r="3.909970179736407" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(205.3859573359487, 457.9701469690593)"><circle style="transition:all 0.5s ease-out" r="18.671848814367277" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(243.05039178277679, 457.9701469690593)"><circle style="transition:all 0.5s ease-out" r="15.294338537457342" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(227.37547914039808, 487.5993668659219)"><circle style="transition:all 0.5s ease-out" r="14.527461474350465" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(227.09619780504383, 432.08644417178897)"><circle style="transition:all 0.5s ease-out" r="11.413045029910652" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(195.4949717848822, 225.25565528648127)"><circle style="transition:all 0.5s ease-out" r="19.712881259810555" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(237.16227513721788, 225.25565528648127)"><circle style="transition:all 0.5s ease-out" r="18.256174997521647" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(217.7249332280996, 259.31035007471127)"><circle style="transition:all 0.5s ease-out" r="17.256960153086474" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(217.64206569946936, 194.0110563317906)"><circle style="transition:all 0.5s ease-out" r="14.886635714397634" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(187.07262029166048, 190.69162712344013)"><circle style="transition:all 0.5s ease-out" r="12.16425706166288" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(190.03876620617808, 255.20722078859342)"><circle style="transition:all 0.5s ease-out" r="7.033353170486991" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(242.86209766288516, 197.05345644503836)"><circle style="transition:all 0.5s ease-out" r="6.817995190636699" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(745.669318783846, 587.1343190816833)"><circle style="transition:all 0.5s ease-out" r="1.6347077418069518" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#2b2b2b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(752.5985122622985, 587.1343190816833)"><circle style="transition:all 0.5s ease-out" r="1.596238641642071" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ece2a9;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(749.1717199151203, 592.9964269045536)"><circle style="transition:all 0.5s ease-out" r="1.4957435612232048" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(775.9595045331006, 588.9606368525184)"><circle style="transition:all 0.5s ease-out" r="4.303422871132548" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(786.4788860797528, 588.9606368525184)"><circle style="transition:all 0.5s ease-out" r="2.517711580516173" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(682.8830705703324, 709.3298235883816)"><circle style="transition:all 0.5s ease-out" r="1.6347077418069518" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#2b2b2b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(689.8122640487849, 709.3298235883816)"><circle style="transition:all 0.5s ease-out" r="1.596238641642071" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ece2a9;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(686.3854717016067, 715.1919314112519)"><circle style="transition:all 0.5s ease-out" r="1.4957435612232048" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(713.1732563195869, 711.1561413592167)"><circle style="transition:all 0.5s ease-out" r="4.303422871132548" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(723.6802657442872, 711.1561413592167)"><circle style="transition:all 0.5s ease-out" r="2.5053394585642716" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(692.2857445639938, 460.39927508889383)"><circle style="transition:all 0.5s ease-out" r="1.6347077418069518" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#2b2b2b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(699.2149380424463, 460.39927508889383)"><circle style="transition:all 0.5s ease-out" r="1.596238641642071" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#ece2a9;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(695.7881456952681, 466.2613829117641)"><circle style="transition:all 0.5s ease-out" r="1.4957435612232048" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(722.5759303132484, 462.2255928597289)"><circle style="transition:all 0.5s ease-out" r="4.303422871132548" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#701516;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(733.0953118599006, 462.2255928597289)"><circle style="transition:all 0.5s ease-out" r="2.517711580516173" stroke-width="0" stroke="#374151"></circle></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(320.00612713573406, 687.2198622231437)"><path fill="none" d="M 0 46.02836011911288 A 46.02836011911288 46.02836011911288 0 0 1 0 -46.02836011911288 A 46.02836011911288 46.02836011911288 0 0 1 0 46.02836011911288" id="CircleText--1" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--1" startOffset="50%">views</textPath></text><path fill="none" d="M 0 46.02836011911288 A 46.02836011911288 46.02836011911288 0 0 1 0 -46.02836011911288 A 46.02836011911288 46.02836011911288 0 0 1 0 46.02836011911288" id="CircleText--2" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--2" startOffset="50%">views</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(661.4430539975464, 565.1971458820385)"><path fill="none" d="M 0 310.55664287251915 A 310.55664287251915 310.55664287251915 0 0 1 0 -310.55664287251915 A 310.55664287251915 310.55664287251915 0 0 1 0 310.55664287251915" id="CircleText--3" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--3" startOffset="50%">test</textPath></text><path fill="none" d="M 0 310.55664287251915 A 310.55664287251915 310.55664287251915 0 0 1 0 -310.55664287251915 A 310.55664287251915 310.55664287251915 0 0 1 0 310.55664287251915" id="CircleText--4" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--4" startOffset="50%">test</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(288.90225953017944, 583.342381404345)"><path fill="none" d="M 0 56.431002761270165 A 56.431002761270165 56.431002761270165 0 0 1 0 -56.431002761270165 A 56.431002761270165 56.431002761270165 0 0 1 0 56.431002761270165" id="CircleText--5" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--5" startOffset="50%">lua</textPath></text><path fill="none" d="M 0 56.431002761270165 A 56.431002761270165 56.431002761270165 0 0 1 0 -56.431002761270165 A 56.431002761270165 56.431002761270165 0 0 1 0 56.431002761270165" id="CircleText--6" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--6" startOffset="50%">lua</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(198.2674333465526, 337.65351269934234)"><path fill="none" d="M 0 199.44335712748088 A 199.44335712748088 199.44335712748088 0 0 1 0 -199.44335712748088 A 199.44335712748088 199.44335712748088 0 0 1 0 199.44335712748088" id="CircleText--7" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--7" startOffset="50%">lib</textPath></text><path fill="none" d="M 0 199.44335712748088 A 199.44335712748088 199.44335712748088 0 0 1 0 -199.44335712748088 A 199.44335712748088 199.44335712748088 0 0 1 0 199.44335712748088" id="CircleText--8" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--8" startOffset="50%">lib</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(208.8559603568583, 675.5911309430885)"><path fill="none" d="M 0 59.71139231128383 A 59.71139231128383 59.71139231128383 0 0 1 0 -59.71139231128383 A 59.71139231128383 59.71139231128383 0 0 1 0 59.71139231128383" id="CircleText--9" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--9" startOffset="50%">docs</textPath></text><path fill="none" d="M 0 59.71139231128383 A 59.71139231128383 59.71139231128383 0 0 1 0 -59.71139231128383 A 59.71139231128383 59.71139231128383 0 0 1 0 59.71139231128383" id="CircleText--10" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--10" startOffset="50%">docs</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(467.62285005827374, 199.5050980291588)"><path fill="none" d="M 0 97.27321821656155 A 97.27321821656155 97.27321821656155 0 0 1 0 -97.27321821656155 A 97.27321821656155 97.27321821656155 0 0 1 0 97.27321821656155" id="CircleText--11" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--11" startOffset="50%">public</textPath></text><path fill="none" d="M 0 97.27321821656155 A 97.27321821656155 97.27321821656155 0 0 1 0 -97.27321821656155 A 97.27321821656155 97.27321821656155 0 0 1 0 97.27321821656155" id="CircleText--12" transform="rotate(1)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:15px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--12" startOffset="50%">public</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(778.8621990400645, 570.0854043526708)"><path fill="none" d="M 0 62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 -62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 62.70172260960655" id="CircleText--13" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--13" startOffset="50%">rails6_dummy</textPath></text><path fill="none" d="M 0 62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 -62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 62.70172260960655" id="CircleText--14" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--14" startOffset="50%">rails6_dummy</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(717.5497323686651, 693.1410767346827)"><path fill="none" d="M 0 62.86175651346099 A 62.86175651346099 62.86175651346099 0 0 1 0 -62.86175651346099 A 62.86175651346099 62.86175651346099 0 0 1 0 62.86175651346099" id="CircleText--15" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--15" startOffset="50%">rails5_dummy</textPath></text><path fill="none" d="M 0 62.86175651346099 A 62.86175651346099 62.86175651346099 0 0 1 0 -62.86175651346099 A 62.86175651346099 62.86175651346099 0 0 1 0 62.86175651346099" id="CircleText--16" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--16" startOffset="50%">rails5_dummy</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(725.4786248202122, 443.3503603598813)"><path fill="none" d="M 0 62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 -62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 62.70172260960655" id="CircleText--17" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--17" startOffset="50%">rails4_dummy</textPath></text><path fill="none" d="M 0 62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 -62.70172260960655 A 62.70172260960655 62.70172260960655 0 0 1 0 62.70172260960655" id="CircleText--18" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--18" startOffset="50%">rails4_dummy</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(815.9255796199952, 665.2156778676149)"><path fill="none" d="M 0 27.45789190686189 A 27.45789190686189 27.45789190686189 0 0 1 0 -27.45789190686189 A 27.45789190686189 27.45789190686189 0 0 1 0 27.45789190686189" id="CircleText--19" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--19" startOffset="50%">integration</textPath></text><path fill="none" d="M 0 27.45789190686189 A 27.45789190686189 27.45789190686189 0 0 1 0 -27.45789190686189 A 27.45789190686189 27.45789190686189 0 0 1 0 27.45789190686189" id="CircleText--20" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--20" startOffset="50%">integration</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(830.9874716327288, 473.39307041316243)"><path fill="none" d="M 0 35.077322847649405 A 35.077322847649405 35.077322847649405 0 0 1 0 -35.077322847649405 A 35.077322847649405 35.077322847649405 0 0 1 0 35.077322847649405" id="CircleText--21" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--21" startOffset="50%">forked</textPath></text><path fill="none" d="M 0 35.077322847649405 A 35.077322847649405 35.077322847649405 0 0 1 0 -35.077322847649405 A 35.077322847649405 35.077322847649405 0 0 1 0 35.077322847649405" id="CircleText--22" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--22" startOffset="50%">forked</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(896.6002602399889, 619.8132053020164)"><path fill="none" d="M 0 53.16879778659873 A 53.16879778659873 53.16879778659873 0 0 1 0 -53.16879778659873 A 53.16879778659873 53.16879778659873 0 0 1 0 53.16879778659873" id="CircleText--23" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--23" startOffset="50%">fixtures</textPath></text><path fill="none" d="M 0 53.16879778659873 A 53.16879778659873 53.16879778659873 0 0 1 0 -53.16879778659873 A 53.16879778659873 53.16879778659873 0 0 1 0 53.16879778659873" id="CircleText--24" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--24" startOffset="50%">fixtures</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(526.6781412802869, 561.9831724861978)"><path fill="none" d="M 0 156.78475878682949 A 156.78475878682949 156.78475878682949 0 0 1 0 -156.78475878682949 A 156.78475878682949 156.78475878682949 0 0 1 0 156.78475878682949" id="CircleText--25" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--25" startOffset="50%">coverband</textPath></text><path fill="none" d="M 0 156.78475878682949 A 156.78475878682949 156.78475878682949 0 0 1 0 -156.78475878682949 A 156.78475878682949 156.78475878682949 0 0 1 0 156.78475878682949" id="CircleText--26" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--26" startOffset="50%">coverband</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(917.8142998307578, 514.6164507209025)"><path fill="none" d="M 0 42.243377971831976 A 42.243377971831976 42.243377971831976 0 0 1 0 -42.243377971831976 A 42.243377971831976 42.243377971831976 0 0 1 0 42.243377971831976" id="CircleText--27" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--27" startOffset="50%">benchmarks</textPath></text><path fill="none" d="M 0 42.243377971831976 A 42.243377971831976 42.243377971831976 0 0 1 0 -42.243377971831976 A 42.243377971831976 42.243377971831976 0 0 1 0 42.243377971831976" id="CircleText--28" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--28" startOffset="50%">benchmarks</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(271.09659053239136, 583.342381404345)"><path fill="none" d="M 0 30.92708666847861 A 30.92708666847861 30.92708666847861 0 0 1 0 -30.92708666847861 A 30.92708666847861 30.92708666847861 0 0 1 0 30.92708666847861" id="CircleText--29" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--29" startOffset="50%">test</textPath></text><path fill="none" d="M 0 30.92708666847861 A 30.92708666847861 30.92708666847861 0 0 1 0 -30.92708666847861 A 30.92708666847861 30.92708666847861 0 0 1 0 30.92708666847861" id="CircleText--30" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--30" startOffset="50%">test</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(216.6995350679417, 337.65351269934234)"><path fill="none" d="M 0 173.31300831108828 A 173.31300831108828 173.31300831108828 0 0 1 0 -173.31300831108828 A 173.31300831108828 173.31300831108828 0 0 1 0 173.31300831108828" id="CircleText--31" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--31" startOffset="50%">coverband</textPath></text><path fill="none" d="M 0 173.31300831108828 A 173.31300831108828 173.31300831108828 0 0 1 0 -173.31300831108828 A 173.31300831108828 173.31300831108828 0 0 1 0 173.31300831108828" id="CircleText--32" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--32" startOffset="50%">coverband</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(429.97707922932756, 163.47274453132013)"><path fill="none" d="M 0 25.55532199063002 A 25.55532199063002 25.55532199063002 0 0 1 0 -25.55532199063002 A 25.55532199063002 25.55532199063002 0 0 1 0 25.55532199063002" id="CircleText--33" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--33" startOffset="50%">images</textPath></text><path fill="none" d="M 0 25.55532199063002 A 25.55532199063002 25.55532199063002 0 0 1 0 -25.55532199063002 A 25.55532199063002 25.55532199063002 0 0 1 0 25.55532199063002" id="CircleText--34" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--34" startOffset="50%">images</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(500.1865499855529, 164.97508910938438)"><path fill="none" d="M 0 32.81043206832132 A 32.81043206832132 32.81043206832132 0 0 1 0 -32.81043206832132 A 32.81043206832132 32.81043206832132 0 0 1 0 32.81043206832132" id="CircleText--35" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--35" startOffset="50%">colorbox</textPath></text><path fill="none" d="M 0 32.81043206832132 A 32.81043206832132 32.81043206832132 0 0 1 0 -32.81043206832132 A 32.81043206832132 32.81043206832132 0 0 1 0 32.81043206832132" id="CircleText--36" transform="rotate(2)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--36" startOffset="50%">colorbox</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(798.663927272489, 548.1192330205217)"><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--37" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--37" startOffset="50%">config</textPath></text><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--38" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--38" startOffset="50%">config</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(766.2883984415773, 588.9606368525184)"><path fill="none" d="M 0 33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 -33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 33.021888760704144" id="CircleText--39" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--39" startOffset="50%">app</textPath></text><path fill="none" d="M 0 33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 -33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 33.021888760704144" id="CircleText--40" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--40" startOffset="50%">app</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(737.5020999043074, 671.8422464849526)"><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--41" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--41" startOffset="50%">config</textPath></text><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--42" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--42" startOffset="50%">config</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(703.4897781061118, 711.1561413592167)"><path fill="none" d="M 0 33.00951663875224 A 33.00951663875224 33.00951663875224 0 0 1 0 -33.00951663875224 A 33.00951663875224 33.00951663875224 0 0 1 0 33.00951663875224" id="CircleText--43" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--43" startOffset="50%">app</textPath></text><path fill="none" d="M 0 33.00951663875224 A 33.00951663875224 33.00951663875224 0 0 1 0 -33.00951663875224 A 33.00951663875224 33.00951663875224 0 0 1 0 33.00951663875224" id="CircleText--44" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--44" startOffset="50%">app</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(745.2803530526367, 421.38418902773225)"><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--45" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--45" startOffset="50%">config</textPath></text><path fill="none" d="M 0 20 A 20 20 0 0 1 0 -20 A 20 20 0 0 1 0 20" id="CircleText--46" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--46" startOffset="50%">config</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(712.9048242217251, 462.2255928597289)"><path fill="none" d="M 0 33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 -33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 33.021888760704144" id="CircleText--47" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--47" startOffset="50%">app</textPath></text><path fill="none" d="M 0 33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 -33.021888760704144 A 33.021888760704144 33.021888760704144 0 0 1 0 33.021888760704144" id="CircleText--48" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--48" startOffset="50%">app</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(884.8899766088306, 619.8145418044999)"><path fill="none" d="M 0 34.45851407917242 A 34.45851407917242 34.45851407917242 0 0 1 0 -34.45851407917242 A 34.45851407917242 34.45851407917242 0 0 1 0 34.45851407917242" id="CircleText--49" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--49" startOffset="50%">app</textPath></text><path fill="none" d="M 0 34.45851407917242 A 34.45851407917242 34.45851407917242 0 0 1 0 -34.45851407917242 A 34.45851407917242 34.45851407917242 0 0 1 0 34.45851407917242" id="CircleText--50" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--50" startOffset="50%">app</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(594.3124503916213, 565.9835650658096)"><path fill="none" d="M 0 54.33198252525729 A 54.33198252525729 54.33198252525729 0 0 1 0 -54.33198252525729 A 54.33198252525729 54.33198252525729 0 0 1 0 54.33198252525729" id="CircleText--51" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--51" startOffset="50%">utils</textPath></text><path fill="none" d="M 0 54.33198252525729 A 54.33198252525729 54.33198252525729 0 0 1 0 -54.33198252525729 A 54.33198252525729 54.33198252525729 0 0 1 0 54.33198252525729" id="CircleText--52" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--52" startOffset="50%">utils</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(458.0907571193274, 593.129206614701)"><path fill="none" d="M 0 32.252814814403905 A 32.252814814403905 32.252814814403905 0 0 1 0 -32.252814814403905 A 32.252814814403905 32.252814814403905 0 0 1 0 32.252814814403905" id="CircleText--53" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--53" startOffset="50%">reporters</textPath></text><path fill="none" d="M 0 32.252814814403905 A 32.252814814403905 32.252814814403905 0 0 1 0 -32.252814814403905 A 32.252814814403905 32.252814814403905 0 0 1 0 32.252814814403905" id="CircleText--54" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--54" startOffset="50%">reporters</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(414.88568361282705, 523.3619964530683)"><path fill="none" d="M 0 31.50902657809285 A 31.50902657809285 31.50902657809285 0 0 1 0 -31.50902657809285 A 31.50902657809285 31.50902657809285 0 0 1 0 31.50902657809285" id="CircleText--55" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--55" startOffset="50%">integrations</textPath></text><path fill="none" d="M 0 31.50902657809285 A 31.50902657809285 31.50902657809285 0 0 1 0 -31.50902657809285 A 31.50902657809285 31.50902657809285 0 0 1 0 31.50902657809285" id="CircleText--56" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--56" startOffset="50%">integrations</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(524.6137748126333, 653.8856447809602)"><path fill="none" d="M 0 39.50018379580438 A 39.50018379580438 39.50018379580438 0 0 1 0 -39.50018379580438 A 39.50018379580438 39.50018379580438 0 0 1 0 39.50018379580438" id="CircleText--57" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--57" startOffset="50%">collectors</textPath></text><path fill="none" d="M 0 39.50018379580438 A 39.50018379580438 39.50018379580438 0 0 1 0 -39.50018379580438 A 39.50018379580438 39.50018379580438 0 0 1 0 39.50018379580438" id="CircleText--58" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--58" startOffset="50%">collectors</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(504.25999184598646, 488.51027072087953)"><path fill="none" d="M 0 46.115071088006374 A 46.115071088006374 46.115071088006374 0 0 1 0 -46.115071088006374 A 46.115071088006374 46.115071088006374 0 0 1 0 46.115071088006374" id="CircleText--59" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--59" startOffset="50%">adapters</textPath></text><path fill="none" d="M 0 46.115071088006374 A 46.115071088006374 46.115071088006374 0 0 1 0 -46.115071088006374 A 46.115071088006374 46.115071088006374 0 0 1 0 46.115071088006374" id="CircleText--60" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--60" startOffset="50%">adapters</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(238.1868617862446, 347.7543374102044)"><path fill="none" d="M 0 63.05492932685485 A 63.05492932685485 63.05492932685485 0 0 1 0 -63.05492932685485 A 63.05492932685485 63.05492932685485 0 0 1 0 63.05492932685485" id="CircleText--61" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--61" startOffset="50%">utils</textPath></text><path fill="none" d="M 0 63.05492932685485 A 63.05492932685485 63.05492932685485 0 0 1 0 -63.05492932685485 A 63.05492932685485 63.05492932685485 0 0 1 0 63.05492932685485" id="CircleText--62" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--62" startOffset="50%">utils</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(150.4031362089642, 415.6689140940736)"><path fill="none" d="M 0 38.23498602070316 A 38.23498602070316 38.23498602070316 0 0 1 0 -38.23498602070316 A 38.23498602070316 38.23498602070316 0 0 1 0 38.23498602070316" id="CircleText--63" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--63" startOffset="50%">reporters</textPath></text><path fill="none" d="M 0 38.23498602070316 A 38.23498602070316 38.23498602070316 0 0 1 0 -38.23498602070316 A 38.23498602070316 38.23498602070316 0 0 1 0 38.23498602070316" id="CircleText--64" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--64" startOffset="50%">reporters</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(157.28916806113872, 295.9475676297178)"><path fill="none" d="M 0 23.311271971547782 A 23.311271971547782 23.311271971547782 0 0 1 0 -23.311271971547782 A 23.311271971547782 23.311271971547782 0 0 1 0 23.311271971547782" id="CircleText--65" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--65" startOffset="50%">integrations</textPath></text><path fill="none" d="M 0 23.311271971547782 A 23.311271971547782 23.311271971547782 0 0 1 0 -23.311271971547782 A 23.311271971547782 23.311271971547782 0 0 1 0 23.311271971547782" id="CircleText--66" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--66" startOffset="50%">integrations</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(227.17287036599689, 461.4004553176366)"><path fill="none" d="M 0 41.42540354143982 A 41.42540354143982 41.42540354143982 0 0 1 0 -41.42540354143982 A 41.42540354143982 41.42540354143982 0 0 1 0 41.42540354143982" id="CircleText--67" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--67" startOffset="50%">collectors</textPath></text><path fill="none" d="M 0 41.42540354143982 A 41.42540354143982 41.42540354143982 0 0 1 0 -41.42540354143982 A 41.42540354143982 41.42540354143982 0 0 1 0 41.42540354143982" id="CircleText--68" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--68" startOffset="50%">collectors</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(207.22035577093106, 225.65294906289324)"><path fill="none" d="M 0 53.213777701583695 A 53.213777701583695 53.213777701583695 0 0 1 0 -53.213777701583695 A 53.213777701583695 53.213777701583695 0 0 1 0 53.213777701583695" id="CircleText--69" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--69" startOffset="50%">adapters</textPath></text><path fill="none" d="M 0 53.213777701583695 A 53.213777701583695 53.213777701583695 0 0 1 0 -53.213777701583695 A 53.213777701583695 53.213777701583695 0 0 1 0 53.213777701583695" id="CircleText--70" transform="rotate(3)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:13px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--70" startOffset="50%">adapters</textPath></text></g><g style="fill:#CED6E0;transition:transform 0s ease-out" transform="translate(181.6174925329217, 668.8661822807057)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">coverban...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">coverban...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">coverban...</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out" transform="translate(235.25964076788532, 666.0924002361269)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">coverban...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">coverban...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">coverban...</text></g><g style="fill:#f1e05a;transition:transform 0s ease-out" transform="translate(414.79764353617486, 225.18973221407245)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">dependenci...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">dependenci...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">dependenci...</text></g><g style="fill:#563d7c;transition:transform 0s ease-out" transform="translate(512.7910567200302, 234.72113105345306)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">applicatio...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">applicatio...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">applicatio...</text></g><g style="fill:#083fa1;transition:transform 0s ease-out" transform="translate(320.1615724594394, 804.9875239262728)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">README.md</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">README.md</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">README.md</text></g><g style="fill:#083fa1;transition:transform 0s ease-out" transform="translate(392.23035259112, 805.8219336390632)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">changes.md</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">changes.md</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">changes.md</text></g><g style="fill:#701516;transition:transform 0s ease-out" transform="translate(907.9869266011095, 514.4932006928734)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">benchmark...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">benchmark...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">benchmark...</text></g><g style="fill:#701516;transition:transform 0s ease-out" transform="translate(145.25770319262406, 347.7543374102044)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">configur...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">configur...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">configur...</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out" transform="translate(495.7269340955641, 164.9374030222777)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">loading.gif</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">loading.gif</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">loading.gif</text></g><g style="fill:#701516;transition:transform 0s ease-out" transform="translate(218.93456647739896, 348.95346774867727)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">source_f...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">source_f...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">source_f...</text></g><g transform="translate(940, 740)"><g transform="translate(0, 0)"><circle r="5" fill="#563d7c"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.css</text></g><g transform="translate(0, 15)"><circle r="5" fill="#701516"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.erb</text></g><g transform="translate(0, 30)"><circle r="5" fill="#701516"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.gemspec</text></g><g transform="translate(0, 45)"><circle r="5" fill="#000000"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.gitignore</text></g><g transform="translate(0, 60)"><circle r="5" fill="#ece2a9"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.haml</text></g><g transform="translate(0, 75)"><circle r="5" fill="#f1e05a"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.js</text></g><g transform="translate(0, 90)"><circle r="5" fill="#000080"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.lua</text></g><g transform="translate(0, 105)"><circle r="5" fill="#083fa1"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.md</text></g><g transform="translate(0, 120)"><circle r="5" fill="#701516"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.rake</text></g><g transform="translate(0, 135)"><circle r="5" fill="#701516"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.rb</text></g><g transform="translate(0, 150)"><circle r="5" fill="#701516"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.ru</text></g><g transform="translate(0, 165)"><circle r="5" fill="#89e051"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.sh</text></g><g transform="translate(0, 180)"><circle r="5" fill="#2b2b2b"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.slim</text></g><g transform="translate(0, 195)"><circle r="5" fill="#ff9900"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.svg</text></g><g transform="translate(0, 210)"><circle r="5" fill="#199f4b"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.txt</text></g><g transform="translate(0, 225)"><circle r="5" fill="#cb171e"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.yml</text></g><g fill="#9CA3AF" style="font-weight:300;font-style:italic;font-size:12px">each dot sized by file size</g></g></svg>
@@ -52,8 +52,9 @@ module Coverband
52
52
  end
53
53
 
54
54
  def get_coverage_report
55
- data = Coverband.configuration.store.split_coverage(Coverband::TYPES)
56
- data.merge(Coverband::MERGED_TYPE => Coverband.configuration.store.merged_coverage(Coverband::TYPES))
55
+ coverage_cache = {}
56
+ data = Coverband.configuration.store.split_coverage(Coverband::TYPES, coverage_cache)
57
+ data.merge(Coverband::MERGED_TYPE => Coverband.configuration.store.merged_coverage(Coverband::TYPES, coverage_cache))
57
58
  end
58
59
 
59
60
  def covered_files
@@ -66,12 +67,12 @@ module Coverband
66
67
 
67
68
  protected
68
69
 
69
- def split_coverage(types)
70
+ def split_coverage(types, coverage_cache)
70
71
  types.reduce({}) do |data, type|
71
72
  if type == Coverband::RUNTIME_TYPE && Coverband.configuration.simulate_oneshot_lines_coverage
72
- data.update(type => simulated_runtime_coverage)
73
+ data.update(type => coverage_cache[type] ||= simulated_runtime_coverage)
73
74
  else
74
- data.update(type => coverage(type))
75
+ data.update(type => coverage_cache[type] ||= coverage(type))
75
76
  end
76
77
  end
77
78
  end
@@ -85,9 +86,9 @@ module Coverband
85
86
  merge_reports(runtime_data, eager_data, skip_expansion: true)
86
87
  end
87
88
 
88
- def merged_coverage(types)
89
+ def merged_coverage(types, coverage_cache)
89
90
  types.reduce({}) do |data, type|
90
- merge_reports(data, coverage(type), skip_expansion: true)
91
+ merge_reports(data, coverage_cache[type] ||= coverage(type), skip_expansion: true)
91
92
  end
92
93
  end
93
94
 
@@ -14,7 +14,7 @@ module Coverband
14
14
  #
15
15
  # View Reports:
16
16
  # Using this assumes you are syncing the coverage files
17
- # to some shared storage that is accessable outside of the production server
17
+ # to some shared storage that is accessible outside of the production server
18
18
  # download files to a system where you want to view the reports..
19
19
  # When viewing coverage from the filestore adapter it merges all coverage
20
20
  # files matching the path pattern, in this case `log/coverage.log.*`
@@ -9,7 +9,7 @@ module Coverband
9
9
  FILE_LENGTH_KEY = "file_length"
10
10
  META_DATA_KEYS = [DATA_KEY, FIRST_UPDATED_KEY, LAST_UPDATED_KEY, FILE_HASH].freeze
11
11
  ###
12
- # This key isn't related to the coverband version, but to the interal format
12
+ # This key isn't related to the coverband version, but to the internal format
13
13
  # used to store data to redis. It is changed only when breaking changes to our
14
14
  # redis format are required.
15
15
  ###
@@ -4,7 +4,7 @@ module Coverband
4
4
  module Adapters
5
5
  ###
6
6
  # NullStore is for benchmarking the impacts of calculating
7
- # and storing coverage data independant of Coverband/Coverage
7
+ # and storing coverage data independent of Coverband/Coverage
8
8
  #
9
9
  # Usage:
10
10
  # config.store = Coverband::Adapters::NullStore.new
@@ -7,7 +7,7 @@ module Coverband
7
7
  ###
8
8
  class RedisStore < Base
9
9
  ###
10
- # This key isn't related to the coverband version, but to the interal format
10
+ # This key isn't related to the coverband version, but to the internal format
11
11
  # used to store data to redis. It is changed only when breaking changes to our
12
12
  # redis format are required.
13
13
  ###
@@ -46,12 +46,30 @@ module Coverband
46
46
  @store.type = old_coverage_type
47
47
  end
48
48
 
49
+ def toggle_eager_loading
50
+ old_coverage_type = @store.type
51
+ eager_loading!
52
+ yield
53
+ ensure
54
+ @store.type = old_coverage_type
55
+ end
56
+
49
57
  def report_coverage
50
58
  @semaphore.synchronize do
51
59
  raise "no Coverband store set" unless @store
52
60
 
53
61
  files_with_line_usage = filtered_files(Delta.results)
54
- @store.save_report(files_with_line_usage)
62
+ if @store.type == Coverband::EAGER_TYPE && Coverband.configuration.defer_eager_loading_data?
63
+ @deferred_eager_loading_data = files_with_line_usage
64
+ else
65
+ if @deferred_eager_loading_data && Coverband.configuration.defer_eager_loading_data?
66
+ toggle_eager_loading do
67
+ @store.save_report(@deferred_eager_loading_data)
68
+ @deferred_eager_loading_data = nil
69
+ end
70
+ end
71
+ @store.save_report(files_with_line_usage)
72
+ end
55
73
  end
56
74
  rescue => e
57
75
  @logger&.error "coverage failed to store"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
3
4
  require "singleton"
4
5
 
5
6
  module Coverband
@@ -12,7 +13,7 @@ module Coverband
12
13
  # https://github.com/livingsocial/flatfoot
13
14
  ###
14
15
  class ViewTracker
15
- attr_accessor :target, :logged_views, :views_to_record
16
+ attr_accessor :target
16
17
  attr_reader :logger, :roots, :store, :ignore_patterns
17
18
 
18
19
  def initialize(options = {})
@@ -29,8 +30,16 @@ module Coverband
29
30
  @roots = @roots.split(",") if @roots.is_a?(String)
30
31
  @one_time_timestamp = false
31
32
 
32
- @logged_views = []
33
- @views_to_record = []
33
+ @logged_views = Set.new
34
+ @views_to_record = Set.new
35
+ end
36
+
37
+ def logged_views
38
+ @logged_views.to_a
39
+ end
40
+
41
+ def views_to_record
42
+ @views_to_record.to_a
34
43
  end
35
44
 
36
45
  ###
@@ -40,8 +49,8 @@ module Coverband
40
49
  def track_views(_name, _start, _finish, _id, payload)
41
50
  if (file = payload[:identifier])
42
51
  if newly_seen_file?(file)
43
- logged_views << file
44
- views_to_record << file if track_file?(file)
52
+ @logged_views << file
53
+ @views_to_record << file if track_file?(file)
45
54
  end
46
55
  end
47
56
 
@@ -54,8 +63,8 @@ module Coverband
54
63
  return unless (layout_file = payload[:layout])
55
64
  return unless newly_seen_file?(layout_file)
56
65
 
57
- logged_views << layout_file
58
- views_to_record << layout_file if track_file?(layout_file, layout: true)
66
+ @logged_views << layout_file
67
+ @views_to_record << layout_file if track_file?(layout_file, layout: true)
59
68
  end
60
69
 
61
70
  def used_views
@@ -81,16 +90,17 @@ module Coverband
81
90
  all_views.uniq
82
91
  end
83
92
 
84
- def unused_views
85
- recently_used_views = used_views.keys
86
- unused_views = all_views.reject { |view| recently_used_views.include?(view) }
93
+ def unused_views(used_views = nil)
94
+ recently_used_views = (used_views || self.used_views).keys
95
+ unused_views = all_views - recently_used_views
87
96
  # since layouts don't include format we count them used if they match with ANY formats
88
97
  unused_views.reject { |view| view.match(/\/layouts\//) && recently_used_views.any? { |used_view| view.include?(used_view) } }
89
98
  end
90
99
 
91
100
  def as_json
101
+ used_views = self.used_views
92
102
  {
93
- unused_views: unused_views,
103
+ unused_views: unused_views(used_views),
94
104
  used_views: used_views
95
105
  }.to_json
96
106
  end
@@ -113,17 +123,17 @@ module Coverband
113
123
 
114
124
  filename = "#{@project_directory}/#{filename}"
115
125
  redis_store.hdel(tracker_key, filename)
116
- logged_views.delete(filename)
126
+ @logged_views.delete(filename)
117
127
  end
118
128
 
119
129
  def report_views_tracked
120
130
  redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists?
121
131
  @one_time_timestamp = true
122
132
  reported_time = Time.now.to_i
123
- views_to_record.each do |file|
133
+ @views_to_record.to_a.each do |file|
124
134
  redis_store.hset(tracker_key, file, reported_time)
125
135
  end
126
- self.views_to_record = []
136
+ @views_to_record.clear
127
137
  rescue => e
128
138
  # we don't want to raise errors if Coverband can't reach redis.
129
139
  # This is a nice to have not a bring the system down
@@ -137,15 +147,12 @@ module Coverband
137
147
  protected
138
148
 
139
149
  def newly_seen_file?(file)
140
- return false if logged_views.include?(file)
141
-
142
- true
150
+ !@logged_views.include?(file)
143
151
  end
144
152
 
145
153
  def track_file?(file, options = {})
146
- @ignore_patterns.none? do |pattern|
147
- file.include?(pattern)
148
- end && (file.start_with?(@project_directory) || options[:layout])
154
+ (file.start_with?(@project_directory) || options[:layout]) &&
155
+ @ignore_patterns.none? { |pattern| file.include?(pattern) }
149
156
  end
150
157
 
151
158
  private
@@ -8,8 +8,8 @@ module Coverband
8
8
  class ViewTrackerService < ViewTracker
9
9
  def report_views_tracked
10
10
  reported_time = Time.now.to_i
11
- if views_to_record.any?
12
- relative_views = views_to_record.map! do |view|
11
+ if @views_to_record.any?
12
+ relative_views = @views_to_record.map! do |view|
13
13
  roots.each do |root|
14
14
  view = view.gsub(/#{root}/, "")
15
15
  end
@@ -17,7 +17,7 @@ module Coverband
17
17
  end
18
18
  save_tracked_views(views: relative_views, reported_time: reported_time)
19
19
  end
20
- self.views_to_record = []
20
+ @views_to_record = []
21
21
  rescue => e
22
22
  # we don't want to raise errors if Coverband can't reach the service
23
23
  logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}" if Coverband.configuration.verbose || Coverband.configuration.service_dev_mode
@@ -8,7 +8,7 @@ module Coverband
8
8
  :background_reporting_enabled,
9
9
  :test_env, :web_enable_clear, :gem_details, :web_debug, :report_on_exit,
10
10
  :simulate_oneshot_lines_coverage,
11
- :view_tracker
11
+ :view_tracker, :defer_eager_loading_data
12
12
  attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id,
13
13
  :s3_secret_access_key, :password, :api_key, :service_url, :coverband_timeout, :service_dev_mode,
14
14
  :service_test_mode, :process_type, :track_views, :redis_url,
@@ -62,6 +62,7 @@ module Coverband
62
62
  @store = nil
63
63
  @background_reporting_enabled = true
64
64
  @background_reporting_sleep_seconds = nil
65
+ @defer_eager_loading_data = false
65
66
  @test_env = nil
66
67
  @web_enable_clear = false
67
68
  @track_views = true
@@ -147,7 +148,9 @@ module Coverband
147
148
  end
148
149
 
149
150
  def track_views
150
- @track_views ||= service_disabled_dev_test_env? ? false : true
151
+ return false if service_disabled_dev_test_env?
152
+
153
+ @track_views
151
154
  end
152
155
 
153
156
  ###
@@ -241,7 +244,13 @@ module Coverband
241
244
  Coverband.coverband_service? || !api_key.nil?
242
245
  end
243
246
 
247
+ def defer_eager_loading_data?
248
+ @defer_eager_loading_data
249
+ end
250
+
244
251
  def service_disabled_dev_test_env?
252
+ return false unless service?
253
+
245
254
  (coverband_env == "test" && !Coverband.configuration.service_test_mode) ||
246
255
  (coverband_env == "development" && !Coverband.configuration.service_dev_mode)
247
256
  end
@@ -31,15 +31,18 @@ module Coverband
31
31
  sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds.to_i
32
32
  @thread = Thread.new {
33
33
  loop do
34
- Coverband.report_coverage
35
- Coverband.configuration.view_tracker&.report_views_tracked
36
34
  if Coverband.configuration.reporting_wiggle
37
35
  sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds.to_i + rand(Coverband.configuration.reporting_wiggle.to_i)
38
36
  end
37
+ # NOTE: Normally as processes first start we immediately report, this causes a redis spike on deploys
38
+ # if deferred is set also sleep frst to spread load
39
+ sleep(sleep_seconds.to_i) if Coverband.configuration.defer_eager_loading_data?
40
+ Coverband.report_coverage
41
+ Coverband.configuration.view_tracker&.report_views_tracked
39
42
  if Coverband.configuration.verbose
40
43
  logger.debug("Coverband: background reporting coverage (#{Coverband.configuration.store.type}). Sleeping #{sleep_seconds}s")
41
44
  end
42
- sleep(sleep_seconds.to_i)
45
+ sleep(sleep_seconds.to_i) unless Coverband.configuration.defer_eager_loading_data?
43
46
  end
44
47
  }
45
48
  end
@@ -15,7 +15,7 @@ module Coverband
15
15
  scov_style_report = get_current_scov_data_imp(store, all_roots)
16
16
 
17
17
  # These are extremelhy verbose but useful during coverband development, not generally for users
18
- # Only avaiable by uncommenting this mode is never released
18
+ # Only available by uncommenting this mode is never released
19
19
  # if Coverband.configuration.verbose
20
20
  # # msg = "report:\n #{scov_style_report.inspect}"
21
21
  # # Coverband.configuration.logger.debug msg
@@ -124,7 +124,7 @@ module Coverband
124
124
  Coverband.configuration.store.clear!
125
125
  notice = "coverband coverage cleared"
126
126
  else
127
- notice = "web_enable_clear isnt enabled in your configuration"
127
+ notice = "web_enable_clear isn't enabled in your configuration"
128
128
  end
129
129
  [301, {"Location" => "#{base_path}?notice=#{notice}"}, []]
130
130
  end
@@ -135,7 +135,7 @@ module Coverband
135
135
  Coverband.configuration.store.clear_file!(filename)
136
136
  notice = "coverage for file #{filename} cleared"
137
137
  else
138
- notice = "web_enable_clear isnt enabled in your configuration"
138
+ notice = "web_enable_clear isn't enabled in your configuration"
139
139
  end
140
140
  [301, {"Location" => "#{base_path}?notice=#{notice}"}, []]
141
141
  end
@@ -146,7 +146,7 @@ module Coverband
146
146
  tracker.reset_recordings
147
147
  notice = "view tracking reset"
148
148
  else
149
- notice = "web_enable_clear isnt enabled in your configuration"
149
+ notice = "web_enable_clear isn't enabled in your configuration"
150
150
  end
151
151
  [301, {"Location" => "#{base_path}/view_tracker?notice=#{notice}"}, []]
152
152
  end
@@ -158,7 +158,7 @@ module Coverband
158
158
  tracker.clear_file!(filename)
159
159
  notice = "coverage for file #{filename} cleared"
160
160
  else
161
- notice = "web_enable_clear isnt enabled in your configuration"
161
+ notice = "web_enable_clear isn't enabled in your configuration"
162
162
  end
163
163
  [301, {"Location" => "#{base_path}/view_tracker?notice=#{notice}"}, []]
164
164
  end
@@ -37,7 +37,7 @@ module Coverband
37
37
 
38
38
  Coverband.configuration.view_tracker = COVERBAND_VIEW_TRACKER
39
39
 
40
- ActiveSupport::Notifications.subscribe(/render_partial.action_view|render_template.action_view/) do |name, start, finish, id, payload|
40
+ ActiveSupport::Notifications.subscribe(/render_(template|partial|collection).action_view/) do |name, start, finish, id, payload|
41
41
  COVERBAND_VIEW_TRACKER.track_views(name, start, finish, id, payload) unless name.include?("!")
42
42
  end
43
43
  end
@@ -55,7 +55,7 @@ module Coverband
55
55
  Dir[tracked_files].each do |file|
56
56
  absolute = File.expand_path(file)
57
57
  result[absolute] ||= {
58
- "data" => Array.new(File.foreach(absolute).count) { 0 },
58
+ "data" => [],
59
59
  "never_loaded" => true
60
60
  }
61
61
  end
@@ -101,7 +101,7 @@ module Coverband
101
101
  @last_updated_at = Time.at(file_data["last_updated_at"]) if file_data["last_updated_at"]
102
102
  @never_loaded = file_data["never_loaded"] || false
103
103
  else
104
- # TODO: Deprecate this code path this was backwards compatability from 3-4
104
+ # TODO: Deprecate this code path this was backwards compatibility from 3-4
105
105
  @coverage = file_data
106
106
  @first_updated_at = NOT_AVAILABLE
107
107
  @last_updated_at = NOT_AVAILABLE
@@ -139,7 +139,7 @@ module Coverband
139
139
  coverage_exceeding_source_warn if coverage.size > src.size
140
140
 
141
141
  lines = src.map.with_index(1) { |src, i|
142
- Coverband::Utils::SourceFile::Line.new(src, i, coverage[i - 1])
142
+ Coverband::Utils::SourceFile::Line.new(src, i, never_loaded ? 0 : coverage[i - 1])
143
143
  }
144
144
 
145
145
  process_skipped_lines(lines)
@@ -5,5 +5,5 @@
5
5
  # use format "4.2.1.rc.1" ~> 4.2.1.rc to prerelease versions like v4.2.1.rc.2 and v4.2.1.rc.3
6
6
  ###
7
7
  module Coverband
8
- VERSION = '5.1.1'
8
+ VERSION = '5.2.1.rc.1'
9
9
  end
@@ -103,7 +103,7 @@ var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/<
103
103
  return this.rel;
104
104
  },
105
105
  href: function() {
106
- // using this.href would give the absolute url, when the href may have been inteded as a selector (e.g. '#container')
106
+ // using this.href would give the absolute url, when the href may have been intedned as a selector (e.g. '#container')
107
107
  return $(this).attr('href');
108
108
  },
109
109
  title: function() {
@@ -397,7 +397,7 @@ var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/<
397
397
  loadedHeight = $loaded.outerHeight(true);
398
398
  loadedWidth = $loaded.outerWidth(true);
399
399
 
400
- // Opens inital empty Colorbox prior to content being loaded.
400
+ // Opens initial empty Colorbox prior to content being loaded.
401
401
  var initialWidth = setSize(settings.get('initialWidth'), 'x');
402
402
  var initialHeight = setSize(settings.get('initialHeight'), 'y');
403
403
  var maxWidth = settings.get('maxWidth');
@@ -983,7 +983,7 @@ var hljs=new function(){function l(o){return o.replace(/&/gm,"&amp;").replace(/<
983
983
  return;
984
984
  }
985
985
 
986
- // A small pause because some browsers will occassionaly report a
986
+ // A small pause because some browsers will occasionally report a
987
987
  // img.width and img.height of zero immediately after the img.onload fires
988
988
  setTimeout(function(){
989
989
  var percent;
@@ -1236,7 +1236,7 @@ u;this.oApi._fnAddColumn=y;this.oApi._fnColumnOptions=C;this.oApi._fnAddData=w;t
1236
1236
  Q;this.oApi._fnFilterCreateSearch=fa;this.oApi._fnDataToSearch=ga;this.oApi._fnSort=O;this.oApi._fnSortAttachListener=$;this.oApi._fnSortingClasses=W;this.oApi._fnFeatureHtmlPaginate=wa;this.oApi._fnPageChange=Ba;this.oApi._fnFeatureHtmlInfo=va;this.oApi._fnUpdateInfo=Ca;this.oApi._fnFeatureHtmlLength=ra;this.oApi._fnFeatureHtmlProcessing=ta;this.oApi._fnProcessingDisplay=K;this.oApi._fnVisibleToColumnIndex=da;this.oApi._fnColumnIndexToVisible=N;this.oApi._fnNodeToDataIndex=R;this.oApi._fnVisbleColumns=
1237
1237
  T;this.oApi._fnCalculateEnd=F;this.oApi._fnConvertToWidth=Da;this.oApi._fnCalculateColumnWidths=ea;this.oApi._fnScrollingWidthAdjust=ia;this.oApi._fnGetWidestNode=Ea;this.oApi._fnGetMaxLenString=Fa;this.oApi._fnStringToCss=v;this.oApi._fnArrayCmp=La;this.oApi._fnDetectType=Z;this.oApi._fnSettingsFromNode=B;this.oApi._fnGetDataMaster=V;this.oApi._fnGetTrNodes=S;this.oApi._fnGetTdNodes=X;this.oApi._fnEscapeRegex=ha;this.oApi._fnDeleteIndex=ja;this.oApi._fnReOrderIndex=qa;this.oApi._fnColumnOrdering=
1238
1238
  aa;this.oApi._fnLog=J;this.oApi._fnClearTable=ba;this.oApi._fnSaveState=Ga;this.oApi._fnLoadState=Ia;this.oApi._fnCreateCookie=Ha;this.oApi._fnReadCookie=ka;this.oApi._fnGetUniqueThs=ca;this.oApi._fnScrollBarWidth=Ja;this.oApi._fnApplyToChildren=M;this.oApi._fnMap=n;var Ka=this;return this.each(function(){var a=0,b,c,d,f;a=0;for(b=E.length;a<b;a++){if(E[a].nTable==this)if(typeof g=="undefined"||typeof g.bRetrieve!="undefined"&&g.bRetrieve===true)return E[a].oInstance;else if(typeof g.bDestroy!="undefined"&&
1239
- g.bDestroy===true){E[a].oInstance.fnDestroy();break}else{J(E[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, please pass either no arguments to the dataTable() function, or set bRetrieve to true. Alternatively, to destory the old table and create a new one, set bDestroy to true (note that a lot of changes to the configuration can be made through the API which is usually much faster).");return}if(E[a].sTableId!==""&&E[a].sTableId==this.getAttribute("id")){E.splice(a,
1239
+ g.bDestroy===true){E[a].oInstance.fnDestroy();break}else{J(E[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, please pass either no arguments to the dataTable() function, or set bRetrieve to true. Alternatively, to destroy the old table and create a new one, set bDestroy to true (note that a lot of changes to the configuration can be made through the API which is usually much faster).");return}if(E[a].sTableId!==""&&E[a].sTableId==this.getAttribute("id")){E.splice(a,
1240
1240
  1);break}}var e=new l;E.push(e);var i=false,h=false;a=this.getAttribute("id");if(a!==null){e.sTableId=a;e.sInstance=a}else e.sInstance=m._oExternConfig.iNextUnique++;e.oInstance=Ka;e.nTable=this;e.oApi=Ka.oApi;if(typeof g!="undefined"&&g!==null){e.oInit=g;n(e.oFeatures,g,"bPaginate");n(e.oFeatures,g,"bLengthChange");n(e.oFeatures,g,"bFilter");n(e.oFeatures,g,"bSort");n(e.oFeatures,g,"bInfo");n(e.oFeatures,g,"bProcessing");n(e.oFeatures,g,"bAutoWidth");n(e.oFeatures,g,"bSortClasses");n(e.oFeatures,
1241
1241
  g,"bServerSide");n(e.oScroll,g,"sScrollX","sX");n(e.oScroll,g,"sScrollXInner","sXInner");n(e.oScroll,g,"sScrollY","sY");n(e.oScroll,g,"bScrollCollapse","bCollapse");n(e,g,"asStripClasses");n(e,g,"fnRowCallback");n(e,g,"fnHeaderCallback");n(e,g,"fnFooterCallback");n(e,g,"fnInitComplete");n(e,g,"fnServerData");n(e,g,"fnFormatNumber");n(e,g,"aaSorting");n(e,g,"aaSortingFixed");n(e,g,"aLengthMenu");n(e,g,"sPaginationType");n(e,g,"sAjaxSource");n(e,g,"iCookieDuration");n(e,g,"sCookiePrefix");n(e,g,"sDom");
1242
1242
  n(e,g,"oSearch","oPreviousSearch");n(e,g,"aoSearchCols","aoPreSearchCols");n(e,g,"iDisplayLength","_iDisplayLength");n(e,g,"bJQueryUI","bJUI");typeof g.fnDrawCallback=="function"&&e.aoDrawCallback.push({fn:g.fnDrawCallback,sName:"user"});e.oFeatures.bServerSide&&e.oFeatures.bSort&&e.oFeatures.bSortClasses&&e.aoDrawCallback.push({fn:W,sName:"server_side_sort_classes"});if(typeof g.bJQueryUI!="undefined"&&g.bJQueryUI){e.oClasses=m.oJUIClasses;if(typeof g.sDom=="undefined")e.sDom='<"H"lfr>t<"F"ip>'}if(e.oScroll.sX!==
@@ -10,7 +10,7 @@ class BaseTest < Minitest::Test
10
10
  Coverband.configure do |config|
11
11
  config.root = Dir.pwd
12
12
  config.root_paths = ["/app_path/"]
13
- config.ignore = ["config/envionments"]
13
+ config.ignore = ["config/environments"]
14
14
  config.reporter = "std_out"
15
15
  config.store = Coverband::Adapters::RedisStore.new(Coverband::Test.redis, redis_namespace: "coverband_test")
16
16
  end
@@ -18,7 +18,7 @@ class BaseTest < Minitest::Test
18
18
 
19
19
  test "ignore works with equal" do
20
20
  Coverband::Collectors::Coverage.instance.reset_instance
21
- expected = ["vendor/", ".erb$", ".slim$", "/tmp", "internal:prelude", "db/schema.rb", "config/envionments"]
21
+ expected = ["vendor/", ".erb$", ".slim$", "/tmp", "internal:prelude", "db/schema.rb", "config/environments"]
22
22
  assert_equal expected, Coverband.configuration.ignore
23
23
  end
24
24
 
@@ -33,7 +33,7 @@ class BaseTest < Minitest::Test
33
33
  "/tmp",
34
34
  "internal:prelude",
35
35
  "db/schema.rb",
36
- "config/envionments",
36
+ "config/environments",
37
37
  "config/initializers"]
38
38
  assert_equal expected, Coverband.configuration.ignore
39
39
  end
@@ -47,7 +47,7 @@ class BaseTest < Minitest::Test
47
47
  Coverband::Collectors::Coverage.instance.reset_instance
48
48
  current_paths = Coverband.configuration.root_paths.dup
49
49
  # verify previous bug fix
50
- # it would extend the root_paths instance variable on each invokation
50
+ # it would extend the root_paths instance variable on each invocation
51
51
  Coverband.configuration.all_root_paths
52
52
  Coverband.configuration.all_root_paths
53
53
  assert_equal current_paths, Coverband.configuration.root_paths
@@ -103,7 +103,7 @@ class BaseTest < Minitest::Test
103
103
  end
104
104
  end
105
105
 
106
- test "store doesnt raises when api key and redis_url" do
106
+ test "store doesn't raises when api key and redis_url" do
107
107
  Coverband::Collectors::Coverage.instance.reset_instance
108
108
  Coverband.configuration.reset
109
109
  Coverband.configure do |config|
@@ -58,7 +58,7 @@ class RailsFullStackTest < Minitest::Test
58
58
 
59
59
  # we don't want this to run during our standard test suite
60
60
  # as the below profiler changes the runtime
61
- # and shold only be included for isolated processes
61
+ # and should only be included for isolated processes
62
62
  begin
63
63
  require "memory_profiler"
64
64
 
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("../test_helper", File.dirname(__FILE__))
4
+ require "rack"
5
+
6
+ class FullStackDeferredEagerTest < Minitest::Test
7
+ REDIS_STORAGE_FORMAT_VERSION = Coverband::Adapters::RedisStore::REDIS_STORAGE_FORMAT_VERSION
8
+ TEST_RACK_APP = "../fake_app/basic_rack.rb"
9
+
10
+ def setup
11
+ super
12
+ Coverband::Collectors::Coverage.instance.reset_instance
13
+ Coverband.configure do |config|
14
+ config.background_reporting_enabled = false
15
+ config.track_gems = true
16
+ config.defer_eager_loading_data = true
17
+ end
18
+ Coverband.start
19
+ Coverband::Collectors::Coverage.instance.eager_loading!
20
+ @rack_file = require_unique_file "fake_app/basic_rack.rb"
21
+ Coverband.report_coverage
22
+ Coverband::Collectors::Coverage.instance.runtime!
23
+ end
24
+
25
+ test "call app" do
26
+ # eager loaded class coverage starts empty
27
+ Coverband.eager_loading_coverage!
28
+ expected = {}
29
+ assert_equal expected, Coverband.configuration.store.coverage
30
+
31
+ Coverband::Collectors::Coverage.instance.runtime!
32
+ request = Rack::MockRequest.env_for("/anything.json")
33
+ middleware = Coverband::BackgroundMiddleware.new(fake_app_with_lines)
34
+ results = middleware.call(request)
35
+ assert_equal "Hello Rack!", results.last
36
+ Coverband.report_coverage
37
+ expected = [nil, nil, 0, nil, 0, 0, 1, nil, nil]
38
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]["data"]
39
+
40
+ # eager loaded class coverage is saved at first normal coverage report
41
+ Coverband.eager_loading_coverage!
42
+ expected = [nil, nil, 1, nil, 1, 1, 0, nil, nil]
43
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]["data"]
44
+ end
45
+
46
+ private
47
+
48
+ def fake_app_with_lines
49
+ @fake_app_with_lines ||= ::HelloWorld.new
50
+ end
51
+ end
data/views/file_list.erb CHANGED
@@ -22,8 +22,8 @@
22
22
  <thead>
23
23
  <tr>
24
24
  <th title="The source file name">File</th>
25
- <th title="Percentage of relavent lines covered (load & runtime)">% covered</th>
26
- <th title="Runtime Percentage of relavent lines covered">% runtime</th>
25
+ <th title="Percentage of relevant lines covered (load & runtime)">% covered</th>
26
+ <th title="Runtime Percentage of relevant lines covered">% runtime</th>
27
27
  <th title="The total line number count for the file">Lines</th>
28
28
  <th title="Line number count excluding comments, whitespace, etc...">Relevant Lines</th>
29
29
  <th title="The number of lines covered (load & runtime)">Lines covered</th>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coverband
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.1
4
+ version: 5.2.1.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Mayer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-08-02 00:00:00.000000000 Z
12
+ date: 2022-01-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: benchmark-ips
@@ -272,6 +272,7 @@ extra_rdoc_files: []
272
272
  files:
273
273
  - ".github/ISSUE_TEMPLATE/bug_report.md"
274
274
  - ".github/ISSUE_TEMPLATE/feature_request.md"
275
+ - ".github/workflows/diagram.yml"
275
276
  - ".github/workflows/main.yml"
276
277
  - ".gitignore"
277
278
  - ".jrubyrc"
@@ -288,6 +289,7 @@ files:
288
289
  - changes.md
289
290
  - config.ru
290
291
  - coverband.gemspec
292
+ - diagram.svg
291
293
  - lib/alternative_coverband_patch.rb
292
294
  - lib/coverband.rb
293
295
  - lib/coverband/adapters/base.rb
@@ -416,6 +418,7 @@ files:
416
418
  - test/forked/rails_full_stack_views_test.rb
417
419
  - test/forked/rails_rake_full_stack_test.rb
418
420
  - test/forked/rails_view_tracker_stack_test.rb
421
+ - test/integration/full_stack_deferred_eager_test.rb
419
422
  - test/integration/full_stack_test.rb
420
423
  - test/jruby_check.rb
421
424
  - test/rails4_dummy/Rakefile
@@ -475,7 +478,12 @@ files:
475
478
  homepage: https://github.com/danmayer/coverband
476
479
  licenses:
477
480
  - MIT
478
- metadata: {}
481
+ metadata:
482
+ homepage_uri: https://github.com/danmayer/coverband
483
+ bug_tracker_uri: https://github.com/danmayer/coverband/issues
484
+ documentation_uri: https://github.com/danmayer/coverband
485
+ changelog_uri: https://github.com/danmayer/coverband/blob/main/changes.md
486
+ source_code_uri: https://github.com/danmayer/coverband
479
487
  post_install_message:
480
488
  rdoc_options: []
481
489
  require_paths:
@@ -487,11 +495,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
487
495
  version: '2.3'
488
496
  required_rubygems_version: !ruby/object:Gem::Requirement
489
497
  requirements:
490
- - - ">="
498
+ - - ">"
491
499
  - !ruby/object:Gem::Version
492
- version: '0'
500
+ version: 1.3.1
493
501
  requirements: []
494
- rubygems_version: 3.2.3
502
+ rubygems_version: 3.0.3
495
503
  signing_key:
496
504
  specification_version: 4
497
505
  summary: Rack middleware to measure production code usage (LOC runtime usage)
@@ -552,6 +560,7 @@ test_files:
552
560
  - test/forked/rails_full_stack_views_test.rb
553
561
  - test/forked/rails_rake_full_stack_test.rb
554
562
  - test/forked/rails_view_tracker_stack_test.rb
563
+ - test/integration/full_stack_deferred_eager_test.rb
555
564
  - test/integration/full_stack_test.rb
556
565
  - test/jruby_check.rb
557
566
  - test/rails4_dummy/Rakefile