Merge mozilla-central to mozilla-beta. a=merge l10n=merge.
authorCosmin Sabou <csabou@mozilla.com>
Mon, 10 Dec 2018 15:37:28 +0200
changeset 508919 89eaae012b3087393772a5c6993bd5b31f6e2632
parent 508721 a7da8d1e4527ab089e6e9d42ffc58cfcfe895204 (current diff)
parent 508918 3386ff76878d83496bb822d09115c77472808b53 (diff)
child 508920 5800a9276ff0cb69a6ee54fa1b8de623c6a0f2dd
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone65.0
Merge mozilla-central to mozilla-beta. a=merge l10n=merge.
browser/components/places/tests/browser/browser_library_warnOnOpen.js
devtools/shared/adb/adb-devices-registry.js
devtools/shared/adb/adb-scanner.js
devtools/shared/adb/addon-aware-adb-scanner.js
devtools/shared/adb/test/test_addon-aware-adb-scanner.js
gfx/wr/webrender/src/prim_store.rs
testing/web-platform/meta/streams/readable-streams/bad-underlying-sources.dedicatedworker.html.ini
testing/web-platform/meta/streams/readable-streams/bad-underlying-sources.html.ini
testing/web-platform/meta/streams/readable-streams/bad-underlying-sources.serviceworker.https.html.ini
testing/web-platform/meta/streams/readable-streams/bad-underlying-sources.sharedworker.html.ini
testing/web-platform/meta/streams/readable-streams/constructor.dedicatedworker.html.ini
testing/web-platform/meta/streams/readable-streams/constructor.html.ini
testing/web-platform/meta/streams/readable-streams/constructor.serviceworker.https.html.ini
testing/web-platform/meta/streams/readable-streams/constructor.sharedworker.html.ini
testing/web-platform/meta/streams/readable-streams/garbage-collection.dedicatedworker.html.ini
testing/web-platform/meta/streams/readable-streams/garbage-collection.html.ini
testing/web-platform/meta/streams/readable-streams/garbage-collection.serviceworker.https.html.ini
testing/web-platform/meta/streams/readable-streams/garbage-collection.sharedworker.html.ini
third_party/rust/darling_core/src/ast.rs
third_party/rust/darling_core/src/codegen/fmi_impl.rs
third_party/rust/darling_core/src/from_meta_item.rs
third_party/rust/darling_core/src/macros.rs
third_party/rust/darling_core/src/options/from_meta_item.rs
third_party/rust/synstructure-0.8.1/.cargo-checksum.json
third_party/rust/synstructure-0.8.1/Cargo.toml
third_party/rust/synstructure-0.8.1/LICENSE
third_party/rust/synstructure-0.8.1/README.md
third_party/rust/synstructure-0.8.1/src/lib.rs
third_party/rust/synstructure-0.8.1/src/macros.rs
toolkit/themes/linux/mozapps/extensions/heart.png
toolkit/themes/osx/mozapps/extensions/heart.png
toolkit/themes/windows/mozapps/extensions/heart.png
--- a/.clang-format
+++ b/.clang-format
@@ -5,20 +5,22 @@ MacroBlockBegin: "^\
 JS_BEGIN_MACRO|\
 NS_INTERFACE_MAP_BEGIN|\
 NS_INTERFACE_TABLE_HEAD|\
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION|\
 NS_IMPL_CYCLE_COLLECTION_.*_BEGIN|\
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED|\
 NS_INTERFACE_TABLE_BEGIN|\
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED|\
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED$"
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED|\
+NS_QUERYFRAME_HEAD$"
 MacroBlockEnd: "^\
 JS_END_MACRO|\
 NS_INTERFACE_MAP_END|\
 NS_IMPL_CYCLE_COLLECTION_.*_END|\
 NS_INTERFACE_TABLE_END|\
 NS_INTERFACE_TABLE_TAIL.*|\
 NS_INTERFACE_MAP_END_.*|\
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END_INHERITED|\
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED$"
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED|\
+NS_QUERYFRAME_TAIL.*$"
 
 SortIncludes: false
--- a/.eslintignore
+++ b/.eslintignore
@@ -26,17 +26,16 @@ gfx/tests/chrome/**
 gfx/tests/mochitest/**
 image/**
 layout/**
 modules/**
 netwerk/cookie/test/browser/**
 netwerk/test/browser/**
 netwerk/test/mochitests/**
 netwerk/test/unit*/**
-parser/**
 tools/update-packaging/**
 uriloader/exthandler/**
 uriloader/exthandler/tests/mochitest/**
 widget/headless/tests/**
 widget/tests/**
 
 # We currently have no js files in these directories, so we ignore them by
 # default to aid ESLint's performance.
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -176,17 +176,17 @@ dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bench-collections-gtest"
 version = "0.1.0"
 dependencies = [
- "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "binary-space-partition"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -672,42 +672,43 @@ source = "registry+https://github.com/ru
 dependencies = [
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "darling"
-version = "0.4.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "darling_macro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "darling_core 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "darling_macro 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "darling_core"
-version = "0.4.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "darling_macro"
-version = "0.4.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "darling_core 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "devd-rs"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -890,17 +891,17 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "fnv"
-version = "1.0.5"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "foreign-types"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1097,17 +1098,17 @@ dependencies = [
 
 [[package]]
 name = "h2"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "http 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1120,17 +1121,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "http"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "httparse"
 version = "1.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1427,19 +1428,19 @@ dependencies = [
  "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "malloc_size_of_derive"
 version = "0.0.1"
 dependencies = [
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "matches"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2403,20 +2404,21 @@ dependencies = [
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "style_derive"
 version = "0.0.1"
 dependencies = [
- "darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "darling 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2476,27 +2478,16 @@ source = "registry+https://github.com/ru
 dependencies = [
  "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "synstructure"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "synstructure"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3177,19 +3168,19 @@ dependencies = [
 "checksum cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "730363a45c4e248d4f21d3e5c1156d1a9cdec0855056c0d9539e814bc59865c3"
 "checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805"
 "checksum cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea"
 "checksum cstr-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0472c17c83d3ec1af32fb6ee2b3ad56ae0b6e69355d63d1d30602055c34324a8"
 "checksum cubeb 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a3502aafa1bf95c524f65d2ba46d8741700c6a8a9543ea52c6da3d8b69a2896"
 "checksum cubeb-backend 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcac95519416d9ec814db2dc40e6293e7da25b906023d93f48b87f0587ab138"
 "checksum cubeb-core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37f7b20f757a4e4b6aa28863236551bff77682dc6db192eba15af615492b5445"
 "checksum cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "653b9e245d35dbe2a2da7c4586275cee75ff656ddeb02d4a73b4afdfa6d67502"
-"checksum darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a78af487e4eb8f4421a1770687b328af6bb4494ca93435210678c6eea875c11"
-"checksum darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b315f49c7b6db3708bca6e6913c194581a44ec619b7a39e131d4dd63733a3698"
-"checksum darling_macro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb69a38fdeaeaf3db712e1df170de67ee9dfc24fb88ca3e9d21e703ec25a4d8e"
+"checksum darling 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f000e7b03a0083a30e1f10b1428a530849c21e72b338fa76869b5dbc4b045bf"
+"checksum darling_core 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "86bc5ce438f4b703755d12f59bbf0a16c642766d4534e922db47569dbdd0b998"
+"checksum darling_macro 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9973050ba46be2a2935a7b316147f41a808ac604b8f0fef6eba77fd47a89daeb"
 "checksum devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
 "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
 "checksum dwrote 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b46afd0d0bbbea88fc083ea293e40865e26a75ec9d38cf5d05a23ac3e2ffe02"
@@ -3200,17 +3191,17 @@ dependencies = [
 "checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "600657e7e5c03bfbccdc68721bc3b5abcb761553973387124eae9c9e4f02c210"
 "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
 "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 "checksum fixedbitset 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "85cb8fec437468d86dc7c83ca7cfc933341d561873275f22dd5eedefa63a6478"
 "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
-"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
+"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
 "checksum freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b659e75b7a7338fe75afd7f909fc2b71937845cffb6ebe54ba2e50f13d8e903d"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
 "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
@@ -3341,17 +3332,16 @@ dependencies = [
 "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
 "checksum syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4b5274d4a0a3d2749d5c158dc64d3403e60554dc61194648787ada5212473d"
 "checksum syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)" = "455a6ec9b368f8c479b0ae5494d13b22dc00990d2f00d68c9dc6a2dc4f17f210"
 "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
-"checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049"
 "checksum target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9"
 "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
 "checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
 "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
 "checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
--- a/accessible/android/SessionAccessibility.cpp
+++ b/accessible/android/SessionAccessibility.cpp
@@ -366,19 +366,25 @@ void SessionAccessibility::ReplaceFocusP
 }
 
 void SessionAccessibility::UpdateCachedBounds(
     const nsTArray<AccessibleWrap*>& aAccessibles,
     const nsTArray<BatchData>& aData) {
   auto infos = jni::ObjectArray::New<java::GeckoBundle>(aAccessibles.Length());
   for (size_t i = 0; i < aAccessibles.Length(); i++) {
     AccessibleWrap* acc = aAccessibles.ElementAt(i);
+    if (!acc) {
+      MOZ_ASSERT_UNREACHABLE("Updated accessible is gone.");
+      continue;
+    }
+
     if (aData.Length() == aAccessibles.Length()) {
       const BatchData& data = aData.ElementAt(i);
-      auto bundle = acc->ToSmallBundle(data.State(), data.Bounds(), data.ActionCount());
+      auto bundle =
+          acc->ToSmallBundle(data.State(), data.Bounds(), data.ActionCount());
       infos->SetElement(i, bundle);
     } else {
       infos->SetElement(i, acc->ToSmallBundle());
     }
   }
 
   mSessionAccessibility->UpdateCachedBounds(infos);
 }
--- a/accessible/base/nsAccessiblePivot.cpp
+++ b/accessible/base/nsAccessiblePivot.cpp
@@ -381,25 +381,25 @@ nsAccessiblePivot::MoveNextByText(TextBo
     tempStart = potentialStart > tempStart ? potentialStart : currentEnd;
 
     // The offset range we've obtained might have embedded characters in it,
     // limit the range to the start of the first occurrence of an embedded
     // character.
     Accessible* childAtOffset = nullptr;
     for (int32_t i = tempStart; i < tempEnd; i++) {
       childAtOffset = text->GetChildAtOffset(i);
-      if (childAtOffset && !childAtOffset->IsText()) {
+      if (childAtOffset && childAtOffset->IsHyperText()) {
         tempEnd = i;
         break;
       }
     }
     // If there's an embedded character at the very start of the range, we
     // instead want to traverse into it. So restart the movement with
     // the child as the starting point.
-    if (childAtOffset && !childAtOffset->IsText() &&
+    if (childAtOffset && childAtOffset->IsHyperText() &&
         tempStart == static_cast<int32_t>(childAtOffset->StartOffset())) {
       tempPosition = childAtOffset;
       tempStart = tempEnd = -1;
       continue;
     }
 
     *aResult = true;
 
--- a/accessible/tests/mochitest/pivot/doc_virtualcursor_text.html
+++ b/accessible/tests/mochitest/pivot/doc_virtualcursor_text.html
@@ -20,11 +20,14 @@
     <tr>
       <td id="cell-3">and wizards</td>
       <td id="cell-4">really exist.</td>
     </tr>
   </table>
   <div id="section-3">Endless fun!</div>
   <p id="paragraph-3">Objects<a id="p3-link-1" href="#">adjacent</a>to <a id="p3-link-2" href="#">each</a><a id="p3-link-3" href="#">other</a> should be separate.</p>
   <p id="paragraph-4">Hello <strong>real</strong><a href="#"> world</p>
+  <a href="#" id="image-desc-link">
+    <img src="../moz.png" alt="">Hello
+  </a>
   <div id="end-block">End!</div>
 </body>
 </html>
--- a/accessible/tests/mochitest/pivot/test_virtualcursor_text.html
+++ b/accessible/tests/mochitest/pivot/test_virtualcursor_text.html
@@ -231,16 +231,23 @@
       gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [20, 28],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("section-1")).lastChild));
       gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [20, 28],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
 
+      gQueue.push(new setVCPosInvoker(docAcc, null, null,
+                                      getAccessible(doc.getElementById("image-desc-link"))));
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [0, 1],
+                  getAccessible(doc.getElementById("image-desc-link"), nsIAccessibleText)));
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [1, 2],
+                  getAccessible(doc.getElementById("image-desc-link"), nsIAccessibleText)));
+
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(function() {
       /* We open a new browser because we need to test with a top-level content
          document. */
       openBrowserWindow(
new file mode 100644
--- /dev/null
+++ b/browser/actors/SearchTelemetryChild.jsm
@@ -0,0 +1,165 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+var EXPORTED_SYMBOLS = ["SearchTelemetryChild"];
+
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const SHARED_DATA_KEY = "SearchTelemetry:ProviderInfo";
+
+/**
+ * SearchProviders looks after keeping track of the search provider information
+ * received from the main process.
+ *
+ * It is separate to SearchTelemetryChild so that it is not constructed for each
+ * tab, but once per process.
+ */
+class SearchProviders {
+  constructor() {
+    this._searchProviderInfo = null;
+    Services.cpmm.sharedData.addEventListener("change", this);
+  }
+
+  /**
+   * Gets the search provider information for any provider with advert information.
+   * If there is nothing in the cache, it will obtain it from shared data.
+   *
+   * @returns {object} Returns the search provider information. @see SearchTelemetry.jsm
+   */
+  get info() {
+    if (this._searchProviderInfo) {
+      return this._searchProviderInfo;
+    }
+
+    this._searchProviderInfo = Services.cpmm.sharedData.get(SHARED_DATA_KEY);
+
+    if (!this._searchProviderInfo) {
+      return null;
+    }
+
+    // Filter-out non-ad providers so that we're not trying to match against
+    // those unnecessarily.
+    for (let [providerName, info] of Object.entries(this._searchProviderInfo)) {
+      if (!("extraAdServersRegexps" in info)) {
+        delete this._searchProviderInfo[providerName];
+      }
+    }
+
+    return this._searchProviderInfo;
+  }
+
+  /**
+   * Handles events received from sharedData notifications.
+   *
+   * @param {object} event The event details.
+   */
+  handleEvent(event) {
+    switch (event.type) {
+      case "change": {
+        if (event.changedKeys.includes(SHARED_DATA_KEY)) {
+          // Just null out the provider information for now, we'll fetch it next
+          // time we need it.
+          this._searchProviderInfo = null;
+        }
+        break;
+      }
+    }
+  }
+}
+
+const searchProviders = new SearchProviders();
+
+/**
+ * SearchTelemetryChild monitors for pages that are partner searches, and
+ * looks through them to find links which looks like adverts and sends back
+ * a notification to SearchTelemetry for possible telemetry reporting.
+ *
+ * Only the partner details and the fact that at least one ad was found on the
+ * page are returned to SearchTelemetry. If no ads are found, no notification is
+ * given.
+ */
+class SearchTelemetryChild extends ActorChild {
+  /**
+   * Determines if there is a provider that matches the supplied URL and returns
+   * the information associated with that provider.
+   *
+   * @param {string} url The url to check
+   * @returns {array|null} Returns null if there's no match, otherwise an array
+   *   of provider name and the provider information.
+   */
+  _getProviderInfoForUrl(url) {
+    return Object.entries(searchProviders.info || []).find(
+      ([_, info]) => info.regexp.test(url)
+    );
+  }
+
+  /**
+   * Checks to see if the page is a partner and has an ad link within it. If so,
+   * it will notify SearchTelemetry.
+   *
+   * @param {object} doc The document object to check.
+   */
+  _checkForAdLink(doc) {
+    let providerInfo = this._getProviderInfoForUrl(doc.documentURI);
+    if (!providerInfo) {
+      return;
+    }
+
+    let regexps = providerInfo[1].extraAdServersRegexps;
+
+    let anchors = doc.getElementsByTagName("a");
+    let hasAds = false;
+    for (let anchor of anchors) {
+      if (!anchor.href) {
+        continue;
+      }
+      for (let regexp of regexps) {
+        if (regexp.test(anchor.href)) {
+          hasAds = true;
+          break;
+        }
+      }
+      if (hasAds) {
+        break;
+      }
+    }
+    if (hasAds) {
+      this.sendAsyncMessage("SearchTelemetry:PageInfo", {
+        hasAds: true,
+        url: doc.documentURI,
+      });
+    }
+  }
+
+  /**
+   * Handles events received from the actor child notifications.
+   *
+   * @param {object} event The event details.
+   */
+  handleEvent(event) {
+    // We are only interested in the top-level frame.
+    if (event.target.ownerGlobal != this.content) {
+      return;
+    }
+
+    switch (event.type) {
+      case "pageshow": {
+        // If a page is loaded from the bfcache, we won't get a "DOMContentLoaded"
+        // event, so we need to rely on "pageshow" in this case. Note: we do this
+        // so that we remain consistent with the *.in-content:sap* count for the
+        // SEARCH_COUNTS histogram.
+        if (event.persisted) {
+          this._checkForAdLink(this.content.document);
+        }
+        break;
+      }
+      case "DOMContentLoaded": {
+        this._checkForAdLink(this.content.document);
+        break;
+      }
+    }
+  }
+}
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -38,11 +38,12 @@ FINAL_TARGET_FILES.actors += [
     'LightWeightThemeInstallChild.jsm',
     'LinkHandlerChild.jsm',
     'NetErrorChild.jsm',
     'OfflineAppsChild.jsm',
     'PageInfoChild.jsm',
     'PageMetadataChild.jsm',
     'PageStyleChild.jsm',
     'PluginChild.jsm',
+    'SearchTelemetryChild.jsm',
     'URIFixupChild.jsm',
     'WebRTCChild.jsm',
 ]
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1270,23 +1270,28 @@ pref("browser.newtabpage.activity-stream
 #ifdef EARLY_BETA_OR_EARLIER
 pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", true);
 #else
 pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", false);
 #endif
 
 // ASRouter provider configuration
 #if defined(NIGHTLY_BUILD)
-pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":true,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
 pref("browser.newtabpage.activity-stream.asrouter.providers.cfr", "{\"id\":\"cfr\",\"enabled\":true,\"type\":\"local\",\"localProvider\":\"CFRMessageProvider\",\"frequency\":{\"custom\":[{\"period\":\"daily\",\"cap\":1}]}}");
 #else
-pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":false,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
 pref("browser.newtabpage.activity-stream.asrouter.providers.cfr", "{\"id\":\"cfr\",\"enabled\":false,\"type\":\"local\",\"localProvider\":\"CFRMessageProvider\",\"frequency\":{\"custom\":[{\"period\":\"daily\",\"cap\":1}]}}");
 #endif
 
+#ifdef EARLY_BETA_OR_EARLIER
+pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":true,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
+#else
+pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":false,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
+#endif
+
+
 
 // Enable the DOM fullscreen API.
 pref("full-screen-api.enabled", true);
 
 // Startup Crash Tracking
 // number of startup crashes that can occur before starting into safe mode automatically
 // (this pref has no effect if more than 6 hours have passed since the last crash)
 pref("toolkit.startup.max_resumed_crashes", 3);
@@ -1344,56 +1349,33 @@ pref("security.cert_pinning.enforcement_
 pref("plain_text.wrap_long_lines", true);
 
 // If this turns true, Moz*Gesture events are not called stopPropagation()
 // before content.
 pref("dom.debug.propagate_gesture_events_through_content", false);
 
 // All the Geolocation preferences are here.
 //
-
-// Geolocation preferences for the RELEASE and "later" Beta channels.
-// Some of these prefs are specified even though they are redundant; they are
-// here for clarity and end-user experiments.
-#ifndef EARLY_BETA_OR_EARLIER
 pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
-
-#ifdef XP_MACOSX
-pref("geo.provider.use_corelocation", false);
-#endif
-
-#ifdef XP_WIN
-pref("geo.provider.ms-windows-location", false);
-#endif
-
-#ifdef MOZ_WIDGET_GTK
-pref("geo.provider.use_gpsd", false);
-#endif
-
-#else
-
-// Geolocation preferences for Nightly/Aurora/Beta.
-pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
+// MLS URL:
+// pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
 
 #ifdef XP_MACOSX
 pref("geo.provider.use_corelocation", true);
 #endif
 
-// The native Windows location provider is only enabled in Nightly and likely to
-// be unstable. Set to false if things are really broken.
-#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
+// Set to false if things are really broken.
+#ifdef XP_WIN
 pref("geo.provider.ms-windows-location", true);
 #endif
 
 #if defined(MOZ_WIDGET_GTK) && defined(MOZ_GPSD)
 pref("geo.provider.use_gpsd", true);
 #endif
 
-#endif
-
 // CustomizableUI debug logging.
 pref("browser.uiCustomization.debug", false);
 
 // CustomizableUI state of the browser's user interface
 pref("browser.uiCustomization.state", "");
 
 // If set to false, FxAccounts and Sync will be unavailable.
 // A restart is mandatory after flipping that preference.
@@ -1534,16 +1516,17 @@ pref("dom.storage_access.enabled", true)
 
 pref("dom.storage_access.auto_grants", true);
 pref("dom.storage_access.max_concurrent_auto_grants", 5);
 
 // Define a set of default features for the Content Blocking UI.
 pref("browser.contentblocking.trackingprotection.control-center.ui.enabled", true);
 pref("browser.contentblocking.rejecttrackers.control-center.ui.enabled", true);
 
+pref("browser.contentblocking.control-center.ui.showBlockedLabels", false);
 pref("browser.contentblocking.control-center.ui.showAllowedLabels", false);
 
 // Enable the Report Breakage UI on Nightly and Beta but not on Release yet.
 #ifdef EARLY_BETA_OR_EARLIER
 pref("browser.contentblocking.reportBreakage.enabled", true);
 #else
 pref("browser.contentblocking.reportBreakage.enabled", false);
 #endif
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -73,17 +73,17 @@ var TrackingProtection = {
     this.enabledInPrivateWindows =
       Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
     this.updateCategoryLabel();
   },
 
   updateCategoryLabel() {
     let label;
     if (this.enabled) {
-      label = "contentBlocking.trackers.blocked.label";
+      label = ContentBlocking.showBlockedLabels ? "contentBlocking.trackers.blocking.label" : null;
     } else {
       label = ContentBlocking.showAllowedLabels ? "contentBlocking.trackers.allowed.label" : null;
     }
     this.categoryLabel.textContent = label ? gNavigatorBundle.getString(label) : "";
   },
 
   isBlocking(state) {
     return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0;
@@ -110,16 +110,41 @@ var TrackingProtection = {
     let fragment = document.createDocumentFragment();
     for (let [origin, actions] of Object.entries(contentBlockingLog)) {
       let listItem = await this._createListItem(origin, actions);
       if (listItem) {
         fragment.appendChild(listItem);
       }
     }
 
+    // If we don't have trackers we would usually not show the menu item
+    // allowing the user to show the sub-panel. However, in the edge case
+    // that we annotated trackers on the page using the strict list but did
+    // not detect trackers on the page using the basic list, we currently
+    // still show the panel. To reduce the confusion, tell the user that we have
+    // not detected any tracker.
+    if (fragment.childNodes.length == 0) {
+      let emptyBox = document.createXULElement("vbox");
+      let emptyImage = document.createXULElement("image");
+      emptyImage.classList.add("identity-popup-content-blocking-trackersView-empty-image");
+      emptyImage.classList.add("tracking-protection-icon");
+
+      let emptyLabel = document.createXULElement("label");
+      emptyLabel.classList.add("identity-popup-content-blocking-empty-label");
+      emptyLabel.textContent = gNavigatorBundle.getString("contentBlocking.trackersView.empty.label");
+
+      emptyBox.appendChild(emptyImage);
+      emptyBox.appendChild(emptyLabel);
+      fragment.appendChild(emptyBox);
+
+      this.subViewList.classList.add("empty");
+    } else {
+      this.subViewList.classList.remove("empty");
+    }
+
     // This might have taken a while. Only update the list if we're still on the same page.
     if (previousURI == gBrowser.currentURI.spec &&
         previousWindow == gBrowser.selectedBrowser.innerWindowID) {
       this.subViewList.textContent = "";
       this.subViewList.append(fragment);
     }
   },
 
@@ -246,26 +271,26 @@ var ThirdPartyCookies = {
       return "cookierestrictions";
     }
   },
 
   updateCategoryLabel() {
     let label;
     switch (this.behaviorPref) {
     case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
-      label = "contentBlocking.cookies.3rdPartyBlocked.label";
+      label = ContentBlocking.showBlockedLabels ? "contentBlocking.cookies.blocking3rdParty.label" : null;
       break;
     case Ci.nsICookieService.BEHAVIOR_REJECT:
-      label = "contentBlocking.cookies.allBlocked.label";
+      label = ContentBlocking.showBlockedLabels ? "contentBlocking.cookies.blockingAll.label" : null;
       break;
     case Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN:
-      label = "contentBlocking.cookies.unvisitedBlocked.label";
+      label = ContentBlocking.showBlockedLabels ? "contentBlocking.cookies.blockingUnvisited.label" : null;
       break;
     case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
-      label = "contentBlocking.cookies.trackersBlocked.label";
+      label = ContentBlocking.showBlockedLabels ? "contentBlocking.cookies.blockingTrackers.label" : null;
       break;
     default:
       Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
       // fall through
     case Ci.nsICookieService.BEHAVIOR_ACCEPT:
       label = ContentBlocking.showAllowedLabels ? "contentBlocking.cookies.allowed.label" : null;
       break;
     }
@@ -299,27 +324,36 @@ var ThirdPartyCookies = {
     let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog();
     let contentBlockingLog = JSON.parse(contentBlockingLogJSON);
 
     let categories = this._processContentBlockingLog(contentBlockingLog);
 
     this.subViewList.textContent = "";
 
     for (let category of ["firstParty", "trackers", "thirdParty"]) {
-      if (categories[category].length) {
-        let box = document.createXULElement("vbox");
-        let label = document.createXULElement("label");
-        label.className = "identity-popup-cookiesView-list-header";
-        label.textContent = gNavigatorBundle.getString(`contentBlocking.cookiesView.${category}.label`);
-        box.appendChild(label);
-        for (let info of categories[category]) {
-          box.appendChild(this._createListItem(info));
-        }
-        this.subViewList.appendChild(box);
+      let box = document.createXULElement("vbox");
+      let label = document.createXULElement("label");
+      label.className = "identity-popup-cookiesView-list-header";
+      label.textContent = gNavigatorBundle.getString(`contentBlocking.cookiesView.${category}.label`);
+      box.appendChild(label);
+
+      for (let info of categories[category]) {
+        box.appendChild(this._createListItem(info));
       }
+
+      // If the category is empty, add a label noting that to the user.
+      if (categories[category].length == 0) {
+        let emptyLabel = document.createXULElement("label");
+        emptyLabel.classList.add("identity-popup-content-blocking-empty-label");
+        emptyLabel.textContent =
+          gNavigatorBundle.getString(`contentBlocking.cookiesView.${category}.empty.label`);
+        box.appendChild(emptyLabel);
+      }
+
+      this.subViewList.appendChild(box);
     }
   },
 
   _hasException(origin) {
     for (let perm of Services.perms.getAllForPrincipal(gBrowser.contentPrincipal)) {
       if (perm.type == "3rdPartyStorage^" + origin || perm.type.startsWith("3rdPartyStorage^" + origin + "^")) {
         return true;
       }
@@ -484,16 +518,17 @@ var ContentBlocking = {
   // If the user ignores the doorhanger, we stop showing it after some time.
   MAX_INTROS: 20,
   PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
   PREF_REPORT_BREAKAGE_URL: "browser.contentblocking.reportBreakage.url",
   PREF_INTRO_COUNT_CB: "browser.contentblocking.introCount",
   PREF_CB_CATEGORY: "browser.contentblocking.category",
   PREF_SHOW_ALLOWED_LABELS: "browser.contentblocking.control-center.ui.showAllowedLabels",
+  PREF_SHOW_BLOCKED_LABELS: "browser.contentblocking.control-center.ui.showBlockedLabels",
   content: null,
   icon: null,
   activeTooltipText: null,
   disabledTooltipText: null,
 
   get prefIntroCount() {
     return this.PREF_INTRO_COUNT_CB;
   },
@@ -541,27 +576,27 @@ var ContentBlocking = {
     } catch (e) {
       // Getting the hostPort for about: and file: URIs fails, but TP doesn't work with
       // these URIs anyway, so just return null here.
       return null;
     }
   },
 
   init() {
-    let $ = selector => document.querySelector(selector);
-    this.content = $("#identity-popup-content-blocking-content");
-    this.icon = $("#tracking-protection-icon");
-    this.iconBox = $("#tracking-protection-icon-box");
-    this.animatedIcon = $("#tracking-protection-icon-animatable-image");
+    let $ = id => document.getElementById(id);
+    this.content = $("identity-popup-content-blocking-content");
+    this.icon = $("tracking-protection-icon");
+    this.iconBox = $("tracking-protection-icon-box");
+    this.animatedIcon = $("tracking-protection-icon-animatable-image");
     this.animatedIcon.addEventListener("animationend", () => this.iconBox.removeAttribute("animate"));
 
-    this.identityPopupMultiView = $("#identity-popup-multiView");
-    this.reportBreakageButton = $("#identity-popup-content-blocking-report-breakage");
-    this.reportBreakageURL = $("#identity-popup-breakageReportView-collection-url");
-    this.reportBreakageLearnMore = $("#identity-popup-breakageReportView-learn-more");
+    this.identityPopupMultiView = $("identity-popup-multiView");
+    this.reportBreakageButton = $("identity-popup-content-blocking-report-breakage");
+    this.reportBreakageURL = $("identity-popup-breakageReportView-collection-url");
+    this.reportBreakageLearnMore = $("identity-popup-breakageReportView-learn-more");
 
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
     this.reportBreakageLearnMore.href = baseURL + "blocking-breakage";
 
     this.updateAnimationsEnabled = () => {
       this.iconBox.toggleAttribute("animationsenabled",
         Services.prefs.getBoolPref(this.PREF_ANIMATIONS_ENABLED, false));
     };
@@ -571,16 +606,22 @@ var ContentBlocking = {
         blocker.init();
       }
     }
 
     this.updateAnimationsEnabled();
 
     Services.prefs.addObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
 
+    XPCOMUtils.defineLazyPreferenceGetter(this, "showBlockedLabels",
+      this.PREF_SHOW_BLOCKED_LABELS, false, () => {
+        for (let blocker of this.blockers) {
+          blocker.updateCategoryLabel();
+        }
+    });
     XPCOMUtils.defineLazyPreferenceGetter(this, "showAllowedLabels",
       this.PREF_SHOW_ALLOWED_LABELS, false, () => {
         for (let blocker of this.blockers) {
           blocker.updateCategoryLabel();
         }
     });
     XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
       this.PREF_REPORT_BREAKAGE_ENABLED, false);
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -743,17 +743,17 @@ var BookmarksEventHandler = {
       closeMenus(aEvent.target);
     }
 
     if (target._placesNode && PlacesUtils.nodeIsContainer(target._placesNode)) {
       // Don't open the root folder in tabs when the empty area on the toolbar
       // is middle-clicked or when a non-bookmark item (except for Open in Tabs)
       // in a bookmarks menupopup is middle-clicked.
       if (target.localName == "menu" || target.localName == "toolbarbutton")
-        PlacesUIUtils.openMultipleLinksInTabs(target._placesNode, aEvent, aView);
+        PlacesUIUtils.openContainerNodeInTabs(target._placesNode, aEvent, aView);
     } else if (aEvent.button == 1) {
       // left-clicks with modifier are already served by onCommand
       this.onCommand(aEvent);
     }
   },
 
   /**
    * Handler for command event for an item in the bookmarks toolbar.
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -38,25 +38,25 @@
 /* Set additional backgrounds alignment relative to toolbox */
 
 #navigator-toolbox:-moz-lwtheme {
   background-image: var(--lwt-additional-images);
   background-position: var(--lwt-background-alignment);
   background-repeat: var(--lwt-background-tiling);
 }
 
-#main-window:not([chromehidden~="toolbar"]) {
+:root:not([chromehidden~="toolbar"]) {
 %ifdef XP_MACOSX
   min-width: 335px;
 %else
   min-width: 300px;
 %endif
 }
 
-#main-window[customize-entered] {
+:root[customize-entered] {
   min-width: -moz-fit-content;
 }
 
 .searchbar-textbox {
   -moz-binding: url("chrome://browser/content/search/search.xml#searchbar-textbox");
 }
 
 .search-one-offs[compact=true] .search-setting-button,
@@ -280,40 +280,40 @@ window:not([chromehidden~="toolbar"]) #n
 }
 
 
 %ifdef MENUBAR_CAN_AUTOHIDE
 #toolbar-menubar:not([autohide=true]) + #TabsToolbar > .titlebar-buttonbox-container,
 #toolbar-menubar:not([autohide=true]) + #TabsToolbar .titlebar-spacer,
 %endif
 %ifndef MOZ_WIDGET_COCOA
-#main-window:not([sizemode=normal]) .titlebar-spacer[type="pre-tabs"],
+:root:not([sizemode=normal]) .titlebar-spacer[type="pre-tabs"],
 %endif
-#main-window:not([chromemargin]) .titlebar-buttonbox-container,
-#main-window[inFullscreen] .titlebar-buttonbox-container,
-#main-window[inFullscreen] .titlebar-spacer,
-#main-window:not([tabsintitlebar]) .titlebar-spacer {
+:root:not([chromemargin]) .titlebar-buttonbox-container,
+:root[inFullscreen] .titlebar-buttonbox-container,
+:root[inFullscreen] .titlebar-spacer,
+:root:not([tabsintitlebar]) .titlebar-spacer {
   display: none;
 }
 
 %ifdef MENUBAR_CAN_AUTOHIDE
 #toolbar-menubar[autohide=true]:not([inactive]) + #TabsToolbar > .titlebar-buttonbox-container {
   visibility: hidden;
 }
 %endif
 
 #titlebar {
   -moz-window-dragging: drag;
 }
 
-#main-window[tabsintitlebar] .titlebar-buttonbox {
+:root[tabsintitlebar] .titlebar-buttonbox {
   position: relative;
 }
 
-#main-window:not([tabsintitlebar]) .titlebar-buttonbox {
+:root:not([tabsintitlebar]) .titlebar-buttonbox {
   display: none;
 }
 
 .titlebar-buttonbox {
   -moz-appearance: -moz-window-button-box;
   position: relative;
 }
 
@@ -346,33 +346,22 @@ toolbarpaletteitem {
 }
 
 #titlebar-secondary-buttonbox:-moz-locale-dir(rtl),
 .titlebar-buttonbox-container:-moz-locale-dir(ltr) {
   -moz-box-ordinal-group: 0;
 }
 %endif
 
-%ifdef XP_WIN
-#main-window[sizemode="maximized"] #titlebar-buttonbox {
-  -moz-appearance: -moz-window-button-box-maximized;
-}
-
-#main-window[tabletmode] #titlebar-min,
-#main-window[tabletmode] #titlebar-max {
-  display: none !important;
-}
-%endif
-
-#main-window[inDOMFullscreen] #navigator-toolbox,
-#main-window[inDOMFullscreen] #fullscr-toggler,
-#main-window[inDOMFullscreen] #sidebar-box,
-#main-window[inDOMFullscreen] #sidebar-splitter,
-#main-window[inFullscreen]:not([OSXLionFullscreen]) toolbar:not([fullscreentoolbar=true]),
-#main-window[inFullscreen] .global-notificationbox {
+:root[inDOMFullscreen] #navigator-toolbox,
+:root[inDOMFullscreen] #fullscr-toggler,
+:root[inDOMFullscreen] #sidebar-box,
+:root[inDOMFullscreen] #sidebar-splitter,
+:root[inFullscreen]:not([OSXLionFullscreen]) toolbar:not([fullscreentoolbar=true]),
+:root[inFullscreen] .global-notificationbox {
   visibility: collapse;
 }
 
 #navigator-toolbox[fullscreenShouldAnimate] {
   transition: 1.5s margin-top ease-out;
 }
 
 /* Rules to help integrate WebExtension buttons */
@@ -512,17 +501,17 @@ toolbar:not(#TabsToolbar) > #personal-bo
 #appMenu-library-recentlyClosedTabs > .panel-subview-body > .bookmark-item,
 #appMenu-library-recentlyClosedWindows > .panel-subview-body > .bookmark-item,
 #appMenu-library-recentHighlights > .bookmark-item,
 #panelMenu_bookmarksMenu > .bookmark-item {
   max-width: none;
 }
 
 %ifdef XP_MACOSX
-#main-window[inFullscreen="true"] {
+:root[inFullscreen="true"] {
   padding-top: 0; /* override drawintitlebar="true" */
 }
 %endif
 
 /* Hide menu elements intended for keyboard access support */
 #main-menubar[openedwithkey=false] .show-only-for-keyboard {
   display: none;
 }
@@ -567,27 +556,27 @@ html|input.urlbar-input[dir=ltr]:-moz-lo
 
 /*
  * Display visual cue that browser is under remote control by Marionette.
  * This is to help users visually distinguish a user agent session that
  * is under remote control from those used for normal browsing sessions.
  *
  * Attribute is controlled by browser.js:/gRemoteControl.
  */
-#main-window[remotecontrol] #urlbar {
+:root[remotecontrol] #urlbar {
   background: repeating-linear-gradient(
     -45deg,
     transparent,
     transparent 25px,
     rgba(255,255,255,.3) 25px,
     rgba(255,255,255,.3) 50px);
   background-color: rgba(255,170,68,.8);
   color: black;
 }
-#main-window[remotecontrol] #urlbar #identity-box {
+:root[remotecontrol] #urlbar #identity-box {
   background: white;
 }
 
 /* Show the url scheme in a static box when overflowing to the left */
 moz-input-box.urlbar-input-box {
   position: relative;
   direction: ltr;
 }
@@ -949,17 +938,17 @@ html|*.pointerlockfswarning:not([hidden]
 }
 html|*.pointerlockfswarning[onscreen] {
   transform: translate(-50%, 50px);
 }
 html|*.pointerlockfswarning[ontop] {
   /* Use -10px to hide the border and border-radius on the top */
   transform: translate(-50%, -10px);
 }
-#main-window[OSXLionFullscreen] html|*.pointerlockfswarning[ontop] {
+:root[OSXLionFullscreen] html|*.pointerlockfswarning[ontop] {
   transform: translate(-50%, 80px);
 }
 
 html|*.pointerlockfswarning-domain-text,
 html|*.pointerlockfswarning-generic-text {
   word-wrap: break-word;
   /* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
   min-width: 1px
@@ -1277,18 +1266,18 @@ toolbarpaletteitem[place="palette"][hidd
 }
 
 toolbarpaletteitem > toolbarbutton,
 toolbarpaletteitem > toolbaritem {
   /* Prevent children from getting events */
   pointer-events: none;
 }
 
-#main-window[customizing=true] .addon-banner-item,
-#main-window[customizing=true] .panel-banner-item {
+:root[customizing=true] .addon-banner-item,
+:root[customizing=true] .panel-banner-item {
   display: none;
 }
 
 /* UI Tour */
 
 @keyframes uitour-wobble {
   from {
     transform: rotate(0deg) translateX(3px) rotate(0deg);
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -926,52 +926,63 @@
 
       <field name="_animateElement">
         this.arrowScrollbox._scrollButtonDown;
       </field>
 
       <method name="_notifyBackgroundTab">
         <parameter name="aTab"/>
         <body><![CDATA[
-          if (aTab.pinned || aTab.hidden)
-            return;
-
-          var scrollRect = this.arrowScrollbox.scrollClientRect;
-          var tab = aTab.getBoundingClientRect();
-
-          // DOMRect left/right properties are immutable.
-          tab = {left: tab.left, right: tab.right};
-
-          // Is the new tab already completely visible?
-          if (scrollRect.left <= tab.left && tab.right <= scrollRect.right)
+          if (aTab.pinned || aTab.hidden || this.getAttribute("overflow") != "true")
             return;
 
-          if (this.arrowScrollbox.smoothScroll) {
-            let selectedTab = this.selectedItem;
-            let selected = !selectedTab.pinned &&
-                           selectedTab.getBoundingClientRect();
+          this._lastTabToScrollIntoView = aTab;
+          if (!this._backgroundTabScrollPromise) {
+            this._backgroundTabScrollPromise = window.promiseDocumentFlushed(() => {
+              let lastTabRect = this._lastTabToScrollIntoView.getBoundingClientRect();
+              let selectedTab = this.selectedItem;
+              if (selectedTab.pinned) {
+                selectedTab = null;
+              } else {
+                selectedTab = selectedTab.getBoundingClientRect();
+                selectedTab = {left: selectedTab.left, right: selectedTab.right};
+              }
+              delete this._lastTabToScrollIntoView;
+              delete this._backgroundTabScrollPromise;
+              return [
+                this.arrowScrollbox.scrollClientRect,
+                {left: lastTabRect.left, right: lastTabRect.right},
+                selectedTab,
+              ];
+            }).then(([scrollRect, tab, selected]) => {
+              // Is the new tab already completely visible?
+              if (scrollRect.left <= tab.left && tab.right <= scrollRect.right)
+                return;
 
-            // Can we make both the new tab and the selected tab completely visible?
-            if (!selected ||
-                Math.max(tab.right - selected.left, selected.right - tab.left) <=
-                  scrollRect.width) {
-              this.arrowScrollbox.ensureElementIsVisible(aTab);
-              return;
-            }
+              if (this.arrowScrollbox.smoothScroll) {
+                // Can we make both the new tab and the selected tab completely visible?
+                if (!selected ||
+                    Math.max(tab.right - selected.left, selected.right - tab.left) <=
+                      scrollRect.width) {
+                  this.arrowScrollbox.ensureElementIsVisible(aTab);
+                  return;
+                }
 
-            this.arrowScrollbox.scrollByPixels(RTL_UI ?
-                                                 selected.right - scrollRect.right :
-                                                 selected.left - scrollRect.left);
-          }
+                this.arrowScrollbox.scrollByPixels(RTL_UI ?
+                                                     selected.right - scrollRect.right :
+                                                     selected.left - scrollRect.left);
+              }
 
-          if (!this._animateElement.hasAttribute("highlight")) {
-            this._animateElement.setAttribute("highlight", "true");
-            setTimeout(function(ele) {
-              ele.removeAttribute("highlight");
-            }, 150, this._animateElement);
+              if (!this._animateElement.hasAttribute("highlight")) {
+                this._animateElement.setAttribute("highlight", "true");
+                setTimeout(function(ele) {
+                  ele.removeAttribute("highlight");
+                }, 150, this._animateElement);
+              }
+            });
           }
         ]]></body>
       </method>
 
       <method name="_getDragTargetTab">
         <parameter name="event"/>
         <parameter name="isLink"/>
         <body><![CDATA[
--- a/browser/base/content/test/forms/browser_selectpopup_colors.js
+++ b/browser/base/content/test/forms/browser_selectpopup_colors.js
@@ -180,18 +180,22 @@ const SELECT_INHERITED_COLORS_ON_OPTIONS
      <option class="textShadow">{"color": "rgb(0, 0, 255)", "textShadow": "rgb(0, 0, 0) 1px 1px 2px", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>
      <option selected="true">{"end": "true"}</option>
    </select></body></html>
 `;
 
 function getSystemColor(color) {
   // Need to convert system color to RGB color.
   let textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
+  textarea.style.display = "none";
   textarea.style.color = color;
-  return getComputedStyle(textarea).color;
+  document.documentElement.appendChild(textarea);
+  let computed = getComputedStyle(textarea).color;
+  textarea.remove();
+  return computed;
 }
 
 function testOptionColors(index, item, menulist) {
   // The label contains a JSON string of the expected colors for
   // `color` and `background-color`.
   let expected = JSON.parse(item.label);
 
   for (let color of Object.keys(expected)) {
@@ -206,17 +210,17 @@ function testOptionColors(index, item, m
   EventUtils.synthesizeKey("KEY_ArrowDown");
 
   if (expected.end) {
     return;
   }
 
   if (expected.unstyled) {
     ok(!item.hasAttribute("customoptionstyling"),
-      `Item ${index} should not have any custom option styling`);
+      `Item ${index} should not have any custom option styling: ${item.outerHTML}`);
   } else {
     is(getComputedStyle(item).color, expected.color,
        "Item " + (index) + " has correct foreground color");
     is(getComputedStyle(item).backgroundColor, expected.backgroundColor,
        "Item " + (index) + " has correct background color");
     if (expected.textShadow) {
       is(getComputedStyle(item).textShadow, expected.textShadow,
          "Item " + (index) + " has correct text-shadow color");
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -48,16 +48,17 @@ const whitelist = {
     "resource://formautofill/FormAutofillContent.jsm",
 
     // Browser front-end
     "resource:///actors/AboutReaderChild.jsm",
     "resource:///actors/BrowserTabChild.jsm",
     "resource:///modules/ContentMetaHandler.jsm",
     "resource:///actors/LinkHandlerChild.jsm",
     "resource:///actors/PageStyleChild.jsm",
+    "resource:///actors/SearchTelemetryChild.jsm",
     "resource://gre/modules/ActorChild.jsm",
     "resource://gre/modules/ActorManagerChild.jsm",
     "resource://gre/modules/E10SUtils.jsm",
     "resource://gre/modules/Readerable.jsm",
     "resource://gre/modules/WebProgressChild.jsm",
 
     // Pocket
     "chrome://pocket/content/AboutPocket.jsm",
--- a/browser/base/content/test/trackingUI/browser_trackingUI_categories.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_categories.js
@@ -65,27 +65,30 @@ add_task(async function testCategoryLabe
     await TestUtils.waitForCondition(() => appMenuCategoryLabel.value ==
       gNavigatorBundle.getString("contentBlocking.category.custom"));
     is(appMenuCategoryLabel.value, gNavigatorBundle.getString("contentBlocking.category.custom"),
       "The appMenuCategory label has been changed to custom");
   });
 });
 
 add_task(async function testSubcategoryLabels() {
-  SpecialPowers.pushPrefEnv({set: [["browser.contentblocking.control-center.ui.showAllowedLabels", true]]});
+  SpecialPowers.pushPrefEnv({set: [
+    ["browser.contentblocking.control-center.ui.showAllowedLabels", true],
+    ["browser.contentblocking.control-center.ui.showBlockedLabels", true],
+  ]});
 
   await BrowserTestUtils.withNewTab("http://www.example.com", async function() {
     let categoryLabel =
       document.getElementById("identity-popup-content-blocking-tracking-protection-state-label");
 
     Services.prefs.setBoolPref(TP_PREF, true);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
-      gNavigatorBundle.getString("contentBlocking.trackers.blocked.label"),
+      gNavigatorBundle.getString("contentBlocking.trackers.blocking.label"),
       "The category label has updated correctly");
-    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.trackers.blocked.label"));
+    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.trackers.blocking.label"));
 
     Services.prefs.setBoolPref(TP_PREF, false);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
       gNavigatorBundle.getString("contentBlocking.trackers.allowed.label"),
       "The category label has updated correctly");
     is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.trackers.allowed.label"));
 
     categoryLabel =
@@ -94,31 +97,31 @@ add_task(async function testSubcategoryL
     Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
       gNavigatorBundle.getString("contentBlocking.cookies.allowed.label"),
       "The category label has updated correctly");
     is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.allowed.label"));
 
     Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
-      gNavigatorBundle.getString("contentBlocking.cookies.allBlocked.label"),
+      gNavigatorBundle.getString("contentBlocking.cookies.blockingAll.label"),
       "The category label has updated correctly");
-    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.allBlocked.label"));
+    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.blockingAll.label"));
 
     Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
-      gNavigatorBundle.getString("contentBlocking.cookies.3rdPartyBlocked.label"),
+      gNavigatorBundle.getString("contentBlocking.cookies.blocking3rdParty.label"),
       "The category label has updated correctly");
-    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.3rdPartyBlocked.label"));
+    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.blocking3rdParty.label"));
 
     Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
-      gNavigatorBundle.getString("contentBlocking.cookies.trackersBlocked.label"),
+      gNavigatorBundle.getString("contentBlocking.cookies.blockingTrackers.label"),
       "The category label has updated correctly");
-    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.trackersBlocked.label"));
+    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.blockingTrackers.label"));
 
     Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN);
     await TestUtils.waitForCondition(() => categoryLabel.textContent ==
-      gNavigatorBundle.getString("contentBlocking.cookies.unvisitedBlocked.label"),
+      gNavigatorBundle.getString("contentBlocking.cookies.blockingUnvisited.label"),
       "The category label has updated correctly");
-    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.unvisitedBlocked.label"));
+    is(categoryLabel.textContent, gNavigatorBundle.getString("contentBlocking.cookies.blockingUnvisited.label"));
   });
 });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_cookies_subview.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_cookies_subview.js
@@ -29,20 +29,20 @@ async function assertSitesListed(tracker
     let cookiesView = document.getElementById("identity-popup-cookiesView");
     let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
     categoryItem.click();
     await viewShown;
 
     ok(true, "Cookies view was shown");
 
     let listHeaders = cookiesView.querySelectorAll(".identity-popup-cookiesView-list-header");
-    is(listHeaders.length, 1, "We have 1 list header");
-    is(listHeaders[0].textContent,
-       gNavigatorBundle.getString(`contentBlocking.cookiesView.trackers.label`),
-       "The list header is for tracking cookies.");
+    is(listHeaders.length, 3, "We have 3 list headers");
+
+    let emptyLabels = cookiesView.querySelectorAll(".identity-popup-content-blocking-empty-label");
+    is(emptyLabels.length, 2, "We have 2 empty labels");
 
     let listItems = cookiesView.querySelectorAll(".identity-popup-content-blocking-list-item");
     is(listItems.length, 1, "We have 1 cookie in the list");
 
     let listItem = listItems[0];
     let label = listItem.querySelector(".identity-popup-content-blocking-list-host-label");
     is(label.value, "http://trackertest.org", "Has an item for trackertest.org");
     ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
@@ -68,21 +68,18 @@ async function assertSitesListed(tracker
     is(result, undefined, "No securityChange events should be received");
 
     viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
     categoryItem.click();
     await viewShown;
 
     ok(true, "Cookies view was shown");
 
-    listHeaders = cookiesView.querySelectorAll(".identity-popup-cookiesView-list-header");
-    is(listHeaders.length, 2, "We now have 2 list headers");
-    is(listHeaders[1].textContent,
-       gNavigatorBundle.getString(`contentBlocking.cookiesView.thirdParty.label`),
-       "The new list header is for third party cookies.");
+    emptyLabels = cookiesView.querySelectorAll(".identity-popup-content-blocking-empty-label");
+    is(emptyLabels.length, 1, "We have 1 empty label");
 
     listItems = cookiesView.querySelectorAll(".identity-popup-content-blocking-list-item");
     is(listItems.length, 2, "We have 2 cookies in the list");
 
     listItem = listItems[1];
     label = listItem.querySelector(".identity-popup-content-blocking-list-host-label");
     is(label.value, "https://test1.example.org", "Has an item for test1.example.org");
     ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
@@ -106,21 +103,18 @@ async function assertSitesListed(tracker
     is(result, undefined, "No securityChange events should be received");
 
     viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
     categoryItem.click();
     await viewShown;
 
     ok(true, "Cookies view was shown");
 
-    listHeaders = cookiesView.querySelectorAll(".identity-popup-cookiesView-list-header");
-    is(listHeaders.length, 3, "We now have 3 list headers");
-    is(listHeaders[0].textContent,
-       gNavigatorBundle.getString(`contentBlocking.cookiesView.firstParty.label`),
-       "The new list header is for first party cookies.");
+    emptyLabels = cookiesView.querySelectorAll(".identity-popup-content-blocking-empty-label");
+    is(emptyLabels.length, 0, "We have 0 empty label");
 
     listItems = cookiesView.querySelectorAll(".identity-popup-content-blocking-list-item");
     is(listItems.length, 3, "We have 2 cookies in the list");
 
     listItem = listItems[0];
     label = listItem.querySelector(".identity-popup-content-blocking-list-host-label");
     is(label.value, "http://not-tracking.example.com", "Has an item for the first party");
     ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
@@ -159,22 +153,16 @@ add_task(async function testCookiesSubVi
     ok(BrowserTestUtils.is_visible(categoryItem), "TP category item is visible");
     let cookiesView = document.getElementById("identity-popup-cookiesView");
     let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
     categoryItem.click();
     await viewShown;
 
     ok(true, "Cookies view was shown");
 
-    let listHeaders = cookiesView.querySelectorAll(".identity-popup-cookiesView-list-header");
-    is(listHeaders.length, 1, "We have 1 list header");
-    is(listHeaders[0].textContent,
-       gNavigatorBundle.getString(`contentBlocking.cookiesView.trackers.label`),
-       "The list header is for tracking cookies.");
-
     let listItems = cookiesView.querySelectorAll(".identity-popup-content-blocking-list-item");
     is(listItems.length, 1, "We have 1 cookie in the list");
 
     let listItem = listItems[0];
     let label = listItem.querySelector(".identity-popup-content-blocking-list-host-label");
     is(label.value, "http://trackertest.org", "Has an item for trackertest.org");
     ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
     ok(listItem.classList.contains("allowed"), "Indicates whether the cookie was blocked or allowed");
--- a/browser/components/extensions/parent/ext-menus.js
+++ b/browser/components/extensions/parent/ext-menus.js
@@ -650,21 +650,27 @@ MenuItem.prototype = {
       this[propName] = createProperties[propName];
     }
 
     if ("icons" in createProperties && createProperties.icons === null) {
       this.icons = null;
     }
 
     if (createProperties.documentUrlPatterns != null) {
-      this.documentUrlMatchPattern = new MatchPatternSet(this.documentUrlPatterns);
+      this.documentUrlMatchPattern = new MatchPatternSet(this.documentUrlPatterns, {
+        restrictSchemes: this.extension.restrictSchemes,
+      });
     }
 
     if (createProperties.targetUrlPatterns != null) {
-      this.targetUrlMatchPattern = new MatchPatternSet(this.targetUrlPatterns, {restrictSchemes: false});
+      this.targetUrlMatchPattern = new MatchPatternSet(this.targetUrlPatterns, {
+        // restrictSchemes default to false when matching links instead of pages
+        // (see Bug 1280370 for a rationale).
+        restrictSchemes: false,
+      });
     }
 
     // If a child MenuItem does not specify any contexts, then it should
     // inherit the contexts specified from its parent.
     if (createProperties.parentId && !createProperties.contexts) {
       this.contexts = this.parent.contexts;
     }
   },
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js
@@ -184,8 +184,84 @@ add_task(async function unsupportedSchem
   await extension.startup();
   await extension.awaitMessage("ready");
   await openExtensionContextMenu("#test_link_element");
   await extension.awaitMessage("done");
   await closeContextMenu();
 
   await extension.unload();
 });
+
+add_task(async function privileged_are_allowed_to_use_restrictedSchemes() {
+  let privilegedExtension = ExtensionTestUtils.loadExtension({
+    isPrivileged: true,
+    manifest: {
+      permissions: ["tabs", "contextMenus", "mozillaAddons"],
+    },
+    async background() {
+      browser.contextMenus.create({
+        id: "privileged-extension",
+        title: "Privileged Extension",
+        contexts: ["page"],
+        documentUrlPatterns: ["about:reader*"],
+      });
+
+      browser.tabs.onUpdated.addListener(async (tabId, changeInfo) => {
+        if (changeInfo.url && changeInfo.url.startsWith("about:reader")) {
+          browser.test.sendMessage("readerModeEntered");
+        }
+      });
+
+      browser.test.onMessage.addListener(async (msg) => {
+        if (msg !== "enterReaderMode") {
+          browser.test.fail(`Received unexpected test message: ${msg}`);
+          return;
+        }
+
+        browser.tabs.toggleReaderMode();
+      });
+    },
+  });
+
+  let nonPrivilegedExtension = ExtensionTestUtils.loadExtension({
+    isPrivileged: false,
+    manifest: {
+      permissions: ["contextMenus", "mozillaAddons"],
+    },
+    async background() {
+      browser.contextMenus.create({
+        id: "non-privileged-extension",
+        title: "Non Privileged Extension",
+        contexts: ["page"],
+        documentUrlPatterns: ["about:reader*"],
+      });
+    },
+  });
+
+  const baseUrl = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
+  const url = `${baseUrl}/readerModeArticle.html`;
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url, true, true);
+
+  await Promise.all([
+    privilegedExtension.startup(),
+    nonPrivilegedExtension.startup(),
+  ]);
+
+  privilegedExtension.sendMessage("enterReaderMode");
+  await privilegedExtension.awaitMessage("readerModeEntered");
+
+  const contextMenu = await openContextMenu("body > h1");
+
+  let item = contextMenu.getElementsByAttribute("label", "Privileged Extension");
+  is(item.length, 1, "Privileged extension's contextMenu item found as expected");
+
+  item = contextMenu.getElementsByAttribute("label", "Non Privileged Extension");
+  is(item.length, 0, "Non privileged extension's contextMenu not found as expected");
+
+  await closeContextMenu();
+
+  BrowserTestUtils.removeTab(tab);
+
+  await Promise.all([
+    privilegedExtension.unload(),
+    nonPrivilegedExtension.unload(),
+  ]);
+});
--- a/browser/components/extensions/test/browser/browser_ext_popup_background.js
+++ b/browser/components/extensions/test/browser/browser_ext_popup_background.js
@@ -15,17 +15,20 @@ async function testPanel(browser, standA
            "rgb(255, 255, 255)", "Arrow fill should be set to #fff when no background is supplied and popup is standAlone");
       } else {
         let default_background =
           getComputedStyle(document.documentElement).getPropertyValue("--arrowpanel-background");
         // Need to apply the color to a node and get the computed value
         // to resolve CSS named colors such as -moz-field.
         let span = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
         span.style.color = default_background;
+        span.style.display = "none";
+        document.documentElement.appendChild(span);
         let default_background_computed = getComputedStyle(span).color;
+        span.remove();
 
         is(getComputedStyle(arrow).fill, default_background_computed, "Arrow fill should be the default one");
       }
       return;
     }
 
     is(getComputedStyle(arrowContent).backgroundColor, background, "Arrow content should have correct background");
     is(getComputedStyle(arrow).fill, background, "Arrow should have correct background");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -247,16 +247,26 @@ let ACTORS = {
       ],
 
       observers: [
         "decoder-doctor-notification",
       ],
     },
   },
 
+  SearchTelemetry: {
+    child: {
+      module: "resource:///actors/SearchTelemetryChild.jsm",
+      events: {
+        DOMContentLoaded: {},
+        "pageshow": {mozSystemGroup: true},
+      },
+    },
+  },
+
   ShieldFrame: {
     child: {
       module: "resource://normandy-content/ShieldFrameChild.jsm",
       events: {
         "ShieldPageEvent": {wantUntrusted: true},
       },
       matches: ["about:studies"],
     },
@@ -421,16 +431,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.jsm",
   ReaderParent: "resource:///modules/ReaderParent.jsm",
   RemotePrompt: "resource:///modules/RemotePrompt.jsm",
   RemoteSettings: "resource://services-settings/remote-settings.js",
   SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
   Sanitizer: "resource:///modules/Sanitizer.jsm",
   SaveToPocket: "chrome://pocket/content/SaveToPocket.jsm",
+  SearchTelemetry: "resource:///modules/SearchTelemetry.jsm",
   SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
   SessionStore: "resource:///modules/sessionstore/SessionStore.jsm",
   ShellService: "resource:///modules/ShellService.jsm",
   TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
   UIState: "resource://services-sync/UIState.jsm",
   UITour: "resource:///modules/UITour.jsm",
   WebChannel: "resource://gre/modules/WebChannel.jsm",
   WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm",
@@ -1439,16 +1450,17 @@ BrowserGlue.prototype = {
 
     for (let mod of Object.values(initializedModules)) {
       if (mod.uninit) {
         mod.uninit();
       }
     }
 
     BrowserUsageTelemetry.uninit();
+    SearchTelemetry.uninit();
     // Only uninit PingCentre if the getter has initialized it
     if (Object.prototype.hasOwnProperty.call(this, "pingCentre")) {
       this.pingCentre.uninit();
     }
 
     PageThumbs.uninit();
     NewTabUtils.uninit();
     AboutPrivateBrowsingHandler.uninit();
@@ -1506,16 +1518,17 @@ BrowserGlue.prototype = {
 
     // Browser errors are only collected on Nightly, but telemetry for
     // them is collected on all channels.
     if (AppConstants.MOZ_DATA_REPORTING) {
       this.browserErrorReporter.init();
     }
 
     BrowserUsageTelemetry.init();
+    SearchTelemetry.init();
 
     // Show update notification, if needed.
     if (Services.prefs.prefHasUserValue("app.update.postupdate"))
       this._showUpdateNotification();
 
     ExtensionsUI.init();
 
     let signingRequired;
@@ -3023,17 +3036,17 @@ BrowserGlue.prototype = {
 
 var ContentBlockingCategoriesPrefs = {
   PREF_CB_CATEGORY: "browser.contentblocking.category",
   // The prefs inside CATEGORY_PREFS set expected value for each CB category.
   // A null value means that pref is default.
   CATEGORY_PREFS: {
     strict: [
       ["urlclassifier.trackingTable", null],
-      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN],
+      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
       ["privacy.trackingprotection.pbmode.enabled", true],
       ["privacy.trackingprotection.enabled", true],
     ],
     standard: [
       ["urlclassifier.trackingTable", null],
       ["network.cookie.cookieBehavior", null],
       ["privacy.trackingprotection.pbmode.enabled", null],
       ["privacy.trackingprotection.enabled", null],
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -621,46 +621,36 @@ var PlacesUIUtils = {
     // loadTabs with aReplace set to false.
     browserWindow.gBrowser.loadTabs(urls, {
       inBackground: loadInBackground,
       replace: false,
       triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
     });
   },
 
-  /**
-   * Loads a selected node's or nodes' URLs in tabs,
-   * warning the user when lots of URLs are being opened
-   *
-   * @param {object|array} nodeOrNodes
-   *          Contains the node or nodes that we're opening in tabs
-   * @param {event} event
-   *          The DOM mouse/key event with modifier keys set that track the
-   *          user's preferred destination window or tab.
-   * @param {object} view
-   *          The current view that contains the node or nodes selected for
-   *          opening
-   */
-  openMultipleLinksInTabs(nodeOrNodes, event, view) {
-    let window = view.ownerWindow;
+  openContainerNodeInTabs:
+  function PUIU_openContainerInTabs(aNode, aEvent, aView) {
+    let window = aView.ownerWindow;
+
+    let urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode);
+    if (OpenInTabsUtils.confirmOpenInTabs(urlsToOpen.length, window)) {
+      this._openTabset(urlsToOpen, aEvent, window);
+    }
+  },
+
+  openURINodesInTabs: function PUIU_openURINodesInTabs(aNodes, aEvent, aView) {
+    let window = aView.ownerWindow;
+
     let urlsToOpen = [];
-
-    if (PlacesUtils.nodeIsContainer(nodeOrNodes)) {
-      urlsToOpen = PlacesUtils.getURLsForContainerNode(nodeOrNodes);
-    } else {
-      for (var i = 0; i < nodeOrNodes.length; i++) {
-        // Skip over separators and folders.
-        if (PlacesUtils.nodeIsURI(nodeOrNodes[i])) {
-          urlsToOpen.push({uri: nodeOrNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(nodeOrNodes[i])});
-        }
-      }
+    for (var i = 0; i < aNodes.length; i++) {
+      // Skip over separators and folders.
+      if (PlacesUtils.nodeIsURI(aNodes[i]))
+        urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])});
     }
-    if (OpenInTabsUtils.confirmOpenInTabs(urlsToOpen.length, window)) {
-      this._openTabset(urlsToOpen, event, window);
-    }
+    this._openTabset(urlsToOpen, aEvent, window);
   },
 
   /**
    * Loads the node's URL in the appropriate tab or window given the
    * user's preference specified by modifier keys tracked by a
    * DOM mouse/key event.
    * @param   aNode
    *          An uri result node.
@@ -961,17 +951,17 @@ var PlacesUIUtils = {
                      (event.button == 1 || (event.button == 0 && modifKey)) &&
                      PlacesUtils.hasChildURIs(tree.view.nodeForTreeIndex(cell.row));
 
     if (event.button == 0 && isContainer && !openInTabs) {
       tbo.view.toggleOpenState(cell.row);
     } else if (!mouseInGutter && openInTabs &&
                event.originalTarget.localName == "treechildren") {
       tbo.view.selection.select(cell.row);
-      this.openMultipleLinksInTabs(tree.selectedNode, event, tree);
+      this.openContainerNodeInTabs(tree.selectedNode, event, tree);
     } else if (!mouseInGutter && !isContainer &&
                event.originalTarget.localName == "treechildren") {
       // Clear all other selection since we're loading a link now. We must
       // do this *before* attempting to load the link since openURL uses
       // selection as an indication of which link to load.
       tbo.view.selection.select(cell.row);
       this.openNodeWithEvent(tree.selectedNode, event);
     }
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -641,17 +641,20 @@ PlacesController.prototype = {
    */
   openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
     var node = this._view.selectedNode;
     var nodes = this._view.selectedNodes;
     // In the case of no selection, open the root node:
     if (!node && !nodes.length) {
       node = this._view.result.root;
     }
-    PlacesUIUtils.openMultipleLinksInTabs(node ? node : nodes, aEvent, this._view);
+    if (node && PlacesUtils.nodeIsContainer(node))
+      PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._view);
+    else
+      PlacesUIUtils.openURINodesInTabs(nodes, aEvent, this._view);
   },
 
   /**
    * Shows the Add Bookmark UI for the current insertion point.
    *
    * @param aType
    *        the type of the new item (bookmark/folder)
    */
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -348,17 +348,17 @@ var PlacesOrganizer = {
 
     let node = this._places.selectedNode;
     if (node) {
       let middleClick = aEvent.button == 1 && aEvent.detail == 1;
       if (middleClick && PlacesUtils.nodeIsContainer(node)) {
         // The command execution function will take care of seeing if the
         // selection is a folder or a different container type, and will
         // load its contents in tabs.
-        PlacesUIUtils.openMultipleLinksInTabs(node, aEvent, this._places);
+        PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._places);
       }
     }
   },
 
   /**
    * Handle focus changes on the places list and the current content view.
    */
   updateDetailsPane: function PO_updateDetailsPane() {
@@ -1290,17 +1290,17 @@ var ContentTree = {
       let middleClick = aEvent.button == 1 && aEvent.detail == 1;
       if (PlacesUtils.nodeIsURI(node) && (doubleClick || middleClick)) {
         // Open associated uri in the browser.
         this.openSelectedNode(aEvent);
       } else if (middleClick && PlacesUtils.nodeIsContainer(node)) {
         // The command execution function will take care of seeing if the
         // selection is a folder or a different container type, and will
         // load its contents in tabs.
-        PlacesUIUtils.openMultipleLinksInTabs(node, aEvent, this.view);
+        PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this.view);
       }
     }
   },
 
   onKeyPress: function CT_onKeyPress(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
       this.openSelectedNode(aEvent);
   },
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -68,17 +68,16 @@ skip-if = (verify && debug && (os == 'ma
 [browser_library_middleclick.js]
 [browser_library_new_bookmark.js]
 [browser_library_open_leak.js]
 [browser_library_openFlatContainer.js]
 [browser_library_open_bookmark.js]
 [browser_library_panel_leak.js]
 [browser_library_search.js]
 [browser_library_views_liveupdate.js]
-[browser_library_warnOnOpen.js]
 [browser_markPageAsFollowedLink.js]
 [browser_panelview_bookmarks_delete.js]
 [browser_paste_bookmarks.js]
 subsuite = clipboard
 [browser_paste_into_tags.js]
 [browser_paste_resets_cut_highlights.js]
 subsuite = clipboard
 [browser_remove_bookmarks.js]
deleted file mode 100644
--- a/browser/components/places/tests/browser/browser_library_warnOnOpen.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Bug 1435562 - Test that browser.tabs.warnOnOpen is respected when
- * opening multiple items from the Library. */
-
-"use strict";
-
-var gLibrary = null;
-
-add_task(async function setup() {
-  // Temporarily disable history, so we won't record pages navigation.
-  await SpecialPowers.pushPrefEnv({set: [
-    ["places.history.enabled", false],
-  ]});
-
-  // Open Library window.
-  gLibrary = await promiseLibrary();
-
-  registerCleanupFunction(async () => {
-    // We must close "Other Bookmarks" ready for other tests.
-    gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("UnfiledBookmarks");
-    gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = false;
-
-    await PlacesUtils.bookmarks.eraseEverything();
-
-    // Close Library window.
-    await promiseLibraryClosed(gLibrary);
-  });
-});
-
-add_task(async function test_warnOnOpenFolder() {
-  // Generate a list of links larger than browser.tabs.maxOpenBeforeWarn
-  const MAX_LINKS = 16;
-  let children = [];
-  for (let i = 0; i < MAX_LINKS; i++) {
-    children.push({
-      title: `Folder Target ${i}`,
-      url: `http://example${i}.com`,
-    });
-  }
-
-  // Create a new folder containing our links.
-  await PlacesUtils.bookmarks.insertTree({
-    guid: PlacesUtils.bookmarks.unfiledGuid,
-    children: [{
-      title: "bigFolder",
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      children,
-    }],
-  });
-  info("Pushed test folder into the bookmarks tree");
-
-  // Select unsorted bookmarks root in the left pane.
-  gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("UnfiledBookmarks");
-  info("Got selection in the Library left pane");
-
-  // Get our bookmark in the right pane.
-  gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
-  info("Got bigFolder in the right pane");
-
-  gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = true;
-
-  // Middle-click on folder (opens all links in folder) and then cancel opening in the dialog
-  let promiseLoaded = BrowserTestUtils.promiseAlertDialog("cancel");
-  let bookmarkedNode = gLibrary.PlacesOrganizer._places.selectedNode.getChild(0);
-  mouseEventOnCell(gLibrary.PlacesOrganizer._places,
-    gLibrary.PlacesOrganizer._places.view.treeIndexForNode(bookmarkedNode),
-    0,
-    { button: 1 });
-
-  await promiseLoaded;
-
-  Assert.ok(true, "Expected dialog was shown when attempting to open folder with lots of links");
-
-  await PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(async function test_warnOnOpenLinks() {
-  // Generate a list of links larger than browser.tabs.maxOpenBeforeWarn
-  const MAX_LINKS = 16;
-  let children = [];
-  for (let i = 0; i < MAX_LINKS; i++) {
-    children.push({
-      title: `Highlighted Target ${i}`,
-      url: `http://example${i}.com`,
-    });
-  }
-
-  // Insert the links into the tree
-  await PlacesUtils.bookmarks.insertTree({
-    guid: PlacesUtils.bookmarks.toolbarGuid,
-    children,
-  });
-  info("Pushed test folder into the bookmarks tree");
-
-  gLibrary.PlacesOrganizer.selectLeftPaneBuiltIn("BookmarksToolbar");
-  info("Got selection in the Library left pane");
-
-  // Select all the links
-  gLibrary.ContentTree.view.selectAll();
-
-  let placesContext = gLibrary.document.getElementById("placesContext");
-  let promiseContextMenu = BrowserTestUtils.waitForEvent(placesContext, "popupshown");
-
-  // Open up the context menu and select "Open All In Tabs" (the first item in the list)
-  synthesizeClickOnSelectedTreeCell(gLibrary.ContentTree.view, {
-    button: 2,
-    type: "contextmenu",
-  });
-
-  await promiseContextMenu;
-  info("Context menu opened as expected");
-
-  let openTabs = gLibrary.document.getElementById("placesContext_openLinks:tabs");
-  let promiseLoaded = BrowserTestUtils.promiseAlertDialog("cancel");
-
-  EventUtils.synthesizeMouseAtCenter(openTabs, {}, gLibrary);
-
-  await promiseLoaded;
-
-  Assert.ok(true, "Expected dialog was shown when attempting to open lots of selected links");
-
-  await PlacesUtils.bookmarks.eraseEverything();
-});
-
-function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
-  var selection = aTree.view.selection;
-  selection.select(aRowIndex);
-  aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
-  var column = aTree.columns[aColumnIndex];
-
-  // get cell coordinates
-  var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
-
-  EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
-    aEventDetails, gLibrary);
-}
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -62,17 +62,17 @@ function promiseLibraryClosed(organizer)
 function promiseClipboard(aPopulateClipboardFn, aFlavor) {
   return new Promise((resolve, reject) => {
     waitForClipboard(data => !!data, aPopulateClipboardFn, resolve, reject, aFlavor);
   });
 }
 
 function synthesizeClickOnSelectedTreeCell(aTree, aOptions) {
   let tbo = aTree.treeBoxObject;
-  if (tbo.view.selection.count < 1)
+  if (tbo.view.selection.count != 1)
      throw new Error("The test node should be successfully selected");
   // Get selection rowID.
   let min = {}, max = {};
   tbo.view.selection.getRangeAt(0, min, max);
   let rowID = min.value;
   tbo.ensureRowIsVisible(rowID);
   // Calculate the click coordinates.
   var rect = tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text");
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -91,17 +91,17 @@
               <vbox class="content-blocking-extra-information">
                 <vbox class="indent">
                   <hbox class="extra-information-label">
                     <image class="content-blocking-trackers-image"/>
                     <label data-l10n-id="content-blocking-all-windows-trackers"/>
                   </hbox>
                   <hbox class="extra-information-label">
                     <image class="content-blocking-cookies-image"/>
-                    <label data-l10n-id="content-blocking-all-third-party-cookies"/>
+                    <label data-l10n-id="content-blocking-third-party-cookies"/>
                   </hbox>
                 </vbox>
                 <vbox class="content-blocking-warning">
                   <vbox class="indent">
                     <hbox>
                       <image class="content-blocking-warning-image"/>
                       <label class="content-blocking-warning-title" data-l10n-id="content-blocking-warning-title"/>
                     </hbox>
--- a/browser/components/preferences/in-content/tests/browser_cloud_storage.js
+++ b/browser/components/preferences/in-content/tests/browser_cloud_storage.js
@@ -102,16 +102,17 @@ add_task(async function setup() {
   // Create mock Dropbox discovery and download folder for cloudstorage API
   // to detect dropbox provider app
   // Set prefs required to display second radio option
   // 'Save to Dropbox' under Downloads
   await SpecialPowers.pushPrefEnv({set: [
     [CLOUD_SERVICES_PREF + "api.enabled", true],
     [CLOUD_SERVICES_PREF + "storage.key", "Dropbox"],
   ]});
+
   let folderName = "CloudStorage";
   registerFakePath("Home", folderName);
   registerFakePath("LocalAppData", folderName);
   let status = await mock_dropbox();
   ok(Components.isSuccessCode(status),
     "Cloud Storage: dropbox mockup should be created successfully. status: " + status);
 });
 
@@ -148,11 +149,13 @@ add_task(async function() {
   is(chooseFolder.disabled, false, "chooseFolder button is enabled");
 
   // Test selecting third radio option keeps downloadFolder and chooseFolder elements disabled
   let alwaysAsk = doc.getElementById("alwaysAsk");
   saveToCloud.click();
   alwaysAsk.click();
   is(downloadFolder.disabled, true, "downloadFolder filefield is disabled");
   is(chooseFolder.disabled, true, "chooseFolder button is disabled");
+  saveTo.click();
+  ok(saveTo.selected, "Reset back first option as selected by default");
 
   gBrowser.removeCurrentTab();
 });
--- a/browser/components/preferences/in-content/tests/browser_contentblocking.js
+++ b/browser/components/preferences/in-content/tests/browser_contentblocking.js
@@ -187,17 +187,17 @@ add_task(async function testContentBlock
   strictRadioOption.click();
 
   // TP prefs are reset async to check for extensions controlling them.
   await TestUtils.waitForCondition(() => Services.prefs.prefHasUserValue(TP_PREF));
 
   is(Services.prefs.getStringPref(CAT_PREF), "strict", `${CAT_PREF} has been set to strict`);
   is(Services.prefs.getBoolPref(TP_PREF), true, `${TP_PREF} has been set to true`);
   is(Services.prefs.getBoolPref(TP_PBM_PREF), true, `${TP_PBM_PREF} has been set to true`);
-  is(Services.prefs.getIntPref(NCB_PREF), Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN, `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN}`);
+  is(Services.prefs.getIntPref(NCB_PREF), Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER, `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER}`);
   ok(!Services.prefs.prefHasUserValue(TP_LIST_PREF), `reset the pref ${TP_LIST_PREF}`);
 
   gBrowser.removeCurrentTab();
 });
 
 // Tests that the content blocking "Custom" category behaves as expected.
 add_task(async function testContentBlockingCustomCategory() {
   let prefs = [TP_LIST_PREF, TP_PREF, TP_PBM_PREF, NCB_PREF];
@@ -226,18 +226,18 @@ add_task(async function testContentBlock
   Services.prefs.setBoolPref(TP_PREF, false);
   await TestUtils.waitForCondition(() => !Services.prefs.prefHasUserValue(TP_PREF));
   is(Services.prefs.getStringPref(CAT_PREF), "custom", `${CAT_PREF} has been set to custom`);
 
   strictRadioOption.click();
   await TestUtils.waitForCondition(() => Services.prefs.getStringPref(CAT_PREF) == "strict");
 
   // Changing the NCB_PREF should necessarily set CAT_PREF to "custom"
-  Services.prefs.setIntPref(NCB_PREF, 4);
-  await TestUtils.waitForCondition(() => !Services.prefs.prefHasUserValue(NCB_PREF));
+  Services.prefs.setIntPref(NCB_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
+  await TestUtils.waitForCondition(() => Services.prefs.prefHasUserValue(NCB_PREF));
   is(Services.prefs.getStringPref(CAT_PREF), "custom", `${CAT_PREF} has been set to custom`);
 
   gBrowser.removeCurrentTab();
 });
 
 function checkControlState(doc, controls, enabled) {
   for (let selector of controls) {
     for (let control of doc.querySelectorAll(selector)) {
new file mode 100644
--- /dev/null
+++ b/browser/components/search/.eslintrc.js
@@ -0,0 +1,31 @@
+"use strict";
+
+module.exports = {
+  rules: {
+    "mozilla/var-only-at-top-level": "error",
+    "require-jsdoc": ["error", {
+        "require": {
+            "FunctionDeclaration": false,
+            "MethodDefinition": false,
+            "ClassDeclaration": true,
+            "ArrowFunctionExpression": false,
+            "FunctionExpression": false
+        }
+    }],
+    "valid-jsdoc": ["error", {
+      prefer: {
+        return: "returns",
+      },
+      preferType: {
+        Boolean: "boolean",
+        Number: "number",
+        String: "string",
+        Object: "object",
+        bool: "boolean",
+      },
+      requireParamDescription: false,
+      requireReturn: false,
+      requireReturnDescription: false,
+    }],
+  }
+};
--- a/browser/components/search/SearchTelemetry.jsm
+++ b/browser/components/search/SearchTelemetry.jsm
@@ -7,83 +7,319 @@
 var EXPORTED_SYMBOLS = ["SearchTelemetry"];
 
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", null);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   Services: "resource://gre/modules/Services.jsm",
 });
 
+// The various histograms and scalars that we report to.
 const SEARCH_COUNTS_HISTOGRAM_KEY = "SEARCH_COUNTS";
+const SEARCH_WITH_ADS_SCALAR = "browser.search.with_ads";
+const SEARCH_AD_CLICKS_SCALAR = "browser.search.ad_clicks";
 
-// Used to identify various parameters (query, code, etc.) in search URLS.
+/**
+ * Used to identify various parameters used with partner search providers. This
+ * consists of the following structure:
+ * - {<string>} name
+ *     Details for a particular provider with the string name.
+ * - {regexp} <string>.regexp
+ *     The regular expression used to match the url for the search providers main page.
+ * - {string} <string>.queryParam
+ *     The query parameter name that indicates a search has been made.
+ * - {string} [<string>.codeParam]
+ *     The query parameter name that indicates a search provider's code.
+ * - {array} [<string>.codePrefixes]
+ *     An array of the possible string prefixes for a codeParam, indicating a
+ *     partner search.
+ * - {array} [<string>.followOnParams]
+ *     An array of parameters name that indicates this is a follow-on search.
+ * - {array} [<string>.extraAdServersRegexps]
+ *     An array of regular expressions used to determine if a link on a search
+ *     page mightbe an advert.
+ */
 const SEARCH_PROVIDER_INFO = {
   "google": {
-    "regexp": /^https:\/\/www\.(google)\.(?:.+)\/search/,
+    "regexp": /^https:\/\/www\.google\.(?:.+)\/search/,
     "queryParam": "q",
     "codeParam": "client",
     "codePrefixes": ["firefox"],
     "followonParams": ["oq", "ved", "ei"],
+    "extraAdServersRegexps": [/^https:\/\/www\.googleadservices\.com\/(?:pagead\/)?aclk/],
   },
   "duckduckgo": {
-    "regexp": /^https:\/\/(duckduckgo)\.com\//,
+    "regexp": /^https:\/\/duckduckgo\.com\//,
     "queryParam": "q",
     "codeParam": "t",
     "codePrefixes": ["ff"],
   },
   "yahoo": {
-    "regexp": /^https:\/\/(?:.*)search\.(yahoo)\.com\/search/,
+    "regexp": /^https:\/\/(?:.*)search\.yahoo\.com\/search/,
     "queryParam": "p",
   },
   "baidu": {
-    "regexp": /^https:\/\/www\.(baidu)\.com\/(?:s|baidu)/,
+    "regexp": /^https:\/\/www\.baidu\.com\/(?:s|baidu)/,
     "queryParam": "wd",
     "codeParam": "tn",
     "codePrefixes": ["monline_dg"],
     "followonParams": ["oq"],
   },
   "bing": {
-    "regexp": /^https:\/\/www\.(bing)\.com\/search/,
+    "regexp": /^https:\/\/www\.bing\.com\/search/,
     "queryParam": "q",
     "codeParam": "pc",
     "codePrefixes": ["MOZ", "MZ"],
   },
 };
 
 const BROWSER_SEARCH_PREF = "browser.search.";
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "loggingEnabled", BROWSER_SEARCH_PREF + "log", false);
 
+/**
+ * TelemetryHandler is the main class handling search telemetry. It primarily
+ * deals with tracking of what pages are loaded into tabs.
+ *
+ * It handles the *in-content:sap* keys of the SEARCH_COUNTS histogram.
+ */
 class TelemetryHandler {
   constructor() {
+    this._browserInfoByUrl = new Map();
+    this._initialized = false;
     this.__searchProviderInfo = null;
+    this._contentHandler = new ContentHandler({
+      browserInfoByUrl: this._browserInfoByUrl,
+      getProviderInfoForUrl: this._getProviderInfoForUrl.bind(this),
+    });
+  }
+
+  /**
+   * Initializes the TelemetryHandler and its ContentHandler. It will add
+   * appropriate listeners to the window so that window opening and closing
+   * can be tracked.
+   */
+  init() {
+    if (this._initialized) {
+      return;
+    }
+
+    this._contentHandler.init();
+
+    for (let win of Services.wm.getEnumerator("navigator:browser")) {
+      this._registerWindow(win);
+    }
+    Services.wm.addListener(this);
+
+    this._initialized = true;
   }
 
+  /**
+   * Uninitializes the TelemetryHandler and its ContentHandler.
+   */
+  uninit() {
+    if (!this._initialized) {
+      return;
+    }
+
+    this._contentHandler.uninit();
+
+    for (let win of Services.wm.getEnumerator("navigator:browser")) {
+      this._unregisterWindow(win);
+    }
+    Services.wm.removeListener(this);
+
+    this._initialized = false;
+  }
+
+  /**
+   * Handles the TabClose event received from the listeners.
+   *
+   * @param {object} event
+   */
+  handleEvent(event) {
+    if (event.type != "TabClose") {
+      Cu.reportError(`Received unexpected event type ${event.type}`);
+      return;
+    }
+
+    this.stopTrackingBrowser(event.target.linkedBrowser);
+  }
+
+  /**
+   * Test-only function, used to override the provider information, so that
+   * unit tests can set it to easy to test values.
+   *
+   * @param {object} infoByProvider @see SEARCH_PROVIDER_INFO for type information.
+   */
   overrideSearchTelemetryForTests(infoByProvider) {
     if (infoByProvider) {
       for (let info of Object.values(infoByProvider)) {
         info.regexp = new RegExp(info.regexp);
       }
       this.__searchProviderInfo = infoByProvider;
     } else {
       this.__searchProviderInfo = SEARCH_PROVIDER_INFO;
     }
+    this._contentHandler.overrideSearchTelemetryForTests(this.__searchProviderInfo);
+  }
+
+  /**
+   * This may start tracking a tab based on the URL. If the URL matches a search
+   * partner, and it has a code, then we'll start tracking it. This will aid
+   * determining if it is a page we should be tracking for adverts.
+   *
+   * @param {object} browser The browser associated with the page.
+   * @param {string} url The url that was loaded in the browser.
+   */
+  updateTrackingStatus(browser, url) {
+    let info = this._checkURLForSerpMatch(url);
+    if (!info) {
+      this.stopTrackingBrowser(browser);
+      return;
+    }
+
+    this._reportSerpPage(info, url);
+
+    // If we have a code, then we also track this for potential ad clicks.
+    if (info.code) {
+      let item = this._browserInfoByUrl.get(url);
+      if (item) {
+        item.browsers.add(browser);
+      } else {
+        this._browserInfoByUrl.set(url, {
+          browser: new WeakSet([browser]),
+          info,
+        });
+      }
+    }
+  }
+
+  /**
+   * Stops tracking of a tab, for example the tab has loaded a different URL.
+   *
+   * @param {object} browser The browser associated with the tab to stop being
+   *                         tracked.
+   */
+  stopTrackingBrowser(browser) {
+    for (let [url, item] of this._browserInfoByUrl) {
+      item.browser.delete(browser);
+
+      if (!item.browser.length) {
+        this._browserInfoByUrl.delete(url);
+      }
+    }
   }
 
-  recordSearchURLTelemetry(url) {
-    let entry = Object.entries(this._searchProviderInfo).find(
+  // nsIWindowMediatorListener
+
+  /**
+   * This is called when a new window is opened, and handles registration of
+   * that window if it is a browser window.
+   *
+   * @param {nsIXULWindow} xulWin The xul window that was opened.
+   */
+  onOpenWindow(xulWin) {
+    let win = xulWin.docShell.domWindow;
+    win.addEventListener("load", () => {
+      if (win.document.documentElement.getAttribute("windowtype") != "navigator:browser") {
+        return;
+      }
+
+      this._registerWindow(win);
+    }, {once: true});
+  }
+
+  /**
+   * Listener that is called when a window is closed, and handles deregistration of
+   * that window if it is a browser window.
+   *
+   * @param {nsIXULWindow} xulWin The xul window that was closed.
+   */
+  onCloseWindow(xulWin) {
+    let win = xulWin.docShell.domWindow;
+
+    if (win.document.documentElement.getAttribute("windowtype") != "navigator:browser") {
+      return;
+    }
+
+    this._unregisterWindow(win);
+  }
+
+  /**
+   * Adds event listeners for the window and registers it with the content handler.
+   *
+   * @param {object} win The window to register.
+   */
+  _registerWindow(win) {
+    this._contentHandler.registerWindow(win);
+    win.gBrowser.tabContainer.addEventListener("TabClose", this);
+  }
+
+  /**
+   * Removes event listeners for the window and unregisters it with the content
+   * handler.
+   *
+   * @param {object} win The window to unregister.
+   */
+  _unregisterWindow(win) {
+    for (let tab of win.gBrowser.tabs) {
+      this.stopTrackingBrowser(tab);
+    }
+
+    this._contentHandler.unregisterWindow(win);
+    win.gBrowser.tabContainer.removeEventListener("TabClose", this);
+  }
+
+  /**
+   * Searches for provider information for a given url.
+   *
+   * @param {string} url The url to match for a provider.
+   * @param {boolean} useOnlyExtraAdServers If true, this will use the extra
+   *   ad server regexp to match instead of the main regexp.
+   * @returns {array|null} Returns an array of provider name and the provider information.
+   */
+  _getProviderInfoForUrl(url, useOnlyExtraAdServers = false) {
+    if (useOnlyExtraAdServers) {
+      return Object.entries(this._searchProviderInfo).find(
+        ([_, info]) => {
+          if (info.extraAdServersRegexps) {
+            for (let regexp of info.extraAdServersRegexps) {
+              if (regexp.test(url)) {
+                return true;
+              }
+            }
+          }
+          return false;
+        }
+      );
+    }
+
+    return Object.entries(this._searchProviderInfo).find(
       ([_, info]) => info.regexp.test(url)
     );
-    if (!entry) {
-      return;
+  }
+
+  /**
+   * Checks to see if a url is a search partner location, and determines the
+   * provider and codes used.
+   *
+   * @param {string} url The url to match.
+   * @returns {null|object} Returns null if there is no match found. Otherwise,
+   *   returns an object of strings for provider, code and type.
+   */
+  _checkURLForSerpMatch(url) {
+    let info = this._getProviderInfoForUrl(url);
+    if (!info) {
+      return null;
     }
-    let [provider, searchProviderInfo] = entry;
+    let [provider, searchProviderInfo] = info;
     let queries = new URLSearchParams(url.split("#")[0].split("?")[1]);
     if (!queries.get(searchProviderInfo.queryParam)) {
-      return;
+      return null;
     }
     // Default to organic to simplify things.
     // We override type in the sap cases.
     let type = "organic";
     let code;
     if (searchProviderInfo.codeParam) {
       code = queries.get(searchProviderInfo.codeParam);
       if (code &&
@@ -109,34 +345,206 @@ class TelemetryHandler {
                 code = cookie.value.split("=")[1];
                 break;
               }
             }
           }
         }
       }
     }
+    return {provider, type, code};
+  }
 
-    let payload = `${provider}.in-content:${type}:${code || "none"}`;
+  /**
+   * Logs telemetry for a search provider visit.
+   *
+   * @param {object} info
+   * @param {string} info.provider The name of the provider.
+   * @param {string} info.type The type of search.
+   * @param {string} [info.code] The code for the provider.
+   * @param {string} url The url that was matched (for debug logging only).
+   */
+  _reportSerpPage(info, url) {
+    let payload = `${info.provider}.in-content:${info.type}:${info.code || "none"}`;
     let histogram = Services.telemetry.getKeyedHistogramById(SEARCH_COUNTS_HISTOGRAM_KEY);
     histogram.add(payload);
-    LOG("recordSearchURLTelemetry: " + payload);
+    LOG(`SearchTelemetry::recordSearchURLTelemetry: ${payload} for ${url}`);
   }
 
+  /**
+   * Returns the current search provider information in use.
+   * @see SEARCH_PROVIDER_INFO
+   */
   get _searchProviderInfo() {
     if (!this.__searchProviderInfo) {
       this.__searchProviderInfo = SEARCH_PROVIDER_INFO;
     }
     return this.__searchProviderInfo;
   }
 }
 
 /**
- * Outputs aText to the JavaScript console as well as to stdout.
+ * ContentHandler deals with handling telemetry of the content within a tab -
+ * when ads detected and when they are selected.
+ *
+ * It handles the "browser.search.with_ads" and "browser.search.ad_clicks"
+ * scalars.
  */
-function LOG(aText) {
+class ContentHandler {
+  /**
+   * Constructor.
+   *
+   * @param {object} options
+   * @param {Map} options.browserInfoByUrl The  map of urls from TelemetryHandler.
+   * @param {function} options.getProviderInfoForUrl A function that obtains
+   *   the provider information for a url.
+   */
+  constructor(options) {
+    this._browserInfoByUrl = options.browserInfoByUrl;
+    this._getProviderInfoForUrl = options.getProviderInfoForUrl;
+  }
+
+  /**
+   * Initializes the content handler. This will also set up the shared data that is
+   * shared with the SearchTelemetryChild actor.
+   */
+  init() {
+    Services.ppmm.sharedData.set("SearchTelemetry:ProviderInfo", SEARCH_PROVIDER_INFO);
+
+    Cc["@mozilla.org/network/http-activity-distributor;1"]
+      .getService(Ci.nsIHttpActivityDistributor)
+      .addObserver(this);
+  }
+
+  /**
+   * Uninitializes the content handler.
+   */
+  uninit() {
+    Cc["@mozilla.org/network/http-activity-distributor;1"]
+      .getService(Ci.nsIHttpActivityDistributor)
+      .removeObserver(this);
+  }
+
+  /**
+   * Receives a message from the SearchTelemetryChild actor.
+   *
+   * @param {object} msg
+   */
+  receiveMessage(msg) {
+    if (msg.name != "SearchTelemetry:PageInfo") {
+      LOG(`"Received unexpected message: ${msg.name}`);
+      return;
+    }
+
+    this._reportPageWithAds(msg.data);
+  }
+
+  /**
+   * Test-only function to override the search provider information for use
+   * with tests. Passes it to the SearchTelemetryChild actor.
+   *
+   * @param {object} providerInfo @see SEARCH_PROVIDER_INFO for type information.
+   */
+  overrideSearchTelemetryForTests(providerInfo) {
+    Services.ppmm.sharedData.set("SearchTelemetry:ProviderInfo", providerInfo);
+  }
+
+  /**
+   * Listener that observes network activity, so that we can determine if a link
+   * from a search provider page was followed, and if then if that link was an
+   * ad click or not.
+   *
+   * @param {nsISupports} httpChannel The channel that generated the activity.
+   * @param {number} activityType The type of activity.
+   * @param {number} activitySubtype The subtype for the activity.
+   * @param {PRTime} timestamp The time of the activity.
+   * @param {number} [extraSizeData] Any size data available for the activity.
+   * @param {string} [extraStringData] Any extra string data available for the
+   *   activity.
+   */
+  observeActivity(httpChannel, activityType, activitySubtype, timestamp, extraSizeData, extraStringData) {
+    if (!this._browserInfoByUrl.size ||
+        activityType != Ci.nsIHttpActivityObserver.ACTIVITY_TYPE_HTTP_TRANSACTION ||
+        activitySubtype != Ci.nsIHttpActivityObserver.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE) {
+      return;
+    }
+
+    let channel = httpChannel.QueryInterface(Ci.nsIHttpChannel);
+    let loadInfo;
+    try {
+      loadInfo = channel.loadInfo;
+    } catch (e) {
+      // Channels without a loadInfo are not pertinent.
+      return;
+    }
+
+    try {
+      let uri = channel.URI;
+      let triggerURI = loadInfo.triggeringPrincipal.URI;
+
+      if (!triggerURI || !this._browserInfoByUrl.has(triggerURI.spec)) {
+        return;
+      }
+
+      let info = this._getProviderInfoForUrl(uri.spec, true);
+      if (!info) {
+        return;
+      }
+
+      Services.telemetry.keyedScalarAdd(SEARCH_AD_CLICKS_SCALAR, info[0], 1);
+      LOG(`SearchTelemetry::recordSearchURLTelemetry: Counting ad click in page for ${info[0]} ${triggerURI.spec}`);
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  }
+
+  /**
+   * Adds a message listener for the window being registered to receive messages
+   * from SearchTelemetryChild.
+   *
+   * @param {object} win The window to register.
+   */
+  registerWindow(win) {
+    win.messageManager.addMessageListener("SearchTelemetry:PageInfo", this);
+  }
+
+  /**
+   * Removes the message listener for the window.
+   *
+   * @param {object} win The window to unregister.
+   */
+  unregisterWindow(win) {
+    win.messageManager.removeMessageListener("SearchTelemetry:PageInfo", this);
+  }
+
+  /**
+   * Logs telemetry for a page with adverts, if it is one of the partner search
+   * provider pages that we're tracking.
+   *
+   * @param {object} info
+   * @param {boolean} info.hasAds Whether or not the page has adverts.
+   * @param {string} info.url The url of the page.
+   */
+  _reportPageWithAds(info) {
+    let item = this._browserInfoByUrl.get(info.url);
+    if (!item) {
+      LOG(`Expected to report URI with ads but couldn't find the information`);
+      return;
+    }
+
+    Services.telemetry.keyedScalarAdd(SEARCH_WITH_ADS_SCALAR, item.info.provider, 1);
+    LOG(`SearchTelemetry::recordSearchURLTelemetry: Counting ads in page for ${item.info.provider} ${info.url}`);
+  }
+}
+
+/**
+ * Outputs the message to the JavaScript console as well as to stdout.
+ *
+ * @param {string} msg The message to output.
+ */
+function LOG(msg) {
   if (loggingEnabled) {
-    dump(`*** SearchTelemetry: ${aText}\n"`);
-    Services.console.logStringMessage(aText);
+    dump(`*** SearchTelemetry: ${msg}\n"`);
+    Services.console.logStringMessage(msg);
   }
 }
 
 var SearchTelemetry = new TelemetryHandler();
--- a/browser/components/search/content/search-one-offs.js
+++ b/browser/components/search/content/search-one-offs.js
@@ -2,16 +2,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /* eslint-env mozilla/browser-window */
 /* globals XULCommandEvent */
 
+/**
+ * Defines the search one-off button elements. These are displayed at the bottom
+ * of the address bar or the search bar.
+ */
 class SearchOneOffs {
   constructor(container) {
     this.container = container;
 
     this.container.appendChild(MozXULElement.parseXULToFragment(`
       <deck class="search-panel-one-offs-header search-panel-header search-panel-current-input">
         <label class="searchbar-oneoffheader-search" value="&searchWithHeader.label;"/>
         <hbox class="search-panel-searchforwith search-panel-current-input">
@@ -161,20 +165,24 @@ class SearchOneOffs {
   /**
    * Width in pixels of the one-off buttons.  49px is the min-width of
    * each search engine button, adapt this const when changing the css.
    * It's actually 48px + 1px of right border.
    */
   get buttonWidth() {
     return 49;
   }
+
   /**
    * The popup that contains the one-offs.  This is required, so it should
    * never be null or undefined, except possibly before the one-offs are
    * used.
+   *
+   * @param {DOMElement} val
+   *        The new value to set.
    */
   set popup(val) {
     let events = [
       "popupshowing",
       "popuphidden",
     ];
     if (this._popup) {
       for (let event of events) {
@@ -202,16 +210,19 @@ class SearchOneOffs {
     return this._popup;
   }
 
   /**
    * The textbox associated with the one-offs.  Set this to a textbox to
    * automatically keep the related one-offs UI up to date.  Otherwise you
    * can leave it null/undefined, and in that case you should update the
    * query property manually.
+   *
+   * @param {DOMElement} val
+   *        The new value to set.
    */
   set textbox(val) {
     if (this._textbox) {
       this._textbox.removeEventListener("input", this);
     }
     if (val) {
       val.addEventListener("input", this);
     }
@@ -225,31 +236,38 @@ class SearchOneOffs {
   get textbox() {
     return this._textbox;
   }
 
   /**
    * The query string currently shown in the one-offs.  If the textbox
    * property is non-null, then this is automatically updated on
    * input.
+   *
+   * @param {string} val
+   *        The new query string to set.
    */
   set query(val) {
     this._query = val;
     if (this.popup && this.popup.popupOpen) {
       this._updateAfterQueryChanged();
     }
     return val;
   }
 
   get query() {
     return this._query;
   }
+
   /**
    * The selected one-off, a xul:button, including the add-engine button
-   * and the search-settings button.  Null if no one-off is selected.
+   * and the search-settings button.
+   *
+   * @param {DOMElement|null} val
+   *        The selected one-off button. Null if no one-off is selected.
    */
   set selectedButton(val) {
     if (val && val.classList.contains("dummy")) {
       // Never select dummy buttons.
       val = null;
     }
     let previousButton = this._selectedButton;
     if (previousButton) {
@@ -271,19 +289,23 @@ class SearchOneOffs {
     });
     this.dispatchEvent(event);
     return val;
   }
 
   get selectedButton() {
     return this._selectedButton;
   }
+
   /**
    * The index of the selected one-off, including the add-engine button
-   * and the search-settings button.  -1 if no one-off is selected.
+   * and the search-settings button.
+   *
+   * @param {number} val
+   *        The new index to set, -1 for nothing selected.
    */
   set selectedButtonIndex(val) {
     let buttons = this.getSelectableButtons(true);
     this.selectedButton = buttons[val];
     return val;
   }
 
   get selectedButtonIndex() {
@@ -617,17 +639,17 @@ class SearchOneOffs {
     return this._popup &&
       document.getAnonymousElementByAttribute(this._popup, "id", this._buttonIDForEngine(engine));
   }
 
   /**
    * Updates the popup and textbox for the currently selected or moused-over
    * button.
    *
-   * @param mousedOverButton
+   * @param {DOMElement} mousedOverButton
    *        The currently moused-over button, or null if there isn't one.
    */
   _updateStateForButton(mousedOverButton) {
     let button = mousedOverButton;
 
     // Ignore dummy buttons.
     if (button && button.classList.contains("dummy")) {
       button = null;
@@ -691,17 +713,17 @@ class SearchOneOffs {
     if (aForceNewTab) {
       where = "tab";
       if (Services.prefs.getBoolPref("browser.tabs.loadInBackground")) {
         params = {
           inBackground: true,
         };
       }
     } else {
-      var newTabPref = Services.prefs.getBoolPref("browser.search.openintab");
+      let newTabPref = Services.prefs.getBoolPref("browser.search.openintab");
       if ((aEvent instanceof KeyboardEvent && aEvent.altKey) ^ newTabPref &&
           !gBrowser.selectedTab.isEmpty) {
         where = "tab";
       }
       if (aEvent instanceof MouseEvent &&
           (aEvent.button == 1 || aEvent.getModifierState("Accel"))) {
         where = "tab";
         params = {
@@ -711,33 +733,31 @@ class SearchOneOffs {
     }
 
     this.popup.handleOneOffSearch(aEvent, aEngine, where, params);
   }
 
   /**
    * Increments or decrements the index of the currently selected one-off.
    *
-   * @param aForward
+   * @param {boolean} aForward
    *        If true, the index is incremented, and if false, the index is
    *        decremented.
-   * @param aIncludeNonEngineButtons
+   * @param {boolean} aIncludeNonEngineButtons
    *        If true, non-dummy buttons that do not have engines are included.
    *        These buttons include the OpenSearch and settings buttons.  For
    *        example, if the currently selected button is an engine button,
    *        the next button is the settings button, and you pass true for
    *        aForward, then passing true for this value would cause the
    *        settings to be selected.  Passing false for this value would
    *        cause the selection to clear or wrap around, depending on what
    *        value you passed for the aWrapAround parameter.
-   * @param aWrapAround
+   * @param {boolean} aWrapAround
    *        If true, the selection wraps around between the first and last
    *        buttons.
-   * @return True if the selection can continue to advance after this method
-   *         returns and false if not.
    */
   advanceSelection(aForward, aIncludeNonEngineButtons, aWrapAround) {
     let buttons = this.getSelectableButtons(aIncludeNonEngineButtons);
     let index;
     if (this.selectedButton) {
       let inc = aForward ? 1 : -1;
       let oldIndex = buttons.indexOf(this.selectedButton);
       index = (oldIndex + inc + buttons.length) % buttons.length;
@@ -759,28 +779,28 @@ class SearchOneOffs {
    * Alt+Up/Down, and Up/Down keys within the buttons.  Since one-off buttons
    * are always used in conjunction with a list of some sort (in this.popup),
    * it also handles Up/Down keys that cross the boundaries between list
    * items and the one-off buttons.
    *
    * If this method handles the key press, then event.defaultPrevented will
    * be true when it returns.
    *
-   * @param event
+   * @param {Event} event
    *        The key event.
-   * @param numListItems
+   * @param {number} numListItems
    *        The number of items in the list.  The reason that this is a
    *        parameter at all is that the list may contain items at the end
    *        that should be ignored, depending on the consumer.  That's true
    *        for the urlbar for example.
-   * @param allowEmptySelection
+   * @param {boolean} allowEmptySelection
    *        Pass true if it's OK that neither the list nor the one-off
    *        buttons contains a selection.  Pass false if either the list or
    *        the one-off buttons (or both) should always contain a selection.
-   * @param textboxUserValue
+   * @param {string} [textboxUserValue]
    *        When the last list item is selected and the user presses Down,
    *        the first one-off becomes selected and the textbox value is
    *        restored to the value that the user typed.  Pass that value here.
    *        However, if you pass true for allowEmptySelection, you don't need
    *        to pass anything for this parameter.  (Pass undefined or null.)
    */
   handleKeyPress(event, numListItems, allowEmptySelection, textboxUserValue) {
     if (!this.popup) {
@@ -960,23 +980,23 @@ class SearchOneOffs {
     return false;
   }
 
   /**
    * If the given event is related to the one-offs, this method records
    * one-off telemetry for it.  this.telemetryOrigin will be appended to the
    * computed source, so make sure you set that first.
    *
-   * @param aEvent
+   * @param {Event} aEvent
    *        An event, like a click on a one-off button.
-   * @param aOpenUILinkWhere
+   * @param {string} aOpenUILinkWhere
    *        The "where" passed to openUILink.
-   * @param aOpenUILinkParams
+   * @param {object} aOpenUILinkParams
    *        The "params" passed to openUILink.
-   * @return True if telemetry was recorded and false if not.
+   * @returns {boolean} True if telemetry was recorded and false if not.
    */
   maybeRecordTelemetry(aEvent, aOpenUILinkWhere, aOpenUILinkParams) {
     if (!aEvent) {
       return false;
     }
 
     let source = null;
     let type = "unknown";
@@ -1228,9 +1248,8 @@ class SearchOneOffs {
     Services.tm.dispatchToMainThread(() => {
       this.selectedButton = null;
       this._contextEngine = null;
     });
   }
 }
 
 window.SearchOneOffs = SearchOneOffs;
-
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -22,22 +22,22 @@
       <constructor><![CDATA[
         if (this.closest("searchbar").parentNode.parentNode.localName ==
             "toolbarpaletteitem")
           return;
 
         if (Services.prefs.getBoolPref("browser.urlbar.clickSelectsAll"))
           this.setAttribute("clickSelectsAll", true);
 
-        var textBox = document.getAnonymousElementByAttribute(this,
+        let textBox = document.getAnonymousElementByAttribute(this,
                                               "anonid", "moz-input-box");
 
         // Force the Custom Element to upgrade until Bug 1470242 handles this:
         customElements.upgrade(textBox);
-        var cxmenu = textBox.menupopup;
+        let cxmenu = textBox.menupopup;
         cxmenu.addEventListener("popupshowing",
                                 () => { this.initContextMenu(cxmenu); },
                                 {capture: true, once: true});
 
         this.setAttribute("aria-owns", this.popup.id);
         this.closest("searchbar")._textboxInitialized = true;
       ]]></constructor>
 
@@ -162,17 +162,17 @@
         <body><![CDATA[
           // Entering customization mode after the search bar had focus causes
           // the popup to appear again, due to focus returning after the
           // hamburger panel closes. Don't open in that spurious event.
           if (document.documentElement.getAttribute("customizing") == "true") {
             return;
           }
 
-          var popup = this.popup;
+          let popup = this.popup;
           if (!popup.mPopupOpen) {
             // Initially the panel used for the searchbar (PopupSearchAutoComplete
             // in browser.xul) is hidden to avoid impacting startup / new
             // window performance. The base binding's openPopup would normally
             // call the overriden openAutocompletePopup in
             // browser-search-autocomplete-result-popup binding to unhide the popup,
             // but since we're overriding openPopup we need to unhide the panel
             // ourselves.
@@ -184,27 +184,27 @@
             }
 
             popup.mInput = this;
             // clear any previous selection, see bugs 400671 and 488357
             popup.selectedIndex = -1;
 
             document.popupNode = null;
 
-            var outerRect = this.getBoundingClientRect();
-            var innerRect = this.inputField.getBoundingClientRect();
+            let outerRect = this.getBoundingClientRect();
+            let innerRect = this.inputField.getBoundingClientRect();
             let width = RTL_UI ?
                         innerRect.right - outerRect.left :
                         outerRect.right - innerRect.left;
             popup.setAttribute("width", width > 100 ? width : 100);
 
             // invalidate() depends on the width attribute
             popup._invalidate();
 
-            var yOffset = outerRect.bottom - innerRect.bottom;
+            let yOffset = outerRect.bottom - innerRect.bottom;
             popup.openPopup(this.inputField, "after_start", 0, yOffset, false, false);
           }
         ]]></body>
       </method>
 
       <method name="openSearch">
         <body>
           <![CDATA[
@@ -294,17 +294,17 @@
 
         isCommandEnabled(aCommand) {
           return true;
         },
 
         doCommand(aCommand) {
           switch (aCommand) {
             case "cmd_clearhistory":
-              var param = this._self.getAttribute("autocompletesearchparam");
+              let param = this._self.getAttribute("autocompletesearchparam");
 
               BrowserSearch.searchBar.FormHistory.update({ op: "remove", fieldname: param }, null);
               this._self.value = "";
               break;
             case "cmd_togglesuggest":
               let enabled =
                 Services.prefs.getBoolPref("browser.search.suggest.enabled");
               Services.prefs.setBoolPref("browser.search.suggest.enabled",
@@ -338,26 +338,26 @@
                action="return this.openSearch();"/>
 
       <handler event="keypress" keycode="VK_UP" modifiers="alt"
                phase="capturing"
                action="return this.openSearch();"/>
 
       <handler event="dragover">
       <![CDATA[
-        var types = event.dataTransfer.types;
+        let types = event.dataTransfer.types;
         if (types.includes("text/plain") || types.includes("text/x-moz-text-internal"))
           event.preventDefault();
       ]]>
       </handler>
 
       <handler event="drop">
       <![CDATA[
-        var dataTransfer = event.dataTransfer;
-        var data = dataTransfer.getData("text/plain");
+        let dataTransfer = event.dataTransfer;
+        let data = dataTransfer.getData("text/plain");
         if (!data)
           data = dataTransfer.getData("text/x-moz-text-internal");
         if (data) {
           event.preventDefault();
           this.value = data;
           this.closest("searchbar").openSuggestionsPanel();
         }
       ]]>
@@ -393,18 +393,18 @@
 
       <method name="onPopupClick">
         <parameter name="aEvent"/>
         <body><![CDATA[
           // Ignore all right-clicks
           if (aEvent.button == 2)
             return;
 
-          var searchBar = BrowserSearch.searchBar;
-          var popupForSearchBar = searchBar && searchBar.textbox == this.mInput;
+          let searchBar = BrowserSearch.searchBar;
+          let popupForSearchBar = searchBar && searchBar.textbox == this.mInput;
           if (popupForSearchBar) {
             searchBar.telemetrySearchDetails = {
               index: this.selectedIndex,
               kind: "mouse",
             };
           }
 
           // Check for unmodified left-click, and use default behavior
@@ -417,20 +417,20 @@
           // Check for middle-click or modified clicks on the search bar
           if (popupForSearchBar) {
             BrowserUsageTelemetry.recordSearchbarSelectedResultMethod(
               aEvent,
               this.selectedIndex
             );
 
             // Handle search bar popup clicks
-            var search = this.input.controller.getValueAt(this.selectedIndex);
+            let search = this.input.controller.getValueAt(this.selectedIndex);
 
             // open the search results according to the clicking subtlety
-            var where = whereToOpenLink(aEvent, false, true);
+            let where = whereToOpenLink(aEvent, false, true);
             let params = {};
 
             // But open ctrl/cmd clicks on autocomplete items in a new background tab.
             let modifier = AppConstants.platform == "macosx" ?
                            aEvent.metaKey :
                            aEvent.ctrlKey;
             if (where == "tab" && (aEvent instanceof MouseEvent) &&
                 (aEvent.button == 1 || modifier))
--- a/browser/components/search/content/searchbar.js
+++ b/browser/components/search/content/searchbar.js
@@ -18,21 +18,24 @@ const inheritsMap = {
 function inheritAttribute(parent, child, attr) {
   if (!parent.hasAttribute(attr)) {
     child.removeAttribute(attr);
   } else {
     child.setAttribute(attr, parent.getAttribute(attr));
   }
 }
 
+/**
+ * Defines the search bar element.
+ */
 class MozSearchbar extends MozXULElement {
 
   static get observedAttributes() {
     let unique = new Set();
-    for (var i in inheritsMap) {
+    for (let i in inheritsMap) {
       inheritsMap[i].forEach(attr => unique.add(attr));
     }
     return Array.from(unique);
   }
 
   attributeChangedCallback() {
     this.inheritAttributes();
   }
@@ -157,17 +160,17 @@ class MozSearchbar extends MozXULElement
   }
 
   set currentEngine(val) {
     Services.search.defaultEngine = val;
     return val;
   }
 
   get currentEngine() {
-    var currentEngine = Services.search.defaultEngine;
+    let currentEngine = Services.search.defaultEngine;
     // Return a dummy engine if there is no currentEngine
     return currentEngine || { name: "", uri: null };
   }
   /**
    * textbox is used by sanitize.js to clear the undo history when
    * clearing form information.
    */
   get textbox() {
@@ -208,21 +211,21 @@ class MozSearchbar extends MozXULElement
     this._textbox.select();
   }
 
   setIcon(element, uri) {
     element.setAttribute("src", uri);
   }
 
   updateDisplay() {
-    var uri = this.currentEngine.iconURI;
+    let uri = this.currentEngine.iconURI;
     this.setIcon(this, uri ? uri.spec : "");
 
-    var name = this.currentEngine.name;
-    var text = this._stringBundle.getFormattedString("searchtip", [name]);
+    let name = this.currentEngine.name;
+    let text = this._stringBundle.getFormattedString("searchtip", [name]);
     this._textbox.label = text;
     this._textbox.tooltipText = text;
   }
 
   updateGoButtonVisibility() {
     this.querySelector(".search-go-button").hidden = !this._textbox.value;
   }
 
@@ -238,44 +241,44 @@ class MozSearchbar extends MozXULElement
       this._textbox.mController.handleText();
     } else if (aShowOnlySettingsIfEmpty) {
       this.setAttribute("showonlysettings", "true");
     }
   }
 
   selectEngine(aEvent, isNextEngine) {
     // Find the new index
-    var newIndex = this.engines.indexOf(this.currentEngine);
+    let newIndex = this.engines.indexOf(this.currentEngine);
     newIndex += isNextEngine ? 1 : -1;
 
     if (newIndex >= 0 && newIndex < this.engines.length) {
       this.currentEngine = this.engines[newIndex];
     }
 
     aEvent.preventDefault();
     aEvent.stopPropagation();
 
     this.openSuggestionsPanel();
   }
 
   handleSearchCommand(aEvent, aEngine, aForceNewTab) {
-    var where = "current";
+    let where = "current";
     let params;
 
     // Open ctrl/cmd clicks on one-off buttons in a new background tab.
     if (aEvent && aEvent.originalTarget.classList.contains("search-go-button")) {
       if (aEvent.button == 2)
         return;
       where = whereToOpenLink(aEvent, false, true);
     } else if (aForceNewTab) {
       where = "tab";
       if (Services.prefs.getBoolPref("browser.tabs.loadInBackground"))
         where += "-background";
     } else {
-      var newTabPref = Services.prefs.getBoolPref("browser.search.openintab");
+      let newTabPref = Services.prefs.getBoolPref("browser.search.openintab");
       if (((aEvent instanceof KeyboardEvent && aEvent.altKey) ^ newTabPref) &&
         !gBrowser.selectedTab.isEmpty) {
         where = "tab";
       }
       if ((aEvent instanceof MouseEvent) &&
         (aEvent.button == 1 || aEvent.getModifierState("Accel"))) {
         where = "tab";
         params = {
@@ -283,18 +286,18 @@ class MozSearchbar extends MozXULElement
         };
       }
     }
 
     this.handleSearchCommandWhere(aEvent, aEngine, where, params);
   }
 
   handleSearchCommandWhere(aEvent, aEngine, aWhere, aParams) {
-    var textBox = this._textbox;
-    var textValue = textBox.value;
+    let textBox = this._textbox;
+    let textValue = textBox.value;
 
     let selection = this.telemetrySearchDetails;
     let oneOffRecorded = false;
 
     BrowserUsageTelemetry.recordSearchbarSelectedResultMethod(
       aEvent,
       selection ? selection.index : -1
     );
@@ -330,33 +333,33 @@ class MozSearchbar extends MozXULElement
     // This is a one-off search only if oneOffRecorded is true.
     this.doSearch(textValue, aWhere, aEngine, aParams, oneOffRecorded);
 
     if (aWhere == "tab" && aParams && aParams.inBackground)
       this.focus();
   }
 
   doSearch(aData, aWhere, aEngine, aParams, aOneOff) {
-    var textBox = this._textbox;
+    let textBox = this._textbox;
 
     // Save the current value in the form history
     if (aData && !PrivateBrowsingUtils.isWindowPrivate(window) && this.FormHistory.enabled) {
       this.FormHistory.update({
         op: "bump",
         fieldname: textBox.getAttribute("autocompletesearchparam"),
         value: aData,
       }, {
         handleError(aError) {
           Cu.reportError("Saving search to form history failed: " + aError.message);
         },
       });
     }
 
     let engine = aEngine || this.currentEngine;
-    var submission = engine.getSubmission(aData, null, "searchbar");
+    let submission = engine.getSubmission(aData, null, "searchbar");
     let telemetrySearchDetails = this.telemetrySearchDetails;
     this.telemetrySearchDetails = null;
     if (telemetrySearchDetails && telemetrySearchDetails.index == -1) {
       telemetrySearchDetails = null;
     }
     // If we hit here, we come either from a one-off, a plain search or a suggestion.
     const details = {
       isOneOff: aOneOff,
@@ -385,17 +388,17 @@ class MozSearchbar extends MozXULElement
 
   _setupEventListeners() {
     this.addEventListener("command", (event) => {
       const target = event.originalTarget;
       if (target.engine) {
         this.currentEngine = target.engine;
       } else if (target.classList.contains("addengine-item")) {
         // Select the installed engine if the installation succeeds
-        var installCallback = {
+        let installCallback = {
           onSuccess: engine => this.currentEngine = engine,
         };
         Services.search.addEngine(target.getAttribute("uri"), null,
           target.getAttribute("src"), false,
           installCallback);
       } else
         return;
 
--- a/browser/components/search/test/browser/SearchTestUtils.jsm
+++ b/browser/components/search/test/browser/SearchTestUtils.jsm
@@ -15,17 +15,17 @@ var SearchTestUtils = Object.freeze({
       registerCleanupFunction,
     };
   },
 
   /**
    * Adds a search engine to the search service. It will remove the engine
    * at the end of the test.
    *
-   * @param {String}   url                     The URL of the engine to add.
+   * @param {string}   url                     The URL of the engine to add.
    * @param {Function} registerCleanupFunction Pass the registerCleanupFunction
    *                                           from the test's scope.
    * @returns {Promise} Returns a promise that is resolved with the new engine
    *                    or rejected if it fails.
    */
   promiseNewSearchEngine(url) {
     return new Promise((resolve, reject) => {
       Services.search.addEngine(url, "", false, {
--- a/browser/components/search/test/browser/browser.ini
+++ b/browser/components/search/test/browser/browser.ini
@@ -41,10 +41,14 @@ skip-if = os == "mac" #1421238
 [browser_aboutSearchReset.js]
 disabled = bug 1488946 - Telemetry probe needs extension
 [browser_searchbar_openpopup.js]
 skip-if = os == "linux" # Linux has different focus behaviours.
 [browser_searchbar_keyboard_navigation.js]
 [browser_searchbar_smallpanel_keyboard_navigation.js]
 [browser_searchEngine_behaviors.js]
 skip-if = artifact # bug 1315953
+[browser_searchTelemetry.js]
+support-files =
+  searchTelemetry.html
+  searchTelemetryAd.html
 [browser_webapi.js]
 [browser_tooManyEnginesOffered.js]
--- a/browser/components/search/test/browser/browser_426329.js
+++ b/browser/components/search/test/browser/browser_426329.js
@@ -1,37 +1,37 @@
 /* eslint-disable mozilla/no-arbitrary-setTimeout */
 ChromeUtils.defineModuleGetter(this, "FormHistory",
   "resource://gre/modules/FormHistory.jsm");
 
 function expectedURL(aSearchTerms) {
   const ENGINE_HTML_BASE = "http://mochi.test:8888/browser/browser/components/search/test/browser/test.html";
-  var searchArg = Services.textToSubURI.ConvertAndEscape("utf-8", aSearchTerms);
+  let searchArg = Services.textToSubURI.ConvertAndEscape("utf-8", aSearchTerms);
   return ENGINE_HTML_BASE + "?test=" + searchArg;
 }
 
 function simulateClick(aEvent, aTarget) {
-  var event = document.createEvent("MouseEvent");
-  var ctrlKeyArg  = aEvent.ctrlKey || false;
-  var altKeyArg   = aEvent.altKey || false;
-  var shiftKeyArg = aEvent.shiftKey || false;
-  var metaKeyArg  = aEvent.metaKey || false;
-  var buttonArg   = aEvent.button || 0;
+  let event = document.createEvent("MouseEvent");
+  let ctrlKeyArg  = aEvent.ctrlKey || false;
+  let altKeyArg   = aEvent.altKey || false;
+  let shiftKeyArg = aEvent.shiftKey || false;
+  let metaKeyArg  = aEvent.metaKey || false;
+  let buttonArg   = aEvent.button || 0;
   event.initMouseEvent("click", true, true, window,
                         0, 0, 0, 0, 0,
                         ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
                         buttonArg, null);
   aTarget.dispatchEvent(event);
 }
 
 // modified from toolkit/components/satchel/test/test_form_autocomplete.html
 function checkMenuEntries(expectedValues) {
-  var actualValues = getMenuEntries();
+  let actualValues = getMenuEntries();
   is(actualValues.length, expectedValues.length, "Checking length of expected menu");
-  for (var i = 0; i < expectedValues.length; i++)
+  for (let i = 0; i < expectedValues.length; i++)
     is(actualValues[i], expectedValues[i], "Checking menu entry #" + i);
 }
 
 function getMenuEntries() {
   // Could perhaps pull values directly from the controller, but it seems
   // more reliable to test the values that are actually in the richlistbox?
   return Array.map(searchBar.textbox.popup.richlistbox.itemChildren,
                    item => item.getAttribute("ac-value"));
@@ -53,22 +53,22 @@ function countEntries(name, value) {
   });
 }
 
 var searchBar;
 var searchButton;
 var searchEntries = ["test"];
 function promiseSetEngine() {
   return new Promise(resolve => {
-    var ss = Services.search;
+    let ss = Services.search;
 
     function observer(aSub, aTopic, aData) {
       switch (aData) {
         case "engine-added":
-          var engine = ss.getEngineByName("Bug 426329");
+          let engine = ss.getEngineByName("Bug 426329");
           ok(engine, "Engine was added.");
           ss.defaultEngine = engine;
           break;
         case "engine-current":
           ok(ss.defaultEngine.name == "Bug 426329", "currentEngine set");
           searchBar = BrowserSearch.searchBar;
           searchButton = searchBar.querySelector(".search-go-button");
           ok(searchButton, "got search-go-button");
@@ -83,27 +83,27 @@ function promiseSetEngine() {
     Services.obs.addObserver(observer, "browser-search-engine-modified");
     ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/browser/426329.xml",
                  "data:image/x-icon,%00", false);
   });
 }
 
 function promiseRemoveEngine() {
   return new Promise(resolve => {
-    var ss = Services.search;
+    let ss = Services.search;
 
     function observer(aSub, aTopic, aData) {
       if (aData == "engine-removed") {
         Services.obs.removeObserver(observer, "browser-search-engine-modified");
         resolve();
       }
     }
 
     Services.obs.addObserver(observer, "browser-search-engine-modified");
-    var engine = ss.getEngineByName("Bug 426329");
+    let engine = ss.getEngineByName("Bug 426329");
     ss.removeEngine(engine);
   });
 }
 
 
 var preSelectedBrowser;
 var preTabNo;
 async function prepareTest() {
@@ -212,25 +212,25 @@ add_task(async function testRightClick()
     simulateClick({ button: 2 }, searchButton);
   });
   // The click in the searchbox focuses it, which opens the suggestion
   // panel. Clean up after ourselves.
   searchBar.textbox.popup.hidePopup();
 });
 
 add_task(async function testSearchHistory() {
-  var textbox = searchBar._textbox;
-  for (var i = 0; i < searchEntries.length; i++) {
+  let textbox = searchBar._textbox;
+  for (let i = 0; i < searchEntries.length; i++) {
     let count = await countEntries(textbox.getAttribute("autocompletesearchparam"), searchEntries[i]);
     ok(count > 0, "form history entry '" + searchEntries[i] + "' should exist");
   }
 });
 
 add_task(async function testAutocomplete() {
-  var popup = searchBar.textbox.popup;
+  let popup = searchBar.textbox.popup;
   let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
   searchBar.textbox.showHistoryPopup();
   await popupShownPromise;
   checkMenuEntries(searchEntries);
 });
 
 add_task(async function testClearHistory() {
   // Open the textbox context menu to trigger controller attachment.
--- a/browser/components/search/test/browser/browser_addEngine.js
+++ b/browser/components/search/test/browser/browser_addEngine.js
@@ -28,17 +28,17 @@ function observer(aSubject, aTopic, aDat
   }
 
   if (method)
     gCurrentTest[method](engine);
 }
 
 function checkEngine(checkObj, engineObj) {
   info("Checking engine");
-  for (var prop in checkObj)
+  for (let prop in checkObj)
     is(checkObj[prop], engineObj[prop], prop + " is correct");
 }
 
 var gTests = [
   {
     name: "opensearch install",
     engine: {
       name: "Foo",
--- a/browser/components/search/test/browser/browser_contextmenu.js
+++ b/browser/components/search/test/browser/browser_contextmenu.js
@@ -2,17 +2,17 @@
  *  * http://creativecommons.org/publicdomain/zero/1.0/ */
 /*
  * Test searching for the selected text using the context menu
  */
 
 add_task(async function() {
   const ss = Services.search;
   const ENGINE_NAME = "Foo";
-  var contextMenu;
+  let contextMenu;
 
   // We want select events to be fired.
   await SpecialPowers.pushPrefEnv({set: [["dom.select_events.enabled", true]]});
 
   let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
   let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
   envService.set("XPCSHELL_TEST_PROFILE_DIR", "1");
 
@@ -23,17 +23,17 @@ add_task(async function() {
   resProt.setSubstitution("search-plugins",
                           Services.io.newURI(url));
 
   let searchDonePromise;
   await new Promise(resolve => {
     function observer(aSub, aTopic, aData) {
       switch (aData) {
         case "engine-added":
-          var engine = ss.getEngineByName(ENGINE_NAME);
+          let engine = ss.getEngineByName(ENGINE_NAME);
           ok(engine, "Engine was added.");
           ss.defaultEngine = engine;
           envService.set("XPCSHELL_TEST_PROFILE_DIR", originalValue);
           resProt.setSubstitution("search-plugins", originalSubstitution);
           break;
         case "engine-current":
           is(ss.defaultEngine.name, ENGINE_NAME, "currentEngine set");
           resolve();
@@ -61,24 +61,24 @@ add_task(async function() {
     return new Promise(resolve => {
       content.document.addEventListener("selectionchange", function() {
         resolve();
       }, {once: true});
       content.document.getSelection().selectAllChildren(content.document.body);
     });
   });
 
-  var eventDetails = { type: "contextmenu", button: 2 };
+  let eventDetails = { type: "contextmenu", button: 2 };
 
   let popupPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
   BrowserTestUtils.synthesizeMouseAtCenter("body", eventDetails, gBrowser.selectedBrowser);
   await popupPromise;
 
   info("checkContextMenu");
-  var searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0];
+  let searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0];
   ok(searchItem, "Got search context menu item");
   is(searchItem.label, "Search " + ENGINE_NAME + " for \u201ctest search\u201d", "Check context menu label");
   is(searchItem.disabled, false, "Check that search context menu item is enabled");
 
   await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
     searchItem.click();
   });
 
--- a/browser/components/search/test/browser/browser_oneOffContextMenu_setDefault.js
+++ b/browser/components/search/test/browser/browser_oneOffContextMenu_setDefault.js
@@ -96,17 +96,17 @@ add_task(async function test_urlBarChang
 
   await promiseClosePopup(urlbarPopup);
 });
 
 /**
  * Promises that an engine change has happened for the current engine, which
  * has resulted in the test engine now being the current engine.
  *
- * @return {Promise} Resolved once the test engine is set as the current engine.
+ * @returns {Promise} Resolved once the test engine is set as the current engine.
  */
 function promiseCurrentEngineChanged() {
   return new Promise(resolve => {
     function observer(aSub, aTopic, aData) {
       if (aData == "engine-current") {
         Assert.equal(Services.search.defaultEngine.name, TEST_ENGINE_NAME, "currentEngine set");
         Services.obs.removeObserver(observer, "browser-search-engine-modified");
         resolve();
@@ -116,23 +116,23 @@ function promiseCurrentEngineChanged() {
     Services.obs.addObserver(observer, "browser-search-engine-modified");
   });
 }
 
 /**
  * Opens the specified urlbar/search popup and gets the test engine from the
  * one-off buttons.
  *
- * @param {Boolean} isSearch true if the search popup should be opened; false
+ * @param {boolean} isSearch true if the search popup should be opened; false
  *                           for the urlbar popup.
- * @param {Object} popup The expected popup.
- * @param {Object} oneOffInstance The expected one-off instance for the popup.
- * @param {String} baseId The expected string for the id of the current
+ * @param {object} popup The expected popup.
+ * @param {object} oneOffInstance The expected one-off instance for the popup.
+ * @param {string} baseId The expected string for the id of the current
  *                        engine button, without the engine name.
- * @return {Object} Returns an object that represents the one off button for the
+ * @returns {object} Returns an object that represents the one off button for the
  *                          test engine.
  */
 async function openPopupAndGetEngineButton(isSearch, popup, oneOffInstance, baseId) {
   // Open the popup.
   let promise = promiseEvent(popup, "popupshown");
   info("Opening panel");
 
   // We have to open the popups in differnt ways.
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser/browser_searchTelemetry.js
@@ -0,0 +1,221 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * Main tests for SearchTelemetry - general engine visiting and link clicking.
+ */
+
+"use strict";
+
+const {SearchTelemetry} = ChromeUtils.import("resource:///modules/SearchTelemetry.jsm", null);
+
+const TEST_PROVIDER_INFO = {
+  "example": {
+    "regexp": /^http:\/\/mochi.test:.+\/browser\/browser\/components\/search\/test\/browser\/searchTelemetry(?:Ad)?.html/,
+    "queryParam": "s",
+    "codeParam": "abc",
+    "codePrefixes": ["ff"],
+    "followonParams": ["a"],
+    "extraAdServersRegexps": [/^https:\/\/example\.com\/ad2?/],
+  },
+};
+
+const SEARCH_AD_CLICK_SCALARS = [
+  "browser.search.with_ads",
+  "browser.search.ad_clicks",
+];
+
+function getPageUrl(useExample = false, useAdPage = false) {
+  let server = useExample ? "example.com" : "mochi.test:8888";
+  let page = useAdPage ? "searchTelemetryAd.html" : "searchTelemetry.html";
+  return `http://${server}/browser/browser/components/search/test/browser/${page}`;
+}
+
+function getSERPUrl(page) {
+  return page + "?s=test&abc=ff";
+}
+
+function getSERPFollowOnUrl(page) {
+  return page + "?s=test&abc=ff&a=foo";
+}
+
+const searchCounts = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
+
+async function assertTelemetry(expectedHistograms, expectedScalars) {
+  let histSnapshot = {};
+  let scalars = {};
+
+  await TestUtils.waitForCondition(() => {
+    histSnapshot = searchCounts.snapshot();
+    return Object.getOwnPropertyNames(histSnapshot).length ==
+      Object.getOwnPropertyNames(expectedHistograms).length;
+  });
+
+  if (Object.entries(expectedScalars).length > 0) {
+    await TestUtils.waitForCondition(() => {
+      scalars = Services.telemetry.getSnapshotForKeyedScalars(
+        "main", false).parent || {};
+      return Object.getOwnPropertyNames(expectedScalars)[0] in
+        scalars;
+    });
+  }
+
+  Assert.equal(Object.getOwnPropertyNames(histSnapshot).length,
+    Object.getOwnPropertyNames(expectedHistograms).length,
+    "Should only have one key");
+
+  for (let [key, value] of Object.entries(expectedHistograms)) {
+    Assert.ok(key in histSnapshot,
+      `Histogram should have the expected key: ${key}`);
+    Assert.equal(histSnapshot[key].sum, value,
+      `Should have counted the correct number of visits for ${key}`);
+  }
+
+  for (let [name, value] of Object.entries(expectedScalars)) {
+    Assert.ok(name in scalars,
+      `Scalar ${name} should have been added.`);
+    Assert.deepEqual(scalars[name], value,
+      `Should have counted the correct number of visits for ${name}`);
+  }
+
+  for (let name of SEARCH_AD_CLICK_SCALARS) {
+    Assert.equal(name in scalars, name in expectedScalars,
+      `Should have matched ${name} in scalars and expectedScalars`);
+  }
+}
+
+add_task(async function setup() {
+  SearchTelemetry.overrideSearchTelemetryForTests(TEST_PROVIDER_INFO);
+  // Enable local telemetry recording for the duration of the tests.
+  let oldCanRecord = Services.telemetry.canRecordExtended;
+  Services.telemetry.canRecordExtended = true;
+  Services.prefs.setBoolPref("browser.search.log", true);
+
+  registerCleanupFunction(async () => {
+    SearchTelemetry.overrideSearchTelemetryForTests();
+    Services.telemetry.canRecordExtended = oldCanRecord;
+    Services.telemetry.clearScalars();
+  });
+});
+
+add_task(async function test_simple_search_page_visit() {
+  searchCounts.clear();
+
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: getSERPUrl(getPageUrl()),
+  }, async () => {
+    await assertTelemetry({"example.in-content:sap:ff": 1}, {});
+  });
+});
+
+add_task(async function test_follow_on_visit() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: getSERPFollowOnUrl(getPageUrl()),
+  }, async () => {
+    await assertTelemetry({
+      "example.in-content:sap:ff": 1,
+      "example.in-content:sap-follow-on:ff": 1,
+    }, {});
+  });
+});
+
+add_task(async function test_track_ad() {
+  searchCounts.clear();
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser,
+    getSERPUrl(getPageUrl(false, true)));
+
+  await assertTelemetry({"example.in-content:sap:ff": 1}, {
+    "browser.search.with_ads": {"example": 1},
+  });
+
+  BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function test_track_ad_new_window() {
+  searchCounts.clear();
+  Services.telemetry.clearScalars();
+
+  let win = await BrowserTestUtils.openNewBrowserWindow();
+
+  let url = getSERPUrl(getPageUrl(false, true));
+  await BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url);
+  await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser, false, url);
+
+  await assertTelemetry({"example.in-content:sap:ff": 1}, {
+    "browser.search.with_ads": {"example": 1},
+  });
+
+  await BrowserTestUtils.closeWindow(win);
+});
+
+add_task(async function test_track_ad_pages_without_ads() {
+  // Note: the above tests have already checked a page with no ad-urls.
+  searchCounts.clear();
+  Services.telemetry.clearScalars();
+
+  let tabs = [];
+
+  tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser,
+    getSERPUrl(getPageUrl(false, false))));
+  tabs.push(await BrowserTestUtils.openNewForegroundTab(gBrowser,
+    getSERPUrl(getPageUrl(false, true))));
+
+  await assertTelemetry({"example.in-content:sap:ff": 2}, {
+    "browser.search.with_ads": {"example": 1},
+  });
+
+  for (let tab of tabs) {
+    BrowserTestUtils.removeTab(tab);
+  }
+});
+
+add_task(async function test_track_ad_click() {
+  // Note: the above tests have already checked a page with no ad-urls.
+  searchCounts.clear();
+  Services.telemetry.clearScalars();
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser,
+    getSERPUrl(getPageUrl(false, true)));
+
+  await assertTelemetry({"example.in-content:sap:ff": 1}, {
+    "browser.search.with_ads": {"example": 1},
+  });
+
+  let pageLoadPromise = BrowserTestUtils.waitForLocationChange(gBrowser);
+  await ContentTask.spawn(tab.linkedBrowser, {}, () => {
+    content.document.getElementById("ad1").click();
+  });
+  await pageLoadPromise;
+
+  await assertTelemetry({"example.in-content:sap:ff": 1}, {
+    "browser.search.with_ads": {"example": 1},
+    "browser.search.ad_clicks": {"example": 1},
+  });
+
+  // Now go back, and click again.
+  pageLoadPromise = BrowserTestUtils.waitForLocationChange(gBrowser);
+  gBrowser.goBack();
+  await pageLoadPromise;
+
+  // We've gone back, so we register an extra display & if it is with ads or not.
+  await assertTelemetry({"example.in-content:sap:ff": 2}, {
+    "browser.search.with_ads": {"example": 2},
+    "browser.search.ad_clicks": {"example": 1},
+  });
+
+  pageLoadPromise = BrowserTestUtils.waitForLocationChange(gBrowser);
+  await ContentTask.spawn(tab.linkedBrowser, {}, () => {
+    content.document.getElementById("ad1").click();
+  });
+  await pageLoadPromise;
+
+  await assertTelemetry({"example.in-content:sap:ff": 2}, {
+    "browser.search.with_ads": {"example": 2},
+    "browser.search.ad_clicks": {"example": 2},
+  });
+
+  BrowserTestUtils.removeTab(tab);
+});
--- a/browser/components/search/test/browser/head.js
+++ b/browser/components/search/test/browser/head.js
@@ -2,16 +2,23 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 ChromeUtils.import("resource://testing-common/CustomizableUITestUtils.jsm", this);
 let gCUITestUtils = new CustomizableUITestUtils(window);
 
 /**
  * Recursively compare two objects and check that every property of expectedObj has the same value
  * on actualObj.
+ *
+ * @param {object} expectedObj
+ *        The expected object to find.
+ * @param {object} actualObj
+ *        The object to inspect.
+ * @param {string} name
+ *        The name of the engine, used for test detail logging.
  */
 function isSubObjectOf(expectedObj, actualObj, name) {
   for (let prop in expectedObj) {
     if (typeof expectedObj[prop] == "function")
       continue;
     if (expectedObj[prop] instanceof Object) {
       is(actualObj[prop].length, expectedObj[prop].length, name + "[" + prop + "]");
       isSubObjectOf(expectedObj[prop], actualObj[prop], name + "[" + prop + "]");
@@ -35,19 +42,19 @@ function promiseEvent(aTarget, aEventNam
   }
 
   return BrowserTestUtils.waitForEvent(aTarget, aEventName, false, cancelEvent);
 }
 
 /**
  * Adds a new search engine to the search service and confirms it completes.
  *
- * @param {String} basename  The file to load that contains the search engine
+ * @param {string} basename  The file to load that contains the search engine
  *                           details.
- * @param {Object} [options] Options for the test:
+ * @param {object} [options] Options for the test:
  *   - {String} [iconURL]       The icon to use for the search engine.
  *   - {Boolean} [setAsCurrent] Whether to set the new engine to be the
  *                              current engine or not.
  *   - {String} [testPath]      Used to override the current test path if this
  *                              file is used from a different directory.
  * @returns {Promise} The promise is resolved once the engine is added, or
  *                    rejected if the addition failed.
  */
@@ -146,21 +153,21 @@ function promiseStateChangeURI() {
   });
 }
 
 
 /**
  * Waits for a load (or custom) event to finish in a given tab. If provided
  * load an uri into the tab.
  *
- * @param tab
+ * @param {object} tab
  *        The tab to load into.
- * @param [optional] url
+ * @param {string} [url]
  *        The url to load, or the current url.
- * @return {Promise} resolved when the event is handled.
+ * @returns {Promise} resolved when the event is handled.
  * @resolves to the received event
  * @rejects if a valid load event is not received within a meaningful interval
  */
 function promiseTabLoadEvent(tab, url) {
   info("Wait tab event: load");
 
   function handle(loadedUrl) {
     if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser/searchTelemetry.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+  <a href="https://example.com/otherpage">Non ad link</a>
+  <a href="https://example1.com/ad">Matching path prefix, different server</a>
+  <a href="https://mochi.test:8888/otherpage">Non ad link</a>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser/searchTelemetryAd.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+  <a id="ad1" href="https://example.com/ad">Ad link</a>
+  <a id="ad2" href="https://example.com/ad2">Second Ad link</a>
+</body>
+</html>
--- a/browser/components/search/test/browser/webapi.html
+++ b/browser/components/search/test/browser/webapi.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 
 <html>
 <head>
 <script>
 function installEngine() {
-  var query = window.location.search.substring(1);
-  var args = JSON.parse(decodeURIComponent(query));
+  let query = window.location.search.substring(1);
+  let args = JSON.parse(decodeURIComponent(query));
 
   window.external.AddSearchProvider(...args);
 }
 </script>
 </head>
 <body onload="installEngine()">
 </body>
 </html>
--- a/browser/components/search/test/unit/test_urlTelemetry.js
+++ b/browser/components/search/test/unit/test_urlTelemetry.js
@@ -2,85 +2,85 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource:///modules/SearchTelemetry.jsm");
 
 add_task(async function test_parsing_search_urls() {
   let hs;
   // Google search access point.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.google.com/search?q=test&ie=utf-8&oe=utf-8&client=firefox-b-1-ab");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.google.com/search?q=test&ie=utf-8&oe=utf-8&client=firefox-b-1-ab");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("google.in-content:sap:firefox-b-1-ab" in hs, "The histogram must contain the correct key");
 
   // Google search access point follow-on.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.google.com/search?client=firefox-b-1-ab&ei=EI_VALUE&q=test2&oq=test2&gs_l=GS_L_VALUE");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.google.com/search?client=firefox-b-1-ab&ei=EI_VALUE&q=test2&oq=test2&gs_l=GS_L_VALUE");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("google.in-content:sap-follow-on:firefox-b-1-ab" in hs, "The histogram must contain the correct key");
 
   // Google organic.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.google.com/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.google.com/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("google.in-content:organic:none" in hs, "The histogram must contain the correct key");
 
   // Google organic UK.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.google.co.uk/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.google.co.uk/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("google.in-content:organic:none" in hs, "The histogram must contain the correct key");
 
   // Yahoo organic.
-  SearchTelemetry.recordSearchURLTelemetry("https://search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8");
+  SearchTelemetry.updateTrackingStatus({}, "https://search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("yahoo.in-content:organic:none" in hs, "The histogram must contain the correct key");
 
   // Yahoo organic UK.
-  SearchTelemetry.recordSearchURLTelemetry("https://uk.search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8");
+  SearchTelemetry.updateTrackingStatus({}, "https://uk.search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("yahoo.in-content:organic:none" in hs, "The histogram must contain the correct key");
 
   // Bing search access point.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.bing.com/search?q=test&pc=MOZI&form=MOZLBR");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.bing.com/search?q=test&pc=MOZI&form=MOZLBR");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("bing.in-content:sap:MOZI" in hs, "The histogram must contain the correct key");
 
   // Bing organic.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.bing.com/search?q=test&qs=n&form=QBLH&sp=-1&pq=&sc=0-0&sk=&cvid=CVID_VALUE");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.bing.com/search?q=test&qs=n&form=QBLH&sp=-1&pq=&sc=0-0&sk=&cvid=CVID_VALUE");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("bing.in-content:organic:none" in hs, "The histogram must contain the correct key");
 
   // DuckDuckGo search access point.
-  SearchTelemetry.recordSearchURLTelemetry("https://duckduckgo.com/?q=test&t=ffab");
+  SearchTelemetry.updateTrackingStatus({}, "https://duckduckgo.com/?q=test&t=ffab");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("duckduckgo.in-content:sap:ffab" in hs, "The histogram must contain the correct key");
 
   // DuckDuckGo organic.
-  SearchTelemetry.recordSearchURLTelemetry("https://duckduckgo.com/?q=test&t=hi&ia=news");
+  SearchTelemetry.updateTrackingStatus({}, "https://duckduckgo.com/?q=test&t=hi&ia=news");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("duckduckgo.in-content:organic:hi" in hs, "The histogram must contain the correct key");
 
   // Baidu search access point.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.baidu.com/baidu?wd=test&tn=monline_dg&ie=utf-8");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.baidu.com/baidu?wd=test&tn=monline_dg&ie=utf-8");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("baidu.in-content:sap:monline_dg" in hs, "The histogram must contain the correct key");
 
   // Baidu search access point follow-on.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_dg&wd=test2&oq=test&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn&rsv_enter=1&rsv_sug3=2&rsv_sug2=0&inputT=227&rsv_sug4=397");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_dg&wd=test2&oq=test&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn&rsv_enter=1&rsv_sug3=2&rsv_sug2=0&inputT=227&rsv_sug4=397");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("baidu.in-content:sap-follow-on:monline_dg" in hs, "The histogram must contain the correct key");
 
   // Baidu organic.
-  SearchTelemetry.recordSearchURLTelemetry("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=test&rn=&oq=&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn");
+  SearchTelemetry.updateTrackingStatus({}, "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=test&rn=&oq=&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn");
   hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
   Assert.ok(hs);
   Assert.ok("baidu.in-content:organic:baidu" in hs, "The histogram must contain the correct key");
 });
--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -103,16 +103,36 @@ class UrlbarController {
 
     this.manager = options.manager || UrlbarProvidersManager;
     this.browserWindow = options.browserWindow;
 
     this._listeners = new Set();
   }
 
   /**
+   * Hooks up the controller with an input.
+   *
+   * @param {UrlbarInput} input
+   *   The UrlbarInput instance associated with this controller.
+   */
+  setInput(input) {
+    this.input = input;
+  }
+
+  /**
+   * Hooks up the controller with a view.
+   *
+   * @param {UrlbarView} view
+   *   The UrlbarView instance associated with this controller.
+   */
+  setView(view) {
+    this.view = view;
+  }
+
+  /**
    * Takes a query context and starts the query based on the user input.
    *
    * @param {QueryContext} queryContext The query details.
    */
   async startQuery(queryContext) {
     queryContext.autoFill = UrlbarPrefs.get("autoFill");
 
     this._notify("onQueryStarted", queryContext);
@@ -169,16 +189,65 @@ class UrlbarController {
    * When switching tabs, clear some internal caches to handle cases like
    * backspace, autofill or repeated searches.
    */
   tabContextChanged() {
     // TODO: implementation needed (bug 1496685)
   }
 
   /**
+   * Receives keyboard events from the input and handles those that should
+   * navigate within the view or pick the currently selected item.
+   *
+   * @param {KeyboardEvent} event
+   *   The DOM KeyboardEvent.
+   */
+  handleKeyNavigation(event) {
+    // Handle readline/emacs-style navigation bindings on Mac.
+    if (AppConstants.platform == "macosx" &&
+        this.view.isOpen &&
+        event.ctrlKey &&
+        (event.key == "n" || event.key == "p")) {
+      this.view.selectNextItem({ reverse: event.key == "p" });
+      event.preventDefault();
+      return;
+    }
+
+    switch (event.keyCode) {
+      case KeyEvent.DOM_VK_RETURN:
+        if (AppConstants.platform == "macosx" &&
+            event.metaKey) {
+          // Prevent beep on Mac.
+          event.preventDefault();
+        }
+        // TODO: We may have an autoFill entry, so we should use that instead.
+        // TODO: We should have an input bufferrer so that we can use search results
+        // if appropriate.
+        this.input.handleCommand(event);
+        return;
+      case KeyEvent.DOM_VK_TAB:
+        this.view.selectNextItem({ reverse: event.shiftKey });
+        event.preventDefault();
+        break;
+      case KeyEvent.DOM_VK_DOWN:
+        if (!event.ctrlKey && !event.altKey) {
+          this.view.selectNextItem();
+          event.preventDefault();
+        }
+        break;
+      case KeyEvent.DOM_VK_UP:
+        if (!event.ctrlKey && !event.altKey) {
+          this.view.selectNextItem({ reverse: true });
+          event.preventDefault();
+        }
+        break;
+    }
+  }
+
+  /**
    * Internal function to notify listeners of results.
    *
    * @param {string} name Name of the notification.
    * @param {object} params Parameters to pass with the notification.
    */
   _notify(name, ...params) {
     for (let listener of this._listeners) {
       try {
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -45,16 +45,17 @@ class UrlbarInput {
     this.textbox.clickSelectsAll = UrlbarPrefs.get("clickSelectsAll");
 
     this.panel = options.panel;
     this.window = this.textbox.ownerGlobal;
     this.document = this.window.document;
     this.controller = options.controller || new UrlbarController({
       browserWindow: this.window,
     });
+    this.controller.setInput(this);
     this.view = new UrlbarView(this);
     this.valueIsTyped = false;
     this.userInitiatedFocus = false;
     this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
     this._untrimmedValue = "";
 
     // Forward textbox methods and properties.
     const METHODS = ["addEventListener", "removeEventListener",
@@ -99,17 +100,17 @@ class UrlbarInput {
     this.inputField.addEventListener("blur", this);
     this.inputField.addEventListener("focus", this);
     this.inputField.addEventListener("mousedown", this);
     this.inputField.addEventListener("mouseover", this);
     this.inputField.addEventListener("overflow", this);
     this.inputField.addEventListener("underflow", this);
     this.inputField.addEventListener("scrollend", this);
     this.inputField.addEventListener("select", this);
-    this.inputField.addEventListener("keyup", this);
+    this.inputField.addEventListener("keydown", this);
 
     this.inputField.controllers.insertControllerAt(0, new CopyCutController(this));
   }
 
   /**
    * Shortens the given value, usually by removing http:// and trailing slashes,
    * such that calling nsIURIFixup::createFixupURI with the result will produce
    * the same URI.
@@ -175,17 +176,17 @@ class UrlbarInput {
       throw new Error("Unrecognized UrlbarInput event: " + event.type);
     }
   }
 
   /**
    * Handles an event which would cause a url or text to be opened.
    * XXX the name is currently handleCommand which is compatible with
    * urlbarBindings. However, it is no longer called automatically by autocomplete,
-   * See _on_keyup.
+   * See _on_keydown.
    *
    * @param {Event} event The event triggering the open.
    * @param {string} [openWhere] Where we expect the result to be opened.
    * @param {object} [openParams]
    *   The parameters related to where the result will be opened.
    * @param {object} [triggeringPrincipal]
    *   The principal that the action was triggered from.
    */
@@ -250,22 +251,22 @@ class UrlbarInput {
     }
 
     this._loadURL(url, where, openParams);
 
     this.view.close();
   }
 
   /**
-   * Called by the view when a result is selected.
+   * Called by the view when a result is picked.
    *
-   * @param {Event} event The event that selected the result.
-   * @param {UrlbarMatch} result The result that was selected.
+   * @param {Event} event The event that picked the result.
+   * @param {UrlbarMatch} result The result that was picked.
    */
-  resultSelected(event, result) {
+  pickResult(event, result) {
     this.setValueFromResult(result);
 
     // TODO: Work out how we get the user selection behavior, probably via passing
     // it in, since we don't have the old autocomplete controller to work with.
     // BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
     //   event, this.userSelectionBehavior);
 
     let where = this._whereToOpen(event);
@@ -707,23 +708,18 @@ class UrlbarInput {
   _on_scrollend(event) {
     this._updateTextOverflow();
   }
 
   _on_TabSelect(event) {
     this.controller.tabContextChanged();
   }
 
-  _on_keyup(event) {
-    // TODO: We may have an autoFill entry, so we should use that instead.
-    // TODO: We should have an input bufferrer so that we can use search results
-    // if appropriate.
-    if (event.key == "Enter") {
-      this.handleCommand(event);
-    }
+  _on_keydown(event) {
+    this.controller.handleKeyNavigation(event);
   }
 }
 
 /**
  * Handles copy and cut commands for the urlbar.
  */
 class CopyCutController {
   /**
--- a/browser/components/urlbar/UrlbarView.jsm
+++ b/browser/components/urlbar/UrlbarView.jsm
@@ -11,58 +11,106 @@ XPCOMUtils.defineLazyModuleGetters(this,
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Receives and displays address bar autocomplete results.
  */
 class UrlbarView {
   /**
-   * @param {UrlbarInput} urlbar
+   * @param {UrlbarInput} input
    *   The UrlbarInput instance belonging to this UrlbarView instance.
    */
-  constructor(urlbar) {
-    this.urlbar = urlbar;
-    this.panel = urlbar.panel;
-    this.controller = urlbar.controller;
-    this.document = urlbar.panel.ownerDocument;
+  constructor(input) {
+    this.input = input;
+    this.panel = input.panel;
+    this.controller = input.controller;
+    this.document = this.panel.ownerDocument;
     this.window = this.document.defaultView;
 
     this._mainContainer = this.panel.querySelector(".urlbarView-body-inner");
     this._rows = this.panel.querySelector(".urlbarView-results");
 
+    this._rows.addEventListener("click", this);
+
     // For the horizontal fade-out effect, set the overflow attribute on result
     // rows when they overflow.
     this._rows.addEventListener("overflow", this);
     this._rows.addEventListener("underflow", this);
 
+    this.controller.setView(this);
     this.controller.addQueryListener(this);
   }
 
   get oneOffSearchButtons() {
     return this._oneOffSearchButtons ||
       (this._oneOffSearchButtons =
          new this.window.SearchOneOffs(this.panel.querySelector(".search-one-offs")));
   }
 
   /**
+   * @returns {boolean}
+   *   Whether the panel is open.
+   */
+  get isOpen() {
+    return this.panel.state == "open" || this.panel.state == "showing";
+  }
+
+  /**
+   * Selects the next or previous view item. An item could be an autocomplete
+   * result or a one-off search button.
+   *
+   * @param {boolean} options.reverse
+   *   Set to true to select the previous item. By default the next item
+   *   will be selected.
+   */
+  selectNextItem({reverse = false} = {}) {
+    if (!this.isOpen) {
+      this.open();
+      return;
+    }
+
+    // TODO: handle one-off search buttons
+
+    let row;
+    if (reverse) {
+      row = this._selected.previousElementSibling ||
+            this._rows.lastElementChild;
+    } else {
+      row = this._selected.nextElementSibling ||
+            this._rows.firstElementChild;
+    }
+
+    this._selected.toggleAttribute("selected", false);
+    this._selected = row;
+    row.toggleAttribute("selected", true);
+
+    let resultIndex = row.getAttribute("resultIndex");
+    let result = this._queryContext.results[resultIndex];
+    if (result) {
+      this.input.setValueFromResult(result);
+    }
+  }
+
+  /**
    * Opens the autocomplete results popup.
    */
   open() {
     this.panel.removeAttribute("hidden");
 
     this._alignPanel();
 
     // TODO: Search one off buttons are a stub right now.
     //       We'll need to set them up properly.
     this.oneOffSearchButtons;
 
-    this.panel.openPopup(this.urlbar.textbox.closest("toolbar"), "after_end", 0, -1);
+    this.panel.openPopup(this.input.textbox.closest("toolbar"), "after_end", 0, -1);
 
-    this._rows.firstElementChild.toggleAttribute("selected", true);
+    this._selected = this._rows.firstElementChild;
+    this._selected.toggleAttribute("selected", true);
   }
 
   /**
    * Closes the autocomplete results popup.
    */
   close() {
     this.panel.hidePopup();
   }
@@ -106,22 +154,22 @@ class UrlbarView {
     let documentRect =
       this._getBoundsWithoutFlushing(this.document.documentElement);
     let width = documentRect.right - documentRect.left;
     this.panel.setAttribute("width", width);
 
     // Subtract two pixels for left and right borders on the panel.
     this._mainContainer.style.maxWidth = (width - 2) + "px";
 
-    // Keep the popup items' site icons aligned with the urlbar's identity
+    // Keep the popup items' site icons aligned with the input's identity
     // icon if it's not too far from the edge of the window.  We define
     // "too far" as "more than 30% of the window's width AND more than
     // 250px".
     let boundToCheck = this.window.RTL_UI ? "right" : "left";
-    let inputRect = this._getBoundsWithoutFlushing(this.urlbar.textbox);
+    let inputRect = this._getBoundsWithoutFlushing(this.input.textbox);
     let startOffset = Math.abs(inputRect[boundToCheck] - documentRect[boundToCheck]);
     let alignSiteIcons = startOffset / width <= 0.3 || startOffset <= 250;
     if (alignSiteIcons) {
       // Calculate the end margin if we have a start margin.
       let boundToCheckEnd = this.window.RTL_UI ? "left" : "right";
       let endOffset = Math.abs(inputRect[boundToCheckEnd] -
                                documentRect[boundToCheckEnd]);
       if (endOffset > startOffset * 2) {
@@ -143,29 +191,31 @@ class UrlbarView {
       this.panel.style.removeProperty("--item-padding-end");
     }
   }
 
   _addRow(resultIndex) {
     let result = this._queryContext.results[resultIndex];
     let item = this._createElement("div");
     item.className = "urlbarView-row";
-    item.addEventListener("click", this);
     item.setAttribute("resultIndex", resultIndex);
+
     if (result.type == UrlbarUtils.MATCH_TYPE.TAB_SWITCH) {
-      item.setAttribute("action", "switch-to-tab");
+      item.setAttribute("type", "switchtab");
+    } else if (result.source == UrlbarUtils.MATCH_SOURCE.BOOKMARKS) {
+      item.setAttribute("type", "bookmark");
     }
 
     let content = this._createElement("span");
     content.className = "urlbarView-row-inner";
     item.appendChild(content);
 
-    let actionIcon = this._createElement("span");
-    actionIcon.className = "urlbarView-action-icon";
-    content.appendChild(actionIcon);
+    let typeIcon = this._createElement("span");
+    typeIcon.className = "urlbarView-type-icon";
+    content.appendChild(typeIcon);
 
     let favicon = this._createElement("img");
     favicon.className = "urlbarView-favicon";
     favicon.src = result.payload.icon || "chrome://mozapps/skin/places/defaultFavicon.svg";
     content.appendChild(favicon);
 
     let title = this._createElement("span");
     title.className = "urlbarView-title";
@@ -203,17 +253,17 @@ class UrlbarView {
   _on_click(event) {
     let row = event.target;
     while (!row.classList.contains("urlbarView-row")) {
       row = row.parentNode;
     }
     let resultIndex = row.getAttribute("resultIndex");
     let result = this._queryContext.results[resultIndex];
     if (result) {
-      this.urlbar.resultSelected(event, result);
+      this.input.pickResult(event, result);
     }
     this.close();
   }
 
   _on_overflow(event) {
     if (event.target.classList.contains("urlbarView-row-inner")) {
       event.target.toggleAttribute("overflow", true);
     }
--- a/browser/components/urlbar/tests/browser/browser.ini
+++ b/browser/components/urlbar/tests/browser/browser.ini
@@ -4,13 +4,12 @@
 
 [DEFAULT]
 support-files =
   head.js
 
 [browser_UrlbarInput_formatValue.js]
 [browser_UrlbarInput_overflow.js]
 [browser_UrlbarInput_tooltip.js]
-skip-if = os == "win" # Bug 1511655
 [browser_UrlbarInput_trimURLs.js]
 subsuite = clipboard
 [browser_UrlbarInput_unit.js]
 support-files = empty.xul
--- a/browser/extensions/formautofill/content/autofillEditForms.js
+++ b/browser/extensions/formautofill/content/autofillEditForms.js
@@ -401,17 +401,17 @@ class EditCreditCard extends EditAutofil
 
     // Empty month option
     this._elements.month.appendChild(new Option());
 
     // Populate month list. Format: "month number - month name"
     let dateFormat = new Intl.DateTimeFormat(navigator.language, {month: "long"}).format;
     for (let i = 0; i < count; i++) {
       let monthNumber = (i + 1).toString();
-      let monthName = dateFormat(new Date(Date.UTC(1970, i, 1)));
+      let monthName = dateFormat(new Date(1970, i));
       let option = new Option();
       option.value = monthNumber;
       // XXX: Bug 1446164 - Localize this string.
       option.textContent = `${monthNumber.padStart(2, "0")} - ${monthName}`;
       this._elements.month.appendChild(option);
     }
   }
 
--- a/browser/extensions/formautofill/test/browser/browser_editCreditCardDialog.js
+++ b/browser/extensions/formautofill/test/browser/browser_editCreditCardDialog.js
@@ -20,16 +20,17 @@ add_task(async function test_cancelEditC
 });
 
 add_task(async function test_saveCreditCard() {
   await testDialog(EDIT_CREDIT_CARD_DIALOG_URL, (win) => {
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-number"], {}, win);
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey("0" + TEST_CREDIT_CARD_1["cc-exp-month"].toString(), {}, win);
+    is(win.document.activeElement.selectedOptions[0].text, "04 - April", "Displayed month should match number and name");
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-exp-year"].toString(), {}, win);
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-name"], {}, win);
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
     EventUtils.synthesizeKey("VK_TAB", {}, win);
     EventUtils.synthesizeKey("VK_TAB", {}, win);
--- a/browser/extensions/screenshots/background/main.js
+++ b/browser/extensions/screenshots/background/main.js
@@ -142,16 +142,20 @@ this.main = (function() {
         .then(() => sendEvent("start-shot", "context-menu", {incognito: tab.incognito}));
     }));
   });
 
   function urlEnabled(url) {
     if (shouldOpenMyShots(url)) {
       return true;
     }
+    // Allow screenshots on urls related to web pages in reader mode.
+    if (url && url.startsWith("about:reader?url=")) {
+      return true;
+    }
     if (isShotOrMyShotPage(url) || /^(?:about|data|moz-extension):/i.test(url) || isBlacklistedUrl(url)) {
       return false;
     }
     return true;
   }
 
   function isShotOrMyShotPage(url) {
     // It's okay to take a shot of any pages except shot pages and My Shots
--- a/browser/extensions/screenshots/background/startBackground.js
+++ b/browser/extensions/screenshots/background/startBackground.js
@@ -36,17 +36,17 @@ this.startBackground = (function() {
       console.error("Error loading Screenshots:", error);
     });
   });
 
   browser.contextMenus.create({
     id: "create-screenshot",
     title: browser.i18n.getMessage("contextMenuLabel"),
     contexts: ["page"],
-    documentUrlPatterns: ["<all_urls>"],
+    documentUrlPatterns: ["<all_urls>", "about:reader*"],
   });
 
   browser.contextMenus.onClicked.addListener((info, tab) => {
     loadIfNecessary().then(() => {
       main.onClickedContextMenu(info, tab);
     }).catch((error) => {
       console.error("Error loading Screenshots:", error);
     });
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -419,25 +419,25 @@ browsing-use-cursor-navigation =
 browsing-search-on-start-typing =
     .label = Search for text when you start typing
     .accesskey = x
 
 browsing-cfr-recommendations =
     .label = Recommend extensions as you browse
     .accesskey = R
 
-browsing-cfr-recommendations-learn-more = Learn More
+browsing-cfr-recommendations-learn-more = Learn more
 
 ## General Section - Proxy
 
 network-settings-title = Network Settings
 
 network-proxy-connection-description = Configure how { -brand-short-name } connects to the internet.
 
-network-proxy-connection-learn-more = Learn More
+network-proxy-connection-learn-more = Learn more
 
 network-proxy-connection-settings =
     .label = Settingsā€¦
     .accesskey = e
 
 ## Home Section
 
 home-new-windows-tabs-header = New Windows and Tabs
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -490,42 +490,70 @@ contentBlocking.category.strict=Strict
 contentBlocking.category.custom=Custom
 
 # LOCALIZATION NOTE (contentBlocking.trackers.allowed.label):
 #   This label signals that this type of content blocking is turned
 #   OFF and is not blocking tracker content, so this is not
 #   a positive thing. It forms the end of the (imaginary) sentence
 #   "Trackers [are] Allowed"
 contentBlocking.trackers.allowed.label=Allowed
-# LOCALIZATION NOTE (contentBlocking.trackers.blocked.label):
+# LOCALIZATION NOTE (contentBlocking.trackers.blocking.label):
 #   This label signals that this type of content blocking is turned
 #   ON and is successfully blocking tracker content, so this is
-#   a positive thing. It forms the end of the (imaginary) sentence
-#   "Trackers [are] Blocked"
-contentBlocking.trackers.blocked.label=Blocked
+#   a positive thing. However, it is important to note that there is no
+#   guarantee that we _actually_ blocked anything, hence we present it
+#   in the present tense, not the past tense in English. The idea is that
+#   past tense would imply that something was blocked, while present
+#   tense expresses that we are waiting for trackers to load
+#   and will block them as appropriate. This concept may not directly
+#   translate to your language, but it is still preferable if the translation
+#   would not make it seem like the blocking had already happened.
+#   So in full context this word could be part of the sentence:
+#   "[Firefox is] Blocking [trackers when they get loaded.]"
+contentBlocking.trackers.blocking.label=Blocking
 
 # LOCALIZATION NOTE (contentBlocking.trackersView.blocked.label):
 #   This label is shown next to a tracker in the trackers subview.
 #   It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
 contentBlocking.trackersView.blocked.label=Blocked
 
+contentBlocking.trackersView.empty.label=None detected on this site
+
 # LOCALIZATION NOTE (contentBlocking.cookies.allowed.label):
 #   This label signals that this type of content blocking is turned
 #   OFF and is not blocking tracker content, so this is not
 #   a positive thing. It forms the end of the (imaginary) sentence
 #   "Cookies [are] Allowed"
 contentBlocking.cookies.allowed.label=Allowed
-contentBlocking.cookies.trackersBlocked.label=Tracking Cookies Blocked
-contentBlocking.cookies.3rdPartyBlocked.label=Third-Party Cookies Blocked
-contentBlocking.cookies.unvisitedBlocked.label=Unvisited Site Cookies Blocked
-contentBlocking.cookies.allBlocked.label=All Cookies Blocked
+# LOCALIZATION NOTE (contentBlocking.cookies.blockingTrackers.label, contentBlocking.cookies.blocking3rdParty.label,
+#   contentBlocking.cookies.blockingUnvisited.label,contentBlocking.cookies.blockingAll.label):
+# See localization note for contentBlocking.trackers.blocking.label to get recommendations on translating "Blocking".
+contentBlocking.cookies.blockingTrackers.label=Blocking Tracking Cookies
+contentBlocking.cookies.blocking3rdParty.label=Blocking Third-Party Cookies
+contentBlocking.cookies.blockingUnvisited.label=Blocking Unvisited Site Cookies
+contentBlocking.cookies.blockingAll.label=Blocking All Cookies
 
 contentBlocking.cookiesView.firstParty.label=From This Site
+# LOCALIZATION NOTE (contentBlocking.cookiesView.firstParty.empty.label):
+#  This references the header from contentBlocking.cookiesView.firstParty.label:
+#  "[Cookies] From This Site: None detected on this site".
+contentBlocking.cookiesView.firstParty.empty.label=None detected on this site
+
 contentBlocking.cookiesView.trackers.label=Tracking Cookies
+# LOCALIZATION NOTE (contentBlocking.cookiesView.trackers.empty.label):
+#  This references the header from contentBlocking.cookiesView.trackers.label:
+#  "Tracking Cookies: None detected on this site".
+contentBlocking.cookiesView.trackers.empty.label=None detected on this site
+
 contentBlocking.cookiesView.thirdParty.label=Third-Party Cookies
+# LOCALIZATION NOTE (contentBlocking.cookiesView.thirdParty.empty.label):
+#  This references the header from contentBlocking.cookiesView.thirdParty.label:
+#  "Third-Party Cookies: None detected on this site".
+contentBlocking.cookiesView.thirdParty.empty.label=None detected on this site
+
 # LOCALIZATION NOTE (contentBlocking.cookiesView.allowed.label):
 #   This label is shown next to a cookie origin in the cookies subview.
 #   It forms the end of the (imaginary) sentence "www.example.com [was] Allowed"
 contentBlocking.cookiesView.allowed.label=Allowed
 # LOCALIZATION NOTE (contentBlocking.cookiesView.blocked.label):
 #   This label is shown next to a cookie origin in the cookies subview.
 #   It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
 contentBlocking.cookiesView.blocked.label=Blocked
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -149,16 +149,19 @@ let URICountListener = {
     if (!this.isHttpURI(uri)) {
       return;
     }
 
     this._restoredURIsMap.set(browser, uri.spec);
   },
 
   onLocationChange(browser, webProgress, request, uri, flags) {
+    // By default, assume we no longer need to track this tab.
+    SearchTelemetry.stopTrackingBrowser(browser);
+
     // Don't count this URI if it's an error page.
     if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
       return;
     }
 
     // We only care about top level loads.
     if (!webProgress.isTopLevel) {
       return;
@@ -214,17 +217,17 @@ let URICountListener = {
     }
 
     if (!this.isHttpURI(uri)) {
       return;
     }
 
     if (shouldRecordSearchCount(browser.getTabBrowser()) &&
         !(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
-      SearchTelemetry.recordSearchURLTelemetry(uriSpec);
+      SearchTelemetry.updateTrackingStatus(browser, uriSpec);
     }
 
     if (!shouldCountURI) {
       return;
     }
 
     // Update the URI counts.
     Services.telemetry.scalarAdd(TOTAL_URI_COUNT_SCALAR_NAME, 1);
--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -837,18 +837,17 @@ async function sanitizeSessionPrincipal(
                                                Ci.nsIClearDataService.CLEAR_COOKIES,
                                                resolve);
   });
 }
 
 function sanitizeNewTabSegregation() {
   let identity = ContextualIdentityService.getPrivateIdentity("userContextIdInternal.thumbnail");
   if (identity) {
-    Services.obs.notifyObservers(null, "clear-origin-attributes-data",
-                                 JSON.stringify({ userContextId: identity.userContextId }));
+    Services.clearData.deleteDataFromOriginAttributesPattern({ userContextId: identity.userContextId });
   }
 }
 
 /**
  * Gets an array of items to clear from the given pref branch.
  * @param branch The pref branch to fetch.
  * @return Array of items to clear
  */
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -156,16 +156,17 @@
   display: inline;
   padding-inline-end: 25px;
   padding-inline-start: 0px;
   color: var(--panel-disabled-color);
 }
 
 /* CONTENT */
 
+.identity-popup-content-blocking-empty-label,
 #tracking-protection-preferences-button > .toolbarbutton-text,
 .identity-popup-footer,
 .tracking-protection-button,
 #identity-popup-trackersView-strict-info > label,
 .identity-popup-cookiesView-list-header,
 .identity-popup-content-blocking-list-item > label,
 #identity-popup-mainView-panel-header > label,
 #identity-popup-trackersView > .panel-header,
@@ -434,16 +435,39 @@ description#identity-popup-content-verif
 
 /* This subview could get filled with a lot of trackers, set a maximum size
  * and allow it to scroll vertically.*/
 #identity-popup-cookiesView,
 #identity-popup-trackersView {
   max-height: 600px;
 }
 
+#identity-popup-trackersView-list.empty {
+  -moz-box-align: center;
+  -moz-box-pack: center;
+}
+
+.identity-popup-content-blocking-empty-label {
+  margin-inline-start: 0;
+  color: var(--panel-disabled-color);
+}
+
+.identity-popup-content-blocking-trackersView-empty-image {
+  width: 48px;
+  height: 48px;
+  -moz-context-properties: fill, fill-opacity;
+  margin-bottom: 16px;
+}
+
+#identity-popup-cookiesView .identity-popup-content-blocking-empty-label {
+  margin-inline-start: 24px;
+  margin-top: 2px;
+  margin-bottom: 4px;
+}
+
 .identity-popup-cookiesView-list-header {
   color: var(--panel-disabled-color);
   margin: 5px 0;
 }
 
 .identity-popup-content-blocking-list {
   padding: 5px 20px;
   -moz-box-flex: 1;
--- a/browser/themes/shared/identity-block/identity-block.inc.css
+++ b/browser/themes/shared/identity-block/identity-block.inc.css
@@ -175,31 +175,35 @@
   overflow: hidden;
   margin-inline-start: 4px;
   width: 16px;
   height: 20px;
 }
 
 #tracking-protection-icon-box:not([hasException])[active] #tracking-protection-icon-animatable-image {
   background-image: url(chrome://browser/skin/tracking-protection-animation.svg);
-  transform: translateX(-1232px);
-  width: 1248px;
+  transform: translateX(-2816px);
+  width: 2832px;
   background-size: auto;
   height: 16px;
   min-height: 20px;
   -moz-context-properties: fill, fill-opacity;
 }
 
+:root[lwt-toolbar-field-brighttext] #tracking-protection-icon-box:not([hasException])[active] #tracking-protection-icon-animatable-image {
+  background-image: url(chrome://browser/skin/tracking-protection-animation-brighttext.svg);
+}
+
 #tracking-protection-icon-box[active] #tracking-protection-icon-animatable-image:-moz-locale-dir(rtl) {
   transform: scaleX(-1) translateX(-1232px);
 }
 
 #tracking-protection-icon-box[active][animate] #tracking-protection-icon-animatable-image {
   animation-name: tp-icon-animation;
-  animation-timing-function: steps(77);
+  animation-timing-function: steps(176);
   animation-duration: 3s;
   animation-fill-mode: forwards;
 }
 
 #tracking-protection-icon-box[active][animate] #tracking-protection-icon-animatable-image:-moz-locale-dir(rtl) {
   animation-name: tp-icon-animation-rtl;
 }
 
@@ -211,73 +215,31 @@
   list-style-image: url(chrome://browser/skin/tracking-protection-disabled.svg);
 }
 
 #urlbar[pageproxystate="invalid"] > #identity-box > #extension-icon,
 #urlbar[pageproxystate="invalid"] > #identity-box > #tracking-protection-icon-box {
   visibility: collapse;
 }
 
-#tracking-protection-icon-animatable-image {
-  --tracking-protection-shield-color: #7f00d6;
-}
-
-:root[lwt-toolbar-field-brighttext] #tracking-protection-icon-animatable-image {
-  --tracking-protection-shield-color: #c069ff;
-}
-
 @keyframes tp-icon-animation {
   from {
     transform: translateX(0);
-    fill-opacity: 0.3;
   }
-  30% {
-    fill: inherit;
-    fill-opacity: 0.3;
-  }
-  31% {
-    fill: var(--tracking-protection-shield-color);
-    fill-opacity: 1;
-  }
-  50% {
-    transform: translateX(-1232px);
-  }
-  65% {
-    fill: var(--tracking-protection-shield-color);
-    fill-opacity: 1;
-  }
-  to {
-    fill: inherit;
-    fill-opacity: inherit;
+  100% {
+    transform: translateX(-2816px);
   }
 }
 
 @keyframes tp-icon-animation-rtl {
   from {
     transform: scaleX(-1) translateX(0);
-    fill-opacity: 0.3;
   }
-  30% {
-    fill: inherit;
-    fill-opacity: 0.3;
-  }
-  31% {
-    fill: var(--tracking-protection-shield-color);
-    fill-opacity: 1;
-  }
-  50% {
-    transform: scaleX(-1) translateX(-1232px);
-  }
-  65% {
-    fill: var(--tracking-protection-shield-color);
-    fill-opacity: 1;
-  }
-  to {
-    fill: inherit;
-    fill-opacity: inherit;
+  100% {
+    transform: scaleX(-1) translateX(-2816px);
   }
 }
 
 /* CONNECTION ICON, EXTENSION ICON, REMOTE CONTROL ICON */
 
 #connection-icon,
 #extension-icon,
 #remote-control-icon {
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/identity-block/tracking-protection-animation-brighttext.svg
@@ -0,0 +1,2464 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="2832" height="20">
+  <defs>
+    <path id="shape-0" d="M18 42.999l-0.336 -0.035a18.737 18.737 0 0 1 -12.036 -7.281 27.778 27.778 0 0 1 -5.4 -15.859c-0.228 -2.517 -0.228 -8.042 -0.228 -11.117a5.535 5.535 0 0 1 4.581 -5.467l13.419 -2.303 13.413 2.303a5.536 5.536 0 0 1 4.587 5.47c0 3.069 0 8.597 -0.24 11.114a27.778 27.778 0 0 1 -5.4 15.859 18.737 18.737 0 0 1 -12.036 7.281l-0.324 0.035zm-12 -33.917c0 4.875 -0.147 8.28 0 9.9a22.722 22.722 0 0 0 4.461 13.146 12.67 12.67 0 0 0 7.539 4.815 12.664 12.664 0 0 0 7.536 -4.815 22.725 22.725 0 0 0 4.464 -13.146c0.147 -1.62 0 -5.025 0 -9.9l-12 -2.055 -12 2.055z"/>
+    <path id="shape-1" d="M18 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    <path id="shape-2" d="M8 13.565l-0.06 -0.006a3.373 3.373 0 0 1 -2.167 -1.311 5 5 0 0 1 -0.972 -2.855c-0.041 -0.453 -0.041 -1.447 -0.041 -2a0.996 0.996 0 0 1 0.825 -0.985l2.415 -0.414 2.414 0.414a0.997 0.997 0 0 1 0.826 0.985c0 0.552 0 1.547 -0.043 2a5 5 0 0 1 -0.972 2.855 3.373 3.373 0 0 1 -2.167 1.31l-0.058 0.007zm-2.16 -6.105c0 0.877 -0.026 1.49 0 1.782a4.09 4.09 0 0 0 0.803 2.366 2.28 2.28 0 0 0 1.357 0.867 2.28 2.28 0 0 0 1.356 -0.867 4.09 4.09 0 0 0 0.804 -2.366c0.026 -0.292 0 -0.905 0 -1.782l-2.16 -0.37 -2.16 0.37z"/>
+    <path id="shape-3" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854"/>
+    <path id="shape-4" d="M8 17.435l-0.121 -0.013a6.745 6.745 0 0 1 -4.333 -2.621 10 10 0 0 1 -1.944 -5.71c-0.082 -0.905 -0.082 -2.894 -0.082 -4.001a1.993 1.993 0 0 1 1.65 -1.969l4.83 -0.829 4.829 0.83a1.993 1.993 0 0 1 1.651 1.969c0 1.104 0 3.095 -0.086 4a10 10 0 0 1 -1.944 5.71 6.745 6.745 0 0 1 -4.333 2.621l-0.117 0.013zm-4.32 -12.21c0 1.755 -0.053 2.98 0 3.564a8.18 8.18 0 0 0 1.606 4.732 4.562 4.562 0 0 0 2.714 1.733 4.559 4.559 0 0 0 2.713 -1.733 8.181 8.181 0 0 0 1.607 -4.732c0.053 -0.584 0 -1.81 0 -3.564l-4.32 -0.74 -4.32 0.74z"/>
+    <path id="shape-5" d="M-20.673 24.01l36.25 40.25 40.854 -40.854 -36 -40.25 -41.104 40.854"/>
+    <path id="shape-6" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
+  </defs>
+  <svg width="16" height="20">
+    <defs>
+      <mask id="a">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.332 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#BF68FF" mask="url(#a)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use href="#shape-0"/>
+      <path d="M11.681 12.84l-6.596 1.13c0.024 2.485 0.079 4.366 0.163 5.277a15.21 15.21 0 0 0 2.982 9.315 7.09 7.09 0 0 0 3.43 2.488h0.021v-18.21z" opacity=".419"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="16">
+    <defs>
+      <mask id="c">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.321 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="b">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".006"/>
+    <g mask="url(#b)" opacity=".045" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#c)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use href="#shape-0"/>
+      <path d="M11.556 12.862l-6.58 1.126c0.023 2.48 0.079 4.357 0.163 5.265a15.173 15.173 0 0 0 2.974 9.293 7.073 7.073 0 0 0 3.422 2.482h0.021v-18.166z" opacity=".412"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="32">
+    <defs>
+      <mask id="e">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.296 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="d">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".023"/>
+    <g mask="url(#d)" opacity=".098" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#e)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use href="#shape-0"/>
+      <path d="M11.432 12.883l-6.565 1.124c0.023 2.474 0.078 4.346 0.162 5.252a15.137 15.137 0 0 0 2.968 9.271 7.056 7.056 0 0 0 3.414 2.477h0.02v-18.124z" opacity=".404"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="48">
+    <defs>
+      <mask id="g">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.263 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="f">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".051"/>
+    <g mask="url(#f)" opacity=".159" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#g)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+      <use href="#shape-0"/>
+      <path d="M11.307 12.905l-6.55 1.121c0.024 2.468 0.08 4.336 0.163 5.24a15.1 15.1 0 0 0 2.96 9.248 7.04 7.04 0 0 0 3.406 2.47h0.02v-18.079z" opacity=".397"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="64">
+    <defs>
+      <mask id="i">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.223 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="h">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".087"/>
+    <g mask="url(#h)" opacity=".224" transform="translate(4.64 5.68) scale(.18672)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#i)" transform="translate(4.654 5.699) scale(.18588)">
+      <use href="#shape-0"/>
+      <path d="M11.182 12.927l-6.534 1.118c0.024 2.462 0.079 4.326 0.163 5.227a15.065 15.065 0 0 0 2.953 9.227 7.023 7.023 0 0 0 3.397 2.464h0.021v-18.036z" opacity=".39"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="80">
+    <defs>
+      <mask id="k">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.178 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="j">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".132"/>
+    <g mask="url(#j)" opacity=".294" transform="translate(4.308 5.285) scale(.20512)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#k)" transform="translate(4.364 5.352) scale(.20198)">
+      <use href="#shape-0"/>
+      <path d="M11.058 12.948l-6.518 1.116c0.023 2.456 0.078 4.315 0.161 5.215a15.029 15.029 0 0 0 2.946 9.204 7.006 7.006 0 0 0 3.39 2.459h0.02v-17.994z" opacity=".382"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="96">
+    <defs>
+      <mask id="m">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.13 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="l">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".183"/>
+    <g mask="url(#l)" opacity=".367" transform="translate(3.813 4.694) scale(.23261)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#m)" transform="translate(3.931 4.835) scale(.22603)">
+      <use href="#shape-0"/>
+      <path d="M10.933 12.97l-6.502 1.113c0.023 2.45 0.078 4.305 0.161 5.202a14.993 14.993 0 0 0 2.94 9.182 6.99 6.99 0 0 0 3.38 2.453h0.021v-17.95z" opacity=".375"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="112">
+    <defs>
+      <mask id="o">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.08 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="n">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-2" opacity=".239"/>
+    <g mask="url(#n)" opacity=".442" transform="translate(3.202 3.964) scale(.26658)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#o)" transform="translate(3.396 4.196) scale(.25575)">
+      <use href="#shape-0"/>
+      <path d="M10.809 12.991l-6.487 1.11c0.023 2.445 0.078 4.295 0.16 5.19a14.957 14.957 0 0 0 2.933 9.16 6.972 6.972 0 0 0 3.373 2.448h0.021v-17.908z" opacity=".368"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="128">
+    <defs>
+      <mask id="q">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.027 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="p">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 13.723l-0.063 -0.006a3.51 3.51 0 0 1 -2.255 -1.365 5.205 5.205 0 0 1 -1.012 -2.971c-0.043 -0.472 -0.043 -1.507 -0.043 -2.083a1.037 1.037 0 0 1 0.859 -1.024l2.514 -0.432 2.513 0.432a1.037 1.037 0 0 1 0.86 1.025c0 0.575 0 1.61 -0.045 2.082a5.205 5.205 0 0 1 -1.012 2.971 3.51 3.51 0 0 1 -2.255 1.365l-0.061 0.006zm-2.248 -6.355c0 0.914 -0.028 1.552 0 1.855a4.257 4.257 0 0 0 0.835 2.463 2.374 2.374 0 0 0 1.413 0.903 2.373 2.373 0 0 0 1.412 -0.903 4.258 4.258 0 0 0 0.836 -2.463c0.028 -0.303 0 -0.941 0 -1.855l-2.248 -0.385 -2.248 0.385z" opacity=".301"/>
+    <g mask="url(#p)" opacity=".517" transform="translate(2.52 3.15) scale(.30443)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#q)" transform="translate(2.8 3.484) scale(.28887)">
+      <use href="#shape-0"/>
+      <path d="M10.685 13.013l-6.472 1.108c0.024 2.438 0.078 4.284 0.16 5.177a14.921 14.921 0 0 0 2.926 9.138 6.956 6.956 0 0 0 3.365 2.441h0.02v-17.864z" opacity=".36"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="144">
+    <defs>
+      <mask id="s">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.973 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="r">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 14.153l-0.07 -0.007a3.885 3.885 0 0 1 -2.495 -1.51 5.76 5.76 0 0 1 -1.12 -3.289c-0.047 -0.521 -0.047 -1.667 -0.047 -2.305a1.148 1.148 0 0 1 0.95 -1.133l2.782 -0.478 2.781 0.478a1.148 1.148 0 0 1 0.951 1.134c0 0.636 0 1.783 -0.05 2.304a5.76 5.76 0 0 1 -1.12 3.289 3.885 3.885 0 0 1 -2.495 1.51l-0.067 0.007zm-2.488 -7.033c0 1.01 -0.03 1.717 0 2.053a4.712 4.712 0 0 0 0.925 2.726 2.627 2.627 0 0 0 1.563 0.998 2.626 2.626 0 0 0 1.563 -0.998 4.712 4.712 0 0 0 0.925 -2.726c0.03 -0.336 0 -1.042 0 -2.053l-2.488 -0.426 -2.488 0.426z" opacity=".365"/>
+    <g mask="url(#r)" opacity=".591" transform="translate(1.816 2.308) scale(.34357)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#s)" transform="translate(2.184 2.748) scale(.32313)">
+      <use href="#shape-0"/>
+      <path d="M10.56 13.034l-6.455 1.105c0.023 2.433 0.077 4.274 0.16 5.165a14.885 14.885 0 0 0 2.918 9.117 6.939 6.939 0 0 0 3.357 2.435h0.02v-17.822z" opacity=".353"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="160">
+    <defs>
+      <mask id="u">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.917 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="t">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 14.786l-0.08 -0.008a4.437 4.437 0 0 1 -2.85 -1.725 6.578 6.578 0 0 1 -1.278 -3.755c-0.054 -0.596 -0.054 -1.904 -0.054 -2.632a1.31 1.31 0 0 1 1.084 -1.295l3.178 -0.545 3.176 0.545a1.31 1.31 0 0 1 1.086 1.295c0 0.727 0 2.036 -0.057 2.632a6.578 6.578 0 0 1 -1.278 3.755 4.437 4.437 0 0 1 -2.85 1.725l-0.077 0.008zm-2.842 -8.031c0 1.154 -0.034 1.96 0 2.344a5.38 5.38 0 0 0 1.057 3.113 3 3 0 0 0 1.785 1.14 2.999 2.999 0 0 0 1.784 -1.14 5.381 5.381 0 0 0 1.058 -3.113c0.034 -0.384 0 -1.19 0 -2.344l-2.842 -0.487 -2.842 0.487z" opacity=".432"/>
+    <g mask="url(#t)" opacity=".663" transform="translate(1.134 1.494) scale(.38142)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#u)" transform="translate(1.588 2.036) scale(.35625)">
+      <use href="#shape-0"/>
+      <path d="M10.437 13.056l-6.44 1.102c0.023 2.427 0.077 4.264 0.16 5.152a14.85 14.85 0 0 0 2.91 9.095 6.922 6.922 0 0 0 3.35 2.43h0.02v-17.78z" opacity=".346"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="176">
+    <defs>
+      <mask id="w">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.86 59.76l5.5 5.5 40.853 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="v">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 15.554l-0.092 -0.01a5.106 5.106 0 0 1 -3.28 -1.984 7.57 7.57 0 0 1 -1.471 -4.322c-0.062 -0.686 -0.062 -2.191 -0.062 -3.03a1.509 1.509 0 0 1 1.248 -1.49l3.657 -0.627 3.655 0.628a1.509 1.509 0 0 1 1.25 1.49c0 0.837 0 2.343 -0.065 3.03a7.57 7.57 0 0 1 -1.472 4.321 5.106 5.106 0 0 1 -3.28 1.984l-0.088 0.01zm-3.27 -9.243c0 1.328 -0.04 2.256 0 2.698a6.192 6.192 0 0 0 1.215 3.582 3.453 3.453 0 0 0 2.055 1.313 3.451 3.451 0 0 0 2.054 -1.313 6.193 6.193 0 0 0 1.216 -3.582c0.04 -0.442 0 -1.37 0 -2.698l-3.27 -0.56 -3.27 0.56z" opacity=".5"/>
+    <g mask="url(#v)" opacity=".731" transform="translate(.523 .764) scale(.41539)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#w)" transform="translate(1.053 1.397) scale(.38597)">
+      <use href="#shape-0"/>
+      <path d="M10.314 13.077l-6.425 1.1c0.023 2.42 0.077 4.253 0.159 5.14a14.814 14.814 0 0 0 2.904 9.073 6.906 6.906 0 0 0 3.341 2.423h0.02v-17.736z" opacity=".338"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="192">
+    <defs>
+      <mask id="y">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.8 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="x">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 16.39l-0.105 -0.011a5.835 5.835 0 0 1 -3.748 -2.267 8.65 8.65 0 0 1 -1.681 -4.939c-0.071 -0.784 -0.071 -2.504 -0.071 -3.462a1.724 1.724 0 0 1 1.426 -1.702l4.179 -0.717 4.177 0.717a1.724 1.724 0 0 1 1.428 1.703c0 0.956 0 2.677 -0.075 3.461a8.65 8.65 0 0 1 -1.681 4.939 5.835 5.835 0 0 1 -3.748 2.267l-0.101 0.01zm-3.737 -10.562c0 1.518 -0.046 2.578 0 3.083a7.076 7.076 0 0 0 1.39 4.094 3.946 3.946 0 0 0 2.347 1.499 3.944 3.944 0 0 0 2.347 -1.5 7.077 7.077 0 0 0 1.39 -4.093c0.046 -0.505 0 -1.565 0 -3.083l-3.737 -0.64 -3.737 0.64z" opacity=".568"/>
+    <g mask="url(#x)" opacity=".795" transform="translate(.028 .173) scale(.44288)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#y)" transform="translate(.62 .88) scale(.41002)">
+      <use href="#shape-0"/>
+      <path d="M10.19 13.098l-6.41 1.098c0.024 2.415 0.078 4.243 0.16 5.127a14.778 14.778 0 0 0 2.897 9.051 6.89 6.89 0 0 0 3.333 2.418h0.02v-17.694z" opacity=".331"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="208">
+    <defs>
+      <mask id="A">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.741 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="z">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.226l-0.118 -0.013a6.563 6.563 0 0 1 -4.216 -2.55 9.73 9.73 0 0 1 -1.891 -5.555c-0.08 -0.882 -0.08 -2.817 -0.08 -3.894a1.939 1.939 0 0 1 1.605 -1.915l4.7 -0.807 4.698 0.807a1.94 1.94 0 0 1 1.607 1.916c0 1.075 0 3.011 -0.084 3.893a9.73 9.73 0 0 1 -1.892 5.555 6.563 6.563 0 0 1 -4.216 2.55l-0.113 0.013zm-4.203 -11.88c0 1.707 -0.052 2.9 0 3.467a7.96 7.96 0 0 0 1.562 4.605 4.438 4.438 0 0 0 2.641 1.686 4.436 4.436 0 0 0 2.64 -1.686 7.96 7.96 0 0 0 1.563 -4.605c0.052 -0.567 0 -1.76 0 -3.468l-4.203 -0.72 -4.203 0.72z" opacity=".635"/>
+    <g mask="url(#z)" opacity=".852" transform="translate(-.303 -.223) scale(.46128)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#A)" transform="translate(.33 .533) scale(.42612)">
+      <use href="#shape-0"/>
+      <path d="M10.067 13.12l-6.394 1.094c0.023 2.41 0.077 4.233 0.159 5.115a14.743 14.743 0 0 0 2.89 9.03 6.873 6.873 0 0 0 3.325 2.412h0.02v-17.652z" opacity=".324"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="224">
+    <defs>
+      <mask id="C">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.68 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="B">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.994l-0.13 -0.014a7.232 7.232 0 0 1 -4.646 -2.81 10.723 10.723 0 0 1 -2.084 -6.122c-0.088 -0.972 -0.088 -3.104 -0.088 -4.291a2.137 2.137 0 0 1 1.768 -2.11l5.18 -0.89 5.178 0.89a2.137 2.137 0 0 1 1.77 2.111c0 1.185 0 3.318 -0.093 4.29a10.723 10.723 0 0 1 -2.084 6.122 7.232 7.232 0 0 1 -4.646 2.81l-0.125 0.014zm-4.632 -13.092c0 1.881 -0.057 3.196 0 3.821a8.771 8.771 0 0 0 1.722 5.074 4.891 4.891 0 0 0 2.91 1.86 4.888 4.888 0 0 0 2.909 -1.86 8.772 8.772 0 0 0 1.723 -5.074c0.057 -0.625 0 -1.94 0 -3.821l-4.632 -0.794 -4.632 0.794z" opacity=".699"/>
+    <g mask="url(#B)" opacity=".902" transform="matrix(.468 0 0 .468 -.424 -.367)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#C)" transform="matrix(.432 0 0 .432 .224 .407)">
+      <use href="#shape-0"/>
+      <path d="M9.944 13.14l-6.378 1.093c0.023 2.403 0.076 4.222 0.158 5.103a14.707 14.707 0 0 0 2.883 9.007 6.856 6.856 0 0 0 3.317 2.406h0.02v-17.608z" opacity=".316"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="240">
+    <defs>
+      <mask id="E">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.62 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="D">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.627l-0.14 -0.015a7.784 7.784 0 0 1 -5 -3.025 11.54 11.54 0 0 1 -2.243 -6.588c-0.095 -1.046 -0.095 -3.341 -0.095 -4.619a2.3 2.3 0 0 1 1.903 -2.271l5.575 -0.957 5.572 0.957a2.3 2.3 0 0 1 1.906 2.272c0 1.275 0 3.572 -0.1 4.618a11.54 11.54 0 0 1 -2.243 6.588 7.784 7.784 0 0 1 -5 3.025l-0.135 0.015zm-4.985 -14.091c0 2.025 -0.061 3.44 0 4.113a9.44 9.44 0 0 0 1.853 5.461 5.264 5.264 0 0 0 3.132 2 5.261 5.261 0 0 0 3.13 -2 9.441 9.441 0 0 0 1.855 -5.461c0.061 -0.673 0 -2.088 0 -4.113l-4.985 -0.854 -4.985 0.854z" opacity=".761"/>
+    <g mask="url(#D)" opacity=".943" transform="translate(-.402 -.34) scale(.46679)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#E)" transform="translate(.24 .427) scale(.43108)">
+      <use href="#shape-0"/>
+      <path d="M9.822 13.162l-6.364 1.09c0.023 2.397 0.077 4.212 0.158 5.09a14.672 14.672 0 0 0 2.877 8.986 6.84 6.84 0 0 0 3.309 2.4h0.02v-17.566z" opacity=".309"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="256">
+    <defs>
+      <mask id="G">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.558 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="F">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 19.056l-0.146 -0.015a8.158 8.158 0 0 1 -5.241 -3.17 12.095 12.095 0 0 1 -2.351 -6.906c-0.1 -1.096 -0.1 -3.502 -0.1 -4.84a2.41 2.41 0 0 1 1.995 -2.381l5.843 -1.003 5.84 1.003a2.41 2.41 0 0 1 1.998 2.382c0 1.336 0 3.743 -0.105 4.84a12.095 12.095 0 0 1 -2.351 6.905 8.158 8.158 0 0 1 -5.24 3.17l-0.142 0.015zm-5.225 -14.768c0 2.123 -0.064 3.605 0 4.31a9.894 9.894 0 0 0 1.942 5.725 5.517 5.517 0 0 0 3.283 2.096 5.514 5.514 0 0 0 3.281 -2.096 9.895 9.895 0 0 0 1.944 -5.724c0.064 -0.706 0 -2.188 0 -4.311l-5.225 -0.895 -5.225 0.895z" opacity=".817"/>
+    <g mask="url(#F)" opacity=".974" transform="translate(-.34 -.267) scale(.46335)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#G)" transform="translate(.287 .482) scale(.4285)">
+      <use href="#shape-0"/>
+      <path d="M9.7 13.183l-6.348 1.087c0.022 2.392 0.076 4.202 0.157 5.078a14.637 14.637 0 0 0 2.87 8.965 6.823 6.823 0 0 0 3.3 2.394h0.02v-17.524z" opacity=".301"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="272">
+    <defs>
+      <mask id="I">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.496 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="H">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 19.215l-0.149 -0.016a8.297 8.297 0 0 1 -5.33 -3.224 12.3 12.3 0 0 1 -2.39 -7.022c-0.101 -1.115 -0.101 -3.561 -0.101 -4.923a2.451 2.451 0 0 1 2.028 -2.42l5.942 -1.02 5.94 1.02a2.451 2.451 0 0 1 2.03 2.422c0 1.359 0 3.806 -0.106 4.92a12.3 12.3 0 0 1 -2.391 7.023 8.297 8.297 0 0 1 -5.33 3.224l-0.143 0.016zm-5.314 -15.019c0 2.159 -0.065 3.667 0 4.384a10.061 10.061 0 0 0 1.976 5.821 5.61 5.61 0 0 0 3.338 2.132 5.608 5.608 0 0 0 3.337 -2.132 10.063 10.063 0 0 0 1.977 -5.821c0.065 -0.717 0 -2.225 0 -4.384l-5.314 -0.91 -5.314 0.91z" opacity=".868"/>
+    <g mask="url(#H)" opacity=".993" transform="translate(-.244 -.153) scale(.45802)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#I)" transform="translate(.359 .568) scale(.4245)">
+      <use href="#shape-0"/>
+      <path d="M9.578 13.204l-6.333 1.084c0.023 2.386 0.076 4.192 0.157 5.066a14.602 14.602 0 0 0 2.863 8.943 6.807 6.807 0 0 0 3.293 2.39h0.02v-17.483z" opacity=".294"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="288">
+    <defs>
+      <mask id="K">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.433 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="J">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 19.195l-0.148 -0.016a8.28 8.28 0 0 1 -5.319 -3.217 12.274 12.274 0 0 1 -2.386 -7.008c-0.1 -1.112 -0.1 -3.553 -0.1 -4.912a2.446 2.446 0 0 1 2.024 -2.416l5.929 -1.017 5.927 1.017a2.446 2.446 0 0 1 2.027 2.418c0 1.356 0 3.798 -0.106 4.91a12.274 12.274 0 0 1 -2.387 7.008 8.28 8.28 0 0 1 -5.318 3.217l-0.143 0.016zm-5.302 -14.987c0 2.154 -0.065 3.659 0 4.374a10.04 10.04 0 0 0 1.97 5.81 5.599 5.599 0 0 0 3.332 2.127 5.596 5.596 0 0 0 3.33 -2.128 10.042 10.042 0 0 0 1.972 -5.809c0.065 -0.715 0 -2.22 0 -4.374l-5.302 -0.908 -5.302 0.908z" opacity=".913"/>
+    <g mask="url(#J)" transform="translate(-.12 -.004) scale(.45111)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#K)" transform="translate(.451 .679) scale(.41936)">
+      <use href="#shape-0"/>
+      <path d="M9.457 13.225l-6.318 1.081c0.022 2.38 0.076 4.183 0.156 5.055a14.567 14.567 0 0 0 2.856 8.921 6.79 6.79 0 0 0 3.285 2.383h0.02v-17.44z" opacity=".287"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="304">
+    <defs>
+      <mask id="M">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.37 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="L">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 19.138l-0.148 -0.015a8.23 8.23 0 0 1 -5.286 -3.198 12.201 12.201 0 0 1 -2.372 -6.966c-0.1 -1.106 -0.1 -3.533 -0.1 -4.883a2.431 2.431 0 0 1 2.012 -2.401l5.894 -1.012 5.891 1.012a2.432 2.432 0 0 1 2.015 2.402c0 1.348 0 3.776 -0.105 4.882a12.201 12.201 0 0 1 -2.372 6.966 8.23 8.23 0 0 1 -5.287 3.198l-0.142 0.015zm-5.27 -14.897c0 2.14 -0.065 3.636 0 4.348a9.98 9.98 0 0 0 1.959 5.774 5.566 5.566 0 0 0 3.311 2.115 5.562 5.562 0 0 0 3.31 -2.115 9.982 9.982 0 0 0 1.96 -5.774c0.065 -0.712 0 -2.207 0 -4.348l-5.27 -0.903 -5.27 0.903z" opacity=".949"/>
+    <g mask="url(#L)" transform="translate(.027 .172) scale(.44294)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#M)" transform="translate(.56 .808) scale(.41333)">
+      <use href="#shape-0"/>
+      <path d="M9.336 13.246l-6.303 1.079c0.023 2.374 0.075 4.172 0.156 5.042a14.532 14.532 0 0 0 2.849 8.9 6.774 6.774 0 0 0 3.277 2.377h0.02v-17.398z" opacity=".279"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="320">
+    <defs>
+      <mask id="O">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.307 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="N">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 19.05l-0.146 -0.015a8.153 8.153 0 0 1 -5.238 -3.168 12.088 12.088 0 0 1 -2.35 -6.901c-0.099 -1.096 -0.099 -3.5 -0.099 -4.838a2.409 2.409 0 0 1 1.994 -2.379l5.839 -1.002 5.837 1.002a2.41 2.41 0 0 1 1.996 2.38c0 1.336 0 3.741 -0.105 4.837a12.088 12.088 0 0 1 -2.35 6.9 8.153 8.153 0 0 1 -5.237 3.17l-0.141 0.014zm-5.222 -14.759c0 2.122 -0.064 3.603 0 4.308a9.888 9.888 0 0 0 1.941 5.72 5.514 5.514 0 0 0 3.281 2.096 5.51 5.51 0 0 0 3.28 -2.095 9.889 9.889 0 0 0 1.942 -5.72c0.064 -0.706 0 -2.187 0 -4.309l-5.222 -0.894 -5.222 0.894z" opacity=".977"/>
+    <g mask="url(#N)" transform="translate(.191 .368) scale(.43382)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#O)" transform="translate(.68 .952) scale(.40665)">
+      <use href="#shape-0"/>
+      <path d="M9.215 13.266l-6.288 1.077c0.023 2.369 0.076 4.162 0.156 5.03a14.497 14.497 0 0 0 2.842 8.879 6.758 6.758 0 0 0 3.27 2.372h0.02v-17.358z" opacity=".272"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="336">
+    <defs>
+      <mask id="Q">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.244 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="P">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.936l-0.144 -0.015a8.054 8.054 0 0 1 -5.174 -3.13 11.94 11.94 0 0 1 -2.321 -6.816c-0.098 -1.082 -0.098 -3.457 -0.098 -4.78a2.38 2.38 0 0 1 1.969 -2.35l5.768 -0.99 5.766 0.99a2.38 2.38 0 0 1 1.971 2.352c0 1.32 0 3.696 -0.103 4.778a11.94 11.94 0 0 1 -2.321 6.817 8.054 8.054 0 0 1 -5.174 3.13l-0.139 0.014zm-5.158 -14.579c0 2.096 -0.063 3.56 0 4.256a9.767 9.767 0 0 0 1.917 5.65 5.447 5.447 0 0 0 3.241 2.07 5.444 5.444 0 0 0 3.24 -2.07 9.769 9.769 0 0 0 1.918 -5.65c0.063 -0.697 0 -2.16 0 -4.256l-5.158 -0.883 -5.158 0.883z" opacity=".994"/>
+    <g mask="url(#P)" transform="translate(.367 .578) scale(.42407)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#Q)" transform="translate(.807 1.104) scale(.3996)">
+      <use href="#shape-0"/>
+      <path d="M9.095 13.287l-6.273 1.074c0.023 2.363 0.075 4.152 0.156 5.018a14.463 14.463 0 0 0 2.835 8.858 6.742 6.742 0 0 0 3.262 2.366h0.02v-17.316z" opacity=".265"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="352">
+    <defs>
+      <mask id="S">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.18 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="R">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.802l-0.142 -0.015a7.937 7.937 0 0 1 -5.099 -3.084 11.766 11.766 0 0 1 -2.287 -6.718c-0.097 -1.066 -0.097 -3.406 -0.097 -4.709a2.345 2.345 0 0 1 1.94 -2.316l5.685 -0.975 5.682 0.975a2.345 2.345 0 0 1 1.943 2.317c0 1.3 0 3.642 -0.102 4.708a11.766 11.766 0 0 1 -2.287 6.718 7.937 7.937 0 0 1 -5.099 3.084l-0.137 0.015zm-5.083 -14.367c0 2.065 -0.062 3.507 0 4.193a9.625 9.625 0 0 0 1.89 5.569 5.367 5.367 0 0 0 3.193 2.04 5.364 5.364 0 0 0 3.192 -2.04 9.626 9.626 0 0 0 1.891 -5.569c0.062 -0.686 0 -2.128 0 -4.193l-5.083 -0.87 -5.083 0.87z"/>
+    <g mask="url(#R)" transform="matrix(.414 0 0 .414 .548 .794)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#S)" transform="translate(.937 1.258) scale(.3924)">
+      <use href="#shape-0"/>
+      <path d="M8.975 13.308l-6.258 1.071c0.023 2.358 0.076 4.143 0.156 5.006a14.428 14.428 0 0 0 2.828 8.837 6.726 6.726 0 0 0 3.254 2.36h0.02v-17.274z" opacity=".257"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="368">
+    <defs>
+      <mask id="U">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.116 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="T">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.651l-0.14 -0.014a7.806 7.806 0 0 1 -5.014 -3.033 11.572 11.572 0 0 1 -2.25 -6.607c-0.095 -1.049 -0.095 -3.35 -0.095 -4.631a2.306 2.306 0 0 1 1.909 -2.278l5.59 -0.96 5.588 0.96a2.306 2.306 0 0 1 1.91 2.279c0 1.278 0 3.581 -0.1 4.63a11.572 11.572 0 0 1 -2.249 6.607 7.806 7.806 0 0 1 -5.014 3.033l-0.135 0.014zm-5 -14.13c0 2.032 -0.06 3.45 0 4.125a9.466 9.466 0 0 0 1.86 5.477 5.279 5.279 0 0 0 3.14 2.005 5.276 5.276 0 0 0 3.14 -2.005 9.467 9.467 0 0 0 1.86 -5.477c0.06 -0.675 0 -2.093 0 -4.124l-5 -0.856 -5 0.856z"/>
+    <g mask="url(#T)" transform="translate(.73 1.01) scale(.40393)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#U)" transform="translate(1.064 1.41) scale(.38535)">
+      <use href="#shape-0"/>
+      <path d="M8.856 13.328l-6.243 1.069c0.023 2.352 0.075 4.133 0.155 4.994a14.394 14.394 0 0 0 2.822 8.816 6.71 6.71 0 0 0 3.246 2.355h0.02v-17.234z" opacity=".25"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="384">
+    <defs>
+      <mask id="W">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.053 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="V">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.49l-0.137 -0.014a7.665 7.665 0 0 1 -4.925 -2.978 11.365 11.365 0 0 1 -2.209 -6.489c-0.093 -1.03 -0.093 -3.29 -0.093 -4.548a2.265 2.265 0 0 1 1.874 -2.237l5.49 -0.942 5.488 0.942a2.265 2.265 0 0 1 1.876 2.238c0 1.256 0 3.518 -0.098 4.547a11.365 11.365 0 0 1 -2.21 6.489 7.665 7.665 0 0 1 -4.923 2.978l-0.133 0.015zm-4.91 -13.875c0 1.994 -0.06 3.387 0 4.05a9.296 9.296 0 0 0 1.826 5.378 5.184 5.184 0 0 0 3.084 1.97 5.181 5.181 0 0 0 3.083 -1.97 9.297 9.297 0 0 0 1.826 -5.378c0.06 -0.663 0 -2.056 0 -4.05l-4.909 -0.841 -4.91 0.84z"/>
+    <g mask="url(#V)" transform="translate(.905 1.22) scale(.39418)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#W)" transform="translate(1.184 1.554) scale(.37867)">
+      <use href="#shape-0"/>
+      <path d="M8.738 13.349l-6.229 1.066c0.023 2.347 0.075 4.123 0.155 4.982a14.36 14.36 0 0 0 2.815 8.795 6.694 6.694 0 0 0 3.239 2.35h0.02v-17.193z" opacity=".243"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="400">
+    <defs>
+      <mask id="Y">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.989 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="X">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.325l-0.135 -0.014a7.52 7.52 0 0 1 -4.831 -2.923 11.15 11.15 0 0 1 -2.168 -6.366c-0.091 -1.01 -0.091 -3.228 -0.091 -4.462a2.222 2.222 0 0 1 1.839 -2.195l5.386 -0.924 5.384 0.924a2.222 2.222 0 0 1 1.841 2.196c0 1.232 0 3.45 -0.096 4.461a11.15 11.15 0 0 1 -2.168 6.366 7.52 7.52 0 0 1 -4.83 2.923l-0.131 0.014zm-4.817 -13.615c0 1.957 -0.059 3.324 0 3.974a9.12 9.12 0 0 0 1.79 5.277 5.086 5.086 0 0 0 3.027 1.933 5.083 5.083 0 0 0 3.025 -1.933 9.122 9.122 0 0 0 1.792 -5.277c0.059 -0.65 0 -2.017 0 -3.974l-4.817 -0.824 -4.817 0.824z"/>
+    <g mask="url(#X)" transform="translate(1.069 1.416) scale(.38506)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#Y)" transform="translate(1.293 1.683) scale(.37264)">
+      <use href="#shape-0"/>
+      <path d="M8.62 13.369l-6.214 1.064c0.023 2.34 0.075 4.113 0.154 4.97a14.326 14.326 0 0 0 2.809 8.774 6.678 6.678 0 0 0 3.23 2.344h0.02v-17.152z" opacity=".235"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="416">
+    <defs>
+      <mask id="aa">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.925 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="Z">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 18.159l-0.132 -0.014a7.376 7.376 0 0 1 -4.739 -2.866 10.936 10.936 0 0 1 -2.126 -6.244c-0.09 -0.99 -0.09 -3.166 -0.09 -4.376a2.18 2.18 0 0 1 1.804 -2.153l5.283 -0.906 5.28 0.906a2.18 2.18 0 0 1 1.806 2.154c0 1.208 0 3.384 -0.094 4.375a10.936 10.936 0 0 1 -2.126 6.244 7.376 7.376 0 0 1 -4.738 2.866l-0.128 0.014zm-4.724 -13.353c0 1.92 -0.058 3.26 0 3.898a8.945 8.945 0 0 0 1.756 5.175 4.988 4.988 0 0 0 2.968 1.896 4.986 4.986 0 0 0 2.967 -1.896 8.947 8.947 0 0 0 1.757 -5.175c0.058 -0.638 0 -1.979 0 -3.898l-4.724 -0.809 -4.724 0.81z"/>
+    <g mask="url(#Z)" transform="translate(1.216 1.592) scale(.37689)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aa)" transform="translate(1.385 1.794) scale(.3675)">
+      <use href="#shape-0"/>
+      <path d="M8.502 13.389l-6.199 1.061c0.023 2.336 0.075 4.104 0.154 4.96a14.293 14.293 0 0 0 2.802 8.753 6.663 6.663 0 0 0 3.223 2.338h0.02v-17.112z" opacity=".228"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="432">
+    <defs>
+      <mask id="ac">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.862 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ab">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.998l-0.13 -0.013a7.236 7.236 0 0 1 -4.648 -2.812 10.728 10.728 0 0 1 -2.086 -6.125c-0.088 -0.972 -0.088 -3.106 -0.088 -4.294a2.138 2.138 0 0 1 1.77 -2.111l5.182 -0.89 5.18 0.89a2.138 2.138 0 0 1 1.772 2.112c0 1.186 0 3.32 -0.093 4.293a10.728 10.728 0 0 1 -2.086 6.125 7.236 7.236 0 0 1 -4.648 2.812l-0.125 0.013zm-4.634 -13.099c0 1.883 -0.057 3.198 0 3.824a8.775 8.775 0 0 0 1.722 5.077 4.894 4.894 0 0 0 2.912 1.86 4.89 4.89 0 0 0 2.91 -1.86 8.777 8.777 0 0 0 1.724 -5.077c0.057 -0.626 0 -1.941 0 -3.824l-4.634 -0.794 -4.634 0.794z"/>
+    <g mask="url(#ab)" transform="translate(1.34 1.74) scale(.36998)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ac)" transform="translate(1.457 1.88) scale(.3635)">
+      <use href="#shape-0"/>
+      <path d="M8.386 13.409l-6.185 1.059c0.023 2.33 0.075 4.094 0.154 4.947a14.26 14.26 0 0 0 2.795 8.733 6.647 6.647 0 0 0 3.216 2.333h0.02v-17.072z" opacity=".221"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="448">
+    <defs>
+      <mask id="ae">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.799 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ad">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.848l-0.127 -0.014a7.105 7.105 0 0 1 -4.565 -2.76 10.534 10.534 0 0 1 -2.047 -6.015c-0.087 -0.954 -0.087 -3.05 -0.087 -4.215a2.1 2.1 0 0 1 1.737 -2.073l5.089 -0.874 5.086 0.874a2.1 2.1 0 0 1 1.74 2.074c0 1.164 0 3.26 -0.091 4.214a10.534 10.534 0 0 1 -2.048 6.014 7.105 7.105 0 0 1 -4.564 2.761l-0.123 0.014zm-4.55 -12.862c0 1.849 -0.056 3.14 0 3.754a8.617 8.617 0 0 0 1.691 4.985 4.805 4.805 0 0 0 2.859 1.826 4.802 4.802 0 0 0 2.858 -1.826 8.618 8.618 0 0 0 1.693 -4.985c0.055 -0.614 0 -1.905 0 -3.754l-4.551 -0.78 -4.55 0.78z"/>
+    <g mask="url(#ad)" transform="translate(1.436 1.855) scale(.36465)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ae)" transform="translate(1.503 1.935) scale(.36092)">
+      <use href="#shape-0"/>
+      <path d="M8.27 13.429l-6.17 1.056c0.022 2.325 0.074 4.085 0.153 4.936a14.226 14.226 0 0 0 2.789 8.713 6.632 6.632 0 0 0 3.208 2.327h0.02v-17.032z" opacity=".213"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="464">
+    <defs>
+      <mask id="ag">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.736 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="af">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.713l-0.125 -0.013a6.988 6.988 0 0 1 -4.49 -2.716 10.36 10.36 0 0 1 -2.013 -5.914c-0.085 -0.939 -0.085 -3 -0.085 -4.146a2.064 2.064 0 0 1 1.708 -2.039l5.005 -0.859 5.002 0.859a2.065 2.065 0 0 1 1.711 2.04c0 1.145 0 3.206 -0.09 4.145a10.36 10.36 0 0 1 -2.013 5.914 6.988 6.988 0 0 1 -4.49 2.716l-0.12 0.013zm-4.475 -12.65c0 1.819 -0.055 3.089 0 3.693a8.474 8.474 0 0 0 1.663 4.903 4.726 4.726 0 0 0 2.812 1.795 4.723 4.723 0 0 0 2.81 -1.795 8.475 8.475 0 0 0 1.665 -4.903c0.055 -0.604 0 -1.874 0 -3.692l-4.475 -0.767 -4.475 0.767z"/>
+    <g mask="url(#af)" transform="translate(1.498 1.929) scale(.36121)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ag)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M8.155 13.449l-6.156 1.053c0.022 2.32 0.074 4.075 0.153 4.925a14.193 14.193 0 0 0 2.782 8.692 6.616 6.616 0 0 0 3.2 2.322h0.02v-16.992z" opacity=".206"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="480">
+    <defs>
+      <mask id="ai">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.673 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ah">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.6l-0.124 -0.014a6.888 6.888 0 0 1 -4.425 -2.677 10.213 10.213 0 0 1 -1.985 -5.83c-0.084 -0.926 -0.084 -2.957 -0.084 -4.087a2.035 2.035 0 0 1 1.685 -2.01l4.933 -0.847 4.931 0.847a2.035 2.035 0 0 1 1.687 2.01c0 1.13 0 3.161 -0.089 4.087a10.213 10.213 0 0 1 -1.985 5.83 6.888 6.888 0 0 1 -4.425 2.677l-0.119 0.013zm-4.412 -12.47c0 1.792 -0.054 3.044 0 3.64a8.354 8.354 0 0 0 1.64 4.832 4.658 4.658 0 0 0 2.772 1.77 4.656 4.656 0 0 0 2.77 -1.77 8.355 8.355 0 0 0 1.642 -4.833c0.054 -0.595 0 -1.847 0 -3.64l-4.412 -0.755 -4.412 0.756z"/>
+    <g mask="url(#ah)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ai)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M8.04 13.468l-6.141 1.052c0.022 2.314 0.073 4.065 0.152 4.913a14.16 14.16 0 0 0 2.776 8.672 6.6 6.6 0 0 0 3.193 2.317h0.02v-16.954z" opacity=".199"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="496">
+    <defs>
+      <mask id="ak">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.61 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aj">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M8.243 58.758l6.362 6.474 40.854 -40.854 -6.355 -6.474 -40.861 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.511l-0.122 -0.012a6.812 6.812 0 0 1 -4.376 -2.648 10.1 10.1 0 0 1 -1.963 -5.765c-0.083 -0.915 -0.083 -2.924 -0.083 -4.042a2.012 2.012 0 0 1 1.665 -1.988l4.879 -0.837 4.876 0.837a2.013 2.013 0 0 1 1.668 1.989c0 1.116 0 3.126 -0.087 4.04a10.1 10.1 0 0 1 -1.963 5.766 6.812 6.812 0 0 1 -4.376 2.648l-0.118 0.012zm-4.363 -12.33c0 1.772 -0.053 3.01 0 3.599a8.261 8.261 0 0 0 1.622 4.779 4.607 4.607 0 0 0 2.741 1.75 4.604 4.604 0 0 0 2.74 -1.75 8.262 8.262 0 0 0 1.623 -4.78c0.053 -0.588 0 -1.826 0 -3.599l-4.363 -0.747 -4.363 0.747z"/>
+    <g mask="url(#aj)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ak)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.927 13.488l-6.128 1.049c0.022 2.308 0.074 4.056 0.152 4.902a14.128 14.128 0 0 0 2.77 8.652 6.586 6.586 0 0 0 3.186 2.311h0.02v-16.914z" opacity=".191"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="512">
+    <defs>
+      <mask id="am">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.55 59.76l5.498 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="al">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M5.98 56.039l8.701 9.117 40.854 -40.854 -8.675 -9.117 -40.88 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <path fill="#F9F9F9" fill-opacity=".2" d="M8 17.455l-0.121 -0.013a6.763 6.763 0 0 1 -4.344 -2.628 10.026 10.026 0 0 1 -1.95 -5.724c-0.082 -0.908 -0.082 -2.903 -0.082 -4.012a1.998 1.998 0 0 1 1.654 -1.974l4.843 -0.83 4.841 0.83a1.998 1.998 0 0 1 1.656 1.975c0 1.107 0 3.103 -0.087 4.011a10.026 10.026 0 0 1 -1.949 5.724 6.763 6.763 0 0 1 -4.344 2.628l-0.117 0.013zm-4.331 -12.242c0 1.76 -0.053 2.988 0 3.573a8.201 8.201 0 0 0 1.61 4.745 4.573 4.573 0 0 0 2.721 1.738 4.57 4.57 0 0 0 2.72 -1.738 8.202 8.202 0 0 0 1.611 -4.745c0.053 -0.585 0 -1.814 0 -3.573l-4.331 -0.742 -4.331 0.742z"/>
+    <g mask="url(#al)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#am)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.814 13.507l-6.113 1.047c0.022 2.303 0.073 4.047 0.151 4.89a14.095 14.095 0 0 0 2.764 8.633 6.57 6.57 0 0 0 3.178 2.306h0.02v-16.876z" opacity=".184"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="528">
+    <defs>
+      <mask id="ao">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.488 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="an">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M2.648 52.034l12.145 13.01 40.854 -40.854 -12.091 -13.01 -40.908 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#an)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ao)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.702 13.526l-6.099 1.044c0.022 2.299 0.073 4.038 0.151 4.88a14.063 14.063 0 0 0 2.757 8.613 6.556 6.556 0 0 0 3.172 2.3h0.02v-16.837z" opacity=".176"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="544">
+    <defs>
+      <mask id="aq">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.428 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ap">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-1.397 47.174l16.326 17.734 40.854 -40.854 -16.238 -17.734 -40.942 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#ap)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aq)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.592 13.545l-6.086 1.042c0.022 2.293 0.073 4.029 0.151 4.869a14.032 14.032 0 0 0 2.75 8.593 6.541 6.541 0 0 0 3.165 2.296h0.02v-16.8z" opacity=".169"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="560">
+    <defs>
+      <mask id="as">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.368 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ar">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-5.798 41.885l20.875 22.875 40.854 -40.854 -20.75 -22.875 -40.979 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#ar)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#as)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.482 13.564l-6.072 1.04c0.022 2.287 0.073 4.02 0.15 4.857a14 14 0 0 0 2.745 8.575 6.527 6.527 0 0 0 3.158 2.29h0.02v-16.762z" opacity=".162"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="576">
+    <defs>
+      <mask id="au">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.31 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="at">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-10.199 36.596l25.424 28.016 40.854 -40.854 -25.262 -28.016 -41.016 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#at)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#au)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.374 13.582l-6.059 1.038c0.022 2.283 0.073 4.01 0.15 4.847a13.97 13.97 0 0 0 2.74 8.555 6.512 6.512 0 0 0 3.15 2.286h0.019v-16.726z" opacity=".154"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="592">
+    <defs>
+      <mask id="aw">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.252 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="av">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-14.244 31.736l29.605 32.74 40.854 -40.854 -29.409 -32.74 -41.05 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#av)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aw)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.267 13.6l-6.045 1.036c0.021 2.278 0.072 4.002 0.15 4.836a13.939 13.939 0 0 0 2.732 8.537 6.498 6.498 0 0 0 3.144 2.28h0.019v-16.688z" opacity=".147"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="608">
+    <defs>
+      <mask id="ay">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.196 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="ax">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-17.576 27.731l33.049 36.633 40.854 -40.854 -32.825 -36.633 -41.078 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#ax)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ay)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.161 13.619l-6.032 1.032c0.022 2.273 0.072 3.994 0.15 4.826a13.909 13.909 0 0 0 2.726 8.519 6.484 6.484 0 0 0 3.137 2.275h0.02v-16.652z" opacity=".14"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="624">
+    <defs>
+      <mask id="aA">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.142 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="az">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-19.839 25.012l35.388 39.276 40.854 -40.854 -35.145 -39.276 -41.097 40.854" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#az)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aA)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M7.057 13.636l-6.02 1.031c0.022 2.268 0.073 3.985 0.15 4.816a13.879 13.879 0 0 0 2.72 8.5 6.47 6.47 0 0 0 3.13 2.27h0.02v-16.617z" opacity=".132"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="640">
+    <defs>
+      <mask id="aC">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.089 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aB">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aB)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aC)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.954 13.654l-6.006 1.028c0.021 2.264 0.072 3.977 0.149 4.806a13.85 13.85 0 0 0 2.715 8.482 6.456 6.456 0 0 0 3.123 2.266h0.02v-16.582z" opacity=".125"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="656">
+    <defs>
+      <mask id="aE">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.038 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aD">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aD)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aE)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.853 13.671l-5.994 1.026c0.022 2.26 0.072 3.969 0.149 4.796a13.821 13.821 0 0 0 2.71 8.465 6.443 6.443 0 0 0 3.116 2.26h0.02v-16.547z" opacity=".118"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="672">
+    <defs>
+      <mask id="aG">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.99 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aF">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aF)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aG)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.754 13.688l-5.982 1.024c0.022 2.254 0.072 3.96 0.149 4.786a13.793 13.793 0 0 0 2.703 8.447 6.43 6.43 0 0 0 3.111 2.257h0.02v-16.514z" opacity=".11"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="688">
+    <defs>
+      <mask id="aI">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.946 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aH">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aH)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aI)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.657 13.705l-5.97 1.022c0.022 2.25 0.072 3.952 0.148 4.776a13.765 13.765 0 0 0 2.699 8.43 6.417 6.417 0 0 0 3.104 2.252h0.02v-16.48z" opacity=".103"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="704">
+    <defs>
+      <mask id="aK">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.906 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aJ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aJ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aK)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.562 13.72l-5.958 1.02c0.021 2.246 0.071 3.945 0.147 4.768a13.738 13.738 0 0 0 2.694 8.414 6.404 6.404 0 0 0 3.098 2.247h0.02v-16.448z" opacity=".096"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="720">
+    <defs>
+      <mask id="aM">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.873 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aL">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aL)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aM)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.47 13.737l-5.948 1.018c0.022 2.24 0.072 3.937 0.148 4.757a13.712 13.712 0 0 0 2.688 8.398 6.392 6.392 0 0 0 3.092 2.243h0.02v-16.416z" opacity=".088"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="736">
+    <defs>
+      <mask id="aO">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.848 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aN">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aN)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aO)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.38 13.752l-5.937 1.016c0.022 2.237 0.072 3.93 0.148 4.749a13.686 13.686 0 0 0 2.683 8.382 6.38 6.38 0 0 0 3.086 2.24h0.02v-16.387z" opacity=".081"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="752">
+    <defs>
+      <mask id="aQ">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.837 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      </mask>
+      <mask id="aP">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aP)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aQ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.292 13.767l-5.925 1.014c0.021 2.233 0.07 3.923 0.147 4.74a13.662 13.662 0 0 0 2.678 8.367 6.369 6.369 0 0 0 3.081 2.235h0.019v-16.356z" opacity=".074"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="768">
+    <defs>
+      <mask id="aS">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M8.982 58.685l6.36 6.474 40.856 -40.854 -6.355 -6.474 -40.861 40.854" filter="null"/>
+      </mask>
+      <mask id="aR">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aR)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aS)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.208 13.781l-5.915 1.013c0.021 2.228 0.07 3.915 0.147 4.731a13.638 13.638 0 0 0 2.673 8.353 6.357 6.357 0 0 0 3.076 2.231h0.019v-16.328z" opacity=".066"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="784">
+    <defs>
+      <mask id="aU">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M6.661 55.768l8.7 9.117 40.855 -40.854 -8.675 -9.117 -40.88 40.854" filter="null"/>
+      </mask>
+      <mask id="aT">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aT)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aU)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.127 13.795l-5.905 1.01c0.021 2.226 0.071 3.91 0.147 4.724a13.615 13.615 0 0 0 2.669 8.339 6.347 6.347 0 0 0 3.07 2.227h0.019v-16.3z" opacity=".059"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="800">
+    <defs>
+      <mask id="aW">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M3.244 51.471l12.144 13.01 40.855 -40.854 -12.091 -13.01 -40.908 40.854" filter="null"/>
+      </mask>
+      <mask id="aV">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aV)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aW)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.05 13.808l-5.895 1.009c0.02 2.221 0.07 3.903 0.146 4.716a13.593 13.593 0 0 0 2.665 8.326 6.337 6.337 0 0 0 3.065 2.223h0.02v-16.274z" opacity=".051"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="816">
+    <defs>
+      <mask id="aY">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-0.905 46.257l16.326 17.734 40.854 -40.854 -16.238 -17.734 -40.942 40.854" filter="null"/>
+      </mask>
+      <mask id="aX">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aX)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#aY)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.978 13.82l-5.887 1.008c0.021 2.218 0.07 3.897 0.146 4.709a13.573 13.573 0 0 0 2.66 8.313 6.327 6.327 0 0 0 3.062 2.22h0.019v-16.25z" opacity=".044"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="832">
+    <defs>
+      <mask id="ba">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-5.418 40.583l20.874 22.875 40.855 -40.855 -20.75 -22.874 -40.979 40.854" filter="null"/>
+      </mask>
+      <mask id="aZ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#aZ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#ba)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.91 13.831l-5.878 1.007c0.021 2.215 0.07 3.891 0.146 4.702a13.554 13.554 0 0 0 2.657 8.301 6.318 6.318 0 0 0 3.057 2.218h0.018v-16.228z" opacity=".037"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="848">
+    <defs>
+      <mask id="bc">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-9.931 34.91l25.423 28.015 40.855 -40.855 -25.262 -28.015 -41.016 40.854" filter="null"/>
+      </mask>
+      <mask id="bb">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#bb)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#bc)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.849 13.842l-5.871 1.005c0.02 2.212 0.07 3.886 0.145 4.696a13.537 13.537 0 0 0 2.654 8.291 6.31 6.31 0 0 0 3.053 2.214h0.019v-16.206z" opacity=".029"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="864">
+    <defs>
+      <mask id="be">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-14.08 29.695l29.605 32.74 40.854 -40.855 -29.409 -32.74 -41.05 40.855" filter="null"/>
+      </mask>
+      <mask id="bd">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#bd)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#be)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.794 13.85l-5.865 1.005c0.022 2.21 0.07 3.882 0.146 4.691a13.521 13.521 0 0 0 2.65 8.281 6.303 6.303 0 0 0 3.05 2.212h0.019v-16.188z" opacity=".022"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="880">
+    <defs>
+      <mask id="bg">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-17.497 25.398l33.049 36.633 40.854 -40.855 -32.825 -36.632 -41.078 40.854" filter="null"/>
+      </mask>
+      <mask id="bf">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#bf)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#bg)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.747 13.859l-5.859 1.003c0.021 2.207 0.07 3.878 0.145 4.686a13.508 13.508 0 0 0 2.649 8.274 6.297 6.297 0 0 0 3.046 2.21h0.019v-16.173z" opacity=".015"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="896">
+    <defs>
+      <mask id="bi">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M-19.818 22.481l35.388 39.276 40.854 -40.855 -35.145 -39.275 -41.097 40.854" filter="null"/>
+      </mask>
+      <mask id="bh">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-5" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#bh)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#ED00B5" href="#shape-0"/>
+    </g>
+    <g fill="#BF68FF" mask="url(#bi)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.71 13.865l-5.855 1.002c0.022 2.206 0.07 3.875 0.146 4.683a13.498 13.498 0 0 0 2.646 8.267 6.292 6.292 0 0 0 3.044 2.208h0.019v-16.16z" opacity=".007"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="912">
+    <defs>
+      <mask id="bj">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#bj)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use fill="#BF68FF" href="#shape-0"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="928">
+    <defs>
+      <mask id="bk">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bk)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M5.675 13.87l-5.85 1.002c0.021 2.204 0.07 3.873 0.145 4.68a13.488 13.488 0 0 0 2.644 8.26 6.288 6.288 0 0 0 3.042 2.208h0.019v-16.15z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="944">
+    <defs>
+      <mask id="bl">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bl)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.013 13.743l-5.942 1.018c0.02 2.239 0.07 3.933 0.147 4.753a13.7 13.7 0 0 0 2.686 8.391 6.387 6.387 0 0 0 3.09 2.242h0.019v-16.404z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="960">
+    <defs>
+      <mask id="bm">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bm)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M6.896 13.51l-6.111 1.045c0.022 2.303 0.073 4.046 0.151 4.89a14.092 14.092 0 0 0 2.763 8.63 6.57 6.57 0 0 0 3.178 2.306h0.02v-16.872z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="976">
+    <defs>
+      <mask id="bn">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bn)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M8.187 13.24l-6.307 1.08c0.023 2.376 0.076 4.175 0.156 5.045a14.542 14.542 0 0 0 2.851 8.906 6.779 6.779 0 0 0 3.28 2.38h0.02v-17.411z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="992">
+    <defs>
+      <mask id="bo">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bo)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M9.763 12.96l-6.51 1.114c0.023 2.453 0.078 4.31 0.161 5.208a15.01 15.01 0 0 0 2.943 9.193 6.997 6.997 0 0 0 3.385 2.456h0.02v-17.972z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1008">
+    <defs>
+      <mask id="bp">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bp)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M11.506 12.68l-6.711 1.15c0.024 2.529 0.08 4.443 0.166 5.37a15.475 15.475 0 0 0 3.034 9.477 7.214 7.214 0 0 0 3.49 2.532h0.021v-18.528z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1024">
+    <defs>
+      <mask id="bq">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bq)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M13.302 12.414l-6.905 1.182c0.025 2.602 0.083 4.571 0.171 5.524a15.921 15.921 0 0 0 3.121 9.751 7.422 7.422 0 0 0 3.591 2.605h0.022v-19.062z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1040">
+    <defs>
+      <mask id="br">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#br)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M15.035 12.167l-7.085 1.212c0.026 2.67 0.085 4.69 0.176 5.668a16.334 16.334 0 0 0 3.202 10.004 7.615 7.615 0 0 0 3.684 2.672h0.023v-19.556z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1056">
+    <defs>
+      <mask id="bs">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bs)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M16.588 11.948l-7.243 1.24c0.026 2.729 0.087 4.795 0.18 5.794a16.7 16.7 0 0 0 3.274 10.228 7.785 7.785 0 0 0 3.766 2.732h0.023v-19.994z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1072">
+    <defs>
+      <mask id="bt">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bt)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M17.846 11.768l-7.373 1.262c0.026 2.779 0.088 4.881 0.183 5.899a17 17 0 0 0 3.332 10.412 7.925 7.925 0 0 0 3.835 2.781h0.023v-20.354z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1088">
+    <defs>
+      <mask id="bu">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bu)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.69 11.642l-7.464 1.278c0.027 2.813 0.09 4.942 0.185 5.972a17.21 17.21 0 0 0 3.374 10.54 8.023 8.023 0 0 0 3.882 2.816h0.024v-20.606z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1104">
+    <defs>
+      <mask id="bv">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bv)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M19 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1120">
+    <defs>
+      <mask id="bw">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bw)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.909 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1136">
+    <defs>
+      <mask id="bx">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bx)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.753 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1152">
+    <defs>
+      <mask id="by">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#by)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.584 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1168">
+    <defs>
+      <mask id="bz">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bz)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.418 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1184">
+    <defs>
+      <mask id="bA">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bA)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.265 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1200">
+    <defs>
+      <mask id="bB">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bB)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.134 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1216">
+    <defs>
+      <mask id="bC">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bC)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <path d="M18.039 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1232">
+    <defs>
+      <mask id="bD">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bD)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1248">
+    <defs>
+      <mask id="bE">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bE)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1264">
+    <defs>
+      <mask id="bF">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bF)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1280">
+    <defs>
+      <mask id="bG">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bG)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1296">
+    <defs>
+      <mask id="bH">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bH)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1312">
+    <defs>
+      <mask id="bI">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bI)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1328">
+    <defs>
+      <mask id="bJ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bJ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1344">
+    <defs>
+      <mask id="bK">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bK)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1360">
+    <defs>
+      <mask id="bL">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bL)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1376">
+    <defs>
+      <mask id="bM">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bM)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1392">
+    <defs>
+      <mask id="bN">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bN)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1408">
+    <defs>
+      <mask id="bO">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bO)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1424">
+    <defs>
+      <mask id="bP">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bP)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1440">
+    <defs>
+      <mask id="bQ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bQ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1456">
+    <defs>
+      <mask id="bR">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bR)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1472">
+    <defs>
+      <mask id="bS">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bS)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1488">
+    <defs>
+      <mask id="bT">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bT)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1504">
+    <defs>
+      <mask id="bU">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bU)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1520">
+    <defs>
+      <mask id="bV">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bV)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1536">
+    <defs>
+      <mask id="bW">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bW)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1552">
+    <defs>
+      <mask id="bX">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bX)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1568">
+    <defs>
+      <mask id="bY">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bY)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1584">
+    <defs>
+      <mask id="bZ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#bZ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1600">
+    <defs>
+      <mask id="ca">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ca)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1616">
+    <defs>
+      <mask id="cb">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cb)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1632">
+    <defs>
+      <mask id="cc">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cc)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1648">
+    <defs>
+      <mask id="cd">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cd)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1664">
+    <defs>
+      <mask id="ce">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ce)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1680">
+    <defs>
+      <mask id="cf">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cf)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1696">
+    <defs>
+      <mask id="cg">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cg)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1712">
+    <defs>
+      <mask id="ch">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ch)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1728">
+    <defs>
+      <mask id="ci">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ci)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1744">
+    <defs>
+      <mask id="cj">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cj)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1760">
+    <defs>
+      <mask id="ck">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ck)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1776">
+    <defs>
+      <mask id="cl">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cl)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1792">
+    <defs>
+      <mask id="cm">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cm)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1808">
+    <defs>
+      <mask id="cn">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cn)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1824">
+    <defs>
+      <mask id="co">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#co)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1840">
+    <defs>
+      <mask id="cp">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cp)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1856">
+    <defs>
+      <mask id="cq">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cq)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1872">
+    <defs>
+      <mask id="cr">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cr)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1888">
+    <defs>
+      <mask id="cs">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cs)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1904">
+    <defs>
+      <mask id="ct">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#ct)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1920">
+    <defs>
+      <mask id="cu">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cu)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1936">
+    <defs>
+      <mask id="cv">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cv)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1952">
+    <defs>
+      <mask id="cw">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cw)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1968">
+    <defs>
+      <mask id="cx">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cx)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="1984">
+    <defs>
+      <mask id="cy">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cy)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2000">
+    <defs>
+      <mask id="cz">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cz)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2016">
+    <defs>
+      <mask id="cA">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cA)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2032">
+    <defs>
+      <mask id="cB">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cB)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2048">
+    <defs>
+      <mask id="cC">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cC)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2064">
+    <defs>
+      <mask id="cD">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cD)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2080">
+    <defs>
+      <mask id="cE">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cE)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2096">
+    <defs>
+      <mask id="cF">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cF)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2112">
+    <defs>
+      <mask id="cG">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cG)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2128">
+    <defs>
+      <mask id="cH">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cH)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2144">
+    <defs>
+      <mask id="cI">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cI)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2160">
+    <defs>
+      <mask id="cJ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cJ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2176">
+    <defs>
+      <mask id="cK">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cK)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2192">
+    <defs>
+      <mask id="cL">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cL)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2208">
+    <defs>
+      <mask id="cM">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cM)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2224">
+    <defs>
+      <mask id="cN">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cN)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2240">
+    <defs>
+      <mask id="cO">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cO)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2256">
+    <defs>
+      <mask id="cP">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cP)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2272">
+    <defs>
+      <mask id="cQ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cQ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2288">
+    <defs>
+      <mask id="cR">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cR)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2304">
+    <defs>
+      <mask id="cS">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cS)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2320">
+    <defs>
+      <mask id="cT">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cT)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2336">
+    <defs>
+      <mask id="cU">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cU)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2352">
+    <defs>
+      <mask id="cV">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cV)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2368">
+    <defs>
+      <mask id="cW">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4"/>
+    <g fill="#BF68FF" mask="url(#cW)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2384">
+    <defs>
+      <mask id="cX">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".952"/>
+    <g fill="#BF68FF" mask="url(#cX)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2400">
+    <defs>
+      <mask id="cY">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".905"/>
+    <g fill="#BF68FF" mask="url(#cY)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2416">
+    <defs>
+      <mask id="cZ">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".857"/>
+    <g fill="#BF68FF" mask="url(#cZ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2432">
+    <defs>
+      <mask id="da">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".81"/>
+    <g fill="#BF68FF" mask="url(#da)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2448">
+    <defs>
+      <mask id="db">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".762"/>
+    <g fill="#BF68FF" mask="url(#db)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2464">
+    <defs>
+      <mask id="dc">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".714"/>
+    <g fill="#BF68FF" mask="url(#dc)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2480">
+    <defs>
+      <mask id="dd">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".667"/>
+    <g fill="#BF68FF" mask="url(#dd)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2496">
+    <defs>
+      <mask id="de">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".619"/>
+    <g fill="#BF68FF" mask="url(#de)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2512">
+    <defs>
+      <mask id="df">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".571"/>
+    <g fill="#C26FFE" mask="url(#df)" opacity=".98" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2528">
+    <defs>
+      <mask id="dg">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".524"/>
+    <g fill="#C577FE" mask="url(#dg)" opacity=".96" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2544">
+    <defs>
+      <mask id="dh">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".476"/>
+    <g fill="#C87EFE" mask="url(#dh)" opacity=".94" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2560">
+    <defs>
+      <mask id="di">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".429"/>
+    <g fill="#CA85FD" mask="url(#di)" opacity=".92" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2576">
+    <defs>
+      <mask id="dj">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".381"/>
+    <g fill="#CD8CFD" mask="url(#dj)" opacity=".9" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2592">
+    <defs>
+      <mask id="dk">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".333"/>
+    <g fill="#D094FD" mask="url(#dk)" opacity=".88" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2608">
+    <defs>
+      <mask id="dl">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".286"/>
+    <g fill="#D39BFD" mask="url(#dl)" opacity=".86" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2624">
+    <defs>
+      <mask id="dm">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".238"/>
+    <g fill="#D6A2FC" mask="url(#dm)" opacity=".84" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2640">
+    <defs>
+      <mask id="dn">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".19"/>
+    <g fill="#D9A9FC" mask="url(#dn)" opacity=".82" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2656">
+    <defs>
+      <mask id="do">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".143"/>
+    <g fill="#DCB1FC" mask="url(#do)" opacity=".8" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2672">
+    <defs>
+      <mask id="dp">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".095"/>
+    <g fill="#DFB8FC" mask="url(#dp)" opacity=".78" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2688">
+    <defs>
+      <mask id="dq">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <use fill="#F9F9F9" fill-opacity=".2" href="#shape-4" opacity=".048"/>
+    <g fill="#E2BFFB" mask="url(#dq)" opacity=".76" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2704">
+    <defs>
+      <mask id="dr">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#E5C7FB" mask="url(#dr)" opacity=".74" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2720">
+    <defs>
+      <mask id="ds">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#E8CEFB" mask="url(#ds)" opacity=".72" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2736">
+    <defs>
+      <mask id="dt">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#EBD5FB" mask="url(#dt)" opacity=".7" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2752">
+    <defs>
+      <mask id="du">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#EEDCFA" mask="url(#du)" opacity=".68" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2768">
+    <defs>
+      <mask id="dv">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#F1E4FA" mask="url(#dv)" opacity=".66" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2784">
+    <defs>
+      <mask id="dw">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#F4EBFA" mask="url(#dw)" opacity=".64" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2800">
+    <defs>
+      <mask id="dx">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="#F6F2FA" mask="url(#dx)" opacity=".62" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+  <svg width="16" height="20" x="2816">
+    <defs>
+      <mask id="dy">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-6" filter="null"/>
+      </mask>
+    </defs>
+    <g fill="context-fill" fill-opacity="context-fill-opacity" transform="matrix(.36 0 0 .36 1.52 1.955)">
+      <use href="#shape-0"/>
+      <use href="#shape-1"/>
+    </g>
+  </svg>
+</svg>
--- a/browser/themes/shared/identity-block/tracking-protection-animation.svg
+++ b/browser/themes/shared/identity-block/tracking-protection-animation.svg
@@ -1,1674 +1,2464 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="1248" height="20">
+<svg xmlns="http://www.w3.org/2000/svg" width="2832" height="20">
   <defs>
     <path id="shape-0" d="M18 42.999l-0.336 -0.035a18.737 18.737 0 0 1 -12.036 -7.281 27.778 27.778 0 0 1 -5.4 -15.859c-0.228 -2.517 -0.228 -8.042 -0.228 -11.117a5.535 5.535 0 0 1 4.581 -5.467l13.419 -2.303 13.413 2.303a5.536 5.536 0 0 1 4.587 5.47c0 3.069 0 8.597 -0.24 11.114a27.778 27.778 0 0 1 -5.4 15.859 18.737 18.737 0 0 1 -12.036 7.281l-0.324 0.035zm-12 -33.917c0 4.875 -0.147 8.28 0 9.9a22.722 22.722 0 0 0 4.461 13.146 12.67 12.67 0 0 0 7.539 4.815 12.664 12.664 0 0 0 7.536 -4.815 22.725 22.725 0 0 0 4.464 -13.146c0.147 -1.62 0 -5.025 0 -9.9l-12 -2.055 -12 2.055z"/>
+    <path id="shape-1" d="M18 11.593l-7.5 1.284c0.027 2.826 0.09 4.965 0.186 6a17.293 17.293 0 0 0 3.39 10.591 8.061 8.061 0 0 0 3.9 2.829h0.024v-20.704z"/>
+    <path id="shape-2" d="M8 13.565l-0.06 -0.006a3.373 3.373 0 0 1 -2.167 -1.311 5 5 0 0 1 -0.972 -2.855c-0.041 -0.453 -0.041 -1.447 -0.041 -2a0.996 0.996 0 0 1 0.825 -0.985l2.415 -0.414 2.414 0.414a0.997 0.997 0 0 1 0.826 0.985c0 0.552 0 1.547 -0.043 2a5 5 0 0 1 -0.972 2.855 3.373 3.373 0 0 1 -2.167 1.31l-0.058 0.007zm-2.16 -6.105c0 0.877 -0.026 1.49 0 1.782a4.09 4.09 0 0 0 0.803 2.366 2.28 2.28 0 0 0 1.357 0.867 2.28 2.28 0 0 0 1.356 -0.867 4.09 4.09 0 0 0 0.804 -2.366c0.026 -0.292 0 -0.905 0 -1.782l-2.16 -0.37 -2.16 0.37z"/>
+    <path id="shape-3" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854"/>
+    <path id="shape-4" d="M8 17.435l-0.121 -0.013a6.745 6.745 0 0 1 -4.333 -2.621 10 10 0 0 1 -1.944 -5.71c-0.082 -0.905 -0.082 -2.894 -0.082 -4.001a1.993 1.993 0 0 1 1.65 -1.969l4.83 -0.829 4.829 0.83a1.993 1.993 0 0 1 1.651 1.969c0 1.104 0 3.095 -0.086 4a10 10 0 0 1 -1.944 5.71 6.745 6.745 0 0 1 -4.333 2.621l-0.117 0.013zm-4.32 -12.21c0 1.755 -0.053 2.98 0 3.564a8.18 8.18 0 0 0 1.606 4.732 4.562 4.562 0 0 0 2.714 1.733 4.559 4.559 0 0 0 2.713 -1.733 8.181 8.181 0 0 0 1.607 -4.732c0.053 -0.584 0 -1.81 0 -3.564l-4.32 -0.74 -4.32 0.74z"/>
+    <path id="shape-5" d="M-20.673 24.01l36.25 40.25 40.854 -40.854 -36 -40.25 -41.104 40.854"/>
+    <path id="shape-6" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
   </defs>
   <svg width="16" height="20">
     <defs>
       <mask id="a">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.332 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
     </defs>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#a)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <g fill="#7F00D6" mask="url(#a)" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use href="#shape-0"/>
       <path d="M11.681 12.84l-6.596 1.13c0.024 2.485 0.079 4.366 0.163 5.277a15.21 15.21 0 0 0 2.982 9.315 7.09 7.09 0 0 0 3.43 2.488h0.021v-18.21z" opacity=".419"/>
     </g>
   </svg>
   <svg width="16" height="20" x="16">
     <defs>
-      <mask id="d">
+      <mask id="c">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.321 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="c">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="b">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="b">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#b)" opacity=".006" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#c)" opacity=".045" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".006"/>
+    <g mask="url(#b)" opacity=".045" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#d)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <g fill="#7F00D6" mask="url(#c)" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use href="#shape-0"/>
       <path d="M11.556 12.862l-6.58 1.126c0.023 2.48 0.079 4.357 0.163 5.265a15.173 15.173 0 0 0 2.974 9.293 7.073 7.073 0 0 0 3.422 2.482h0.021v-18.166z" opacity=".412"/>
     </g>
   </svg>
   <svg width="16" height="20" x="32">
     <defs>
-      <mask id="g">
+      <mask id="e">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.296 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="f">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="d">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="e">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#e)" opacity=".023" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#f)" opacity=".098" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".023"/>
+    <g mask="url(#d)" opacity=".098" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#g)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <g fill="#7F00D6" mask="url(#e)" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use href="#shape-0"/>
       <path d="M11.432 12.883l-6.565 1.124c0.023 2.474 0.078 4.346 0.162 5.252a15.137 15.137 0 0 0 2.968 9.271 7.056 7.056 0 0 0 3.414 2.477h0.02v-18.124z" opacity=".404"/>
     </g>
   </svg>
   <svg width="16" height="20" x="48">
     <defs>
-      <mask id="j">
+      <mask id="g">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.263 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="i">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="f">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="h">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#h)" opacity=".051" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#i)" opacity=".159" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".051"/>
+    <g mask="url(#f)" opacity=".159" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#j)" transform="matrix(.18 0 0 .18 4.76 5.825)">
+    <g fill="#7F00D6" mask="url(#g)" transform="matrix(.18 0 0 .18 4.76 5.825)">
       <use href="#shape-0"/>
-      <path d="M11.307 12.905l-6.55 1.121c0.024 2.468 0.08 4.336 0.163 5.24a15.1 15.1 0 0 0 2.96 9.248 7.04 7.04 0 0 0 3.406 2.47h0.02v-18.078z" opacity=".397"/>
+      <path d="M11.307 12.905l-6.55 1.121c0.024 2.468 0.08 4.336 0.163 5.24a15.1 15.1 0 0 0 2.96 9.248 7.04 7.04 0 0 0 3.406 2.47h0.02v-18.079z" opacity=".397"/>
     </g>
   </svg>
   <svg width="16" height="20" x="64">
     <defs>
-      <mask id="m">
+      <mask id="i">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.223 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="l">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="h">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="k">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#k)" opacity=".087" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#l)" opacity=".224" transform="translate(4.64 5.68) scale(.18672)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".087"/>
+    <g mask="url(#h)" opacity=".224" transform="translate(4.64 5.68) scale(.18672)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#m)" transform="translate(4.654 5.699) scale(.18588)">
+    <g fill="#7F00D6" mask="url(#i)" transform="translate(4.654 5.699) scale(.18588)">
       <use href="#shape-0"/>
-      <path d="M11.182 12.927l-6.534 1.118c0.024 2.462 0.079 4.326 0.163 5.227a15.063 15.063 0 0 0 2.953 9.227 7.023 7.023 0 0 0 3.397 2.464h0.021v-18.036z" opacity=".39"/>
+      <path d="M11.182 12.927l-6.534 1.118c0.024 2.462 0.079 4.326 0.163 5.227a15.065 15.065 0 0 0 2.953 9.227 7.023 7.023 0 0 0 3.397 2.464h0.021v-18.036z" opacity=".39"/>
     </g>
   </svg>
   <svg width="16" height="20" x="80">
     <defs>
-      <mask id="p">
+      <mask id="k">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.178 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="o">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="j">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="n">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#n)" opacity=".132" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#o)" opacity=".294" transform="translate(4.308 5.285) scale(.20512)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".132"/>
+    <g mask="url(#j)" opacity=".294" transform="translate(4.308 5.285) scale(.20512)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#p)" transform="translate(4.364 5.352) scale(.20198)">
+    <g fill="#7F00D6" mask="url(#k)" transform="translate(4.364 5.352) scale(.20198)">
       <use href="#shape-0"/>
       <path d="M11.058 12.948l-6.518 1.116c0.023 2.456 0.078 4.315 0.161 5.215a15.029 15.029 0 0 0 2.946 9.204 7.006 7.006 0 0 0 3.39 2.459h0.02v-17.994z" opacity=".382"/>
     </g>
   </svg>
   <svg width="16" height="20" x="96">
     <defs>
-      <mask id="s">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.13 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.855 40.854" filter="null"/>
-      </mask>
-      <mask id="r">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="m">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.13 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="q">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="l">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#q)" opacity=".183" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#r)" opacity=".367" transform="translate(3.813 4.694) scale(.23261)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".183"/>
+    <g mask="url(#l)" opacity=".367" transform="translate(3.813 4.694) scale(.23261)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#s)" transform="translate(3.931 4.835) scale(.22603)">
+    <g fill="#7F00D6" mask="url(#m)" transform="translate(3.931 4.835) scale(.22603)">
       <use href="#shape-0"/>
-      <path d="M10.933 12.97l-6.502 1.113c0.023 2.45 0.078 4.305 0.161 5.202a14.984 14.984 0 0 0 2.94 9.182 6.99 6.99 0 0 0 3.38 2.453h0.021v-17.95z" opacity=".375"/>
+      <path d="M10.933 12.97l-6.502 1.113c0.023 2.45 0.078 4.305 0.161 5.202a14.993 14.993 0 0 0 2.94 9.182 6.99 6.99 0 0 0 3.38 2.453h0.021v-17.95z" opacity=".375"/>
     </g>
   </svg>
   <svg width="16" height="20" x="112">
     <defs>
-      <mask id="v">
+      <mask id="o">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.08 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="u">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="n">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="t">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#t)" opacity=".239" transform="matrix(.18 0 0 .18 4.76 5.825)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#u)" opacity=".442" transform="translate(3.202 3.964) scale(.26658)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-2" opacity=".239"/>
+    <g mask="url(#n)" opacity=".442" transform="translate(3.202 3.964) scale(.26658)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#v)" transform="translate(3.396 4.196) scale(.25575)">
+    <g fill="#7F00D6" mask="url(#o)" transform="translate(3.396 4.196) scale(.25575)">
       <use href="#shape-0"/>
-      <path d="M10.809 12.991l-6.487 1.11c0.023 2.445 0.078 4.295 0.16 5.19a14.957 14.957 0 0 0 2.933 9.16 6.972 6.972 0 0 0 3.373 2.448h0.021v-17.909z" opacity=".368"/>
+      <path d="M10.809 12.991l-6.487 1.11c0.023 2.445 0.078 4.295 0.16 5.19a14.957 14.957 0 0 0 2.933 9.16 6.972 6.972 0 0 0 3.373 2.448h0.021v-17.908z" opacity=".368"/>
     </g>
   </svg>
   <svg width="16" height="20" x="128">
     <defs>
-      <mask id="y">
+      <mask id="q">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M12.027 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="x">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="p">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="w">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#w)" opacity=".301" transform="translate(4.627 5.667) scale(.18737)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#x)" opacity=".517" transform="translate(2.52 3.15) scale(.30443)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 13.723l-0.063 -0.006a3.51 3.51 0 0 1 -2.255 -1.365 5.205 5.205 0 0 1 -1.012 -2.971c-0.043 -0.472 -0.043 -1.507 -0.043 -2.083a1.037 1.037 0 0 1 0.859 -1.024l2.514 -0.432 2.513 0.432a1.037 1.037 0 0 1 0.86 1.025c0 0.575 0 1.61 -0.045 2.082a5.205 5.205 0 0 1 -1.012 2.971 3.51 3.51 0 0 1 -2.255 1.365l-0.061 0.006zm-2.248 -6.355c0 0.914 -0.028 1.552 0 1.855a4.257 4.257 0 0 0 0.835 2.463 2.374 2.374 0 0 0 1.413 0.903 2.373 2.373 0 0 0 1.412 -0.903 4.258 4.258 0 0 0 0.836 -2.463c0.028 -0.303 0 -0.941 0 -1.855l-2.248 -0.385 -2.248 0.385z" opacity=".301"/>
+    <g mask="url(#p)" opacity=".517" transform="translate(2.52 3.15) scale(.30443)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#y)" transform="translate(2.8 3.484) scale(.28887)">
+    <g fill="#7F00D6" mask="url(#q)" transform="translate(2.8 3.484) scale(.28887)">
       <use href="#shape-0"/>
-      <path d="M10.685 13.013l-6.472 1.107c0.024 2.438 0.078 4.284 0.16 5.177a14.921 14.921 0 0 0 2.927 9.139 6.956 6.956 0 0 0 3.365 2.441h0.02v-17.864z" opacity=".36"/>
+      <path d="M10.685 13.013l-6.472 1.108c0.024 2.438 0.078 4.284 0.16 5.177a14.921 14.921 0 0 0 2.926 9.138 6.956 6.956 0 0 0 3.365 2.441h0.02v-17.864z" opacity=".36"/>
     </g>
   </svg>
   <svg width="16" height="20" x="144">
     <defs>
-      <mask id="B">
+      <mask id="s">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.973 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="A">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="r">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="z">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#z)" opacity=".365" transform="translate(4.268 5.237) scale(.20736)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#A)" opacity=".591" transform="translate(1.816 2.308) scale(.34357)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 14.153l-0.07 -0.007a3.885 3.885 0 0 1 -2.495 -1.51 5.76 5.76 0 0 1 -1.12 -3.289c-0.047 -0.521 -0.047 -1.667 -0.047 -2.305a1.148 1.148 0 0 1 0.95 -1.133l2.782 -0.478 2.781 0.478a1.148 1.148 0 0 1 0.951 1.134c0 0.636 0 1.783 -0.05 2.304a5.76 5.76 0 0 1 -1.12 3.289 3.885 3.885 0 0 1 -2.495 1.51l-0.067 0.007zm-2.488 -7.033c0 1.01 -0.03 1.717 0 2.053a4.712 4.712 0 0 0 0.925 2.726 2.627 2.627 0 0 0 1.563 0.998 2.626 2.626 0 0 0 1.563 -0.998 4.712 4.712 0 0 0 0.925 -2.726c0.03 -0.336 0 -1.042 0 -2.053l-2.488 -0.426 -2.488 0.426z" opacity=".365"/>
+    <g mask="url(#r)" opacity=".591" transform="translate(1.816 2.308) scale(.34357)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#B)" transform="translate(2.184 2.748) scale(.32313)">
+    <g fill="#7F00D6" mask="url(#s)" transform="translate(2.184 2.748) scale(.32313)">
       <use href="#shape-0"/>
-      <path d="M10.56 13.034l-6.454 1.106c0.023 2.433 0.077 4.274 0.16 5.165a14.885 14.885 0 0 0 2.918 9.117 6.939 6.939 0 0 0 3.357 2.435h0.02v-17.823z" opacity=".353"/>
+      <path d="M10.56 13.034l-6.455 1.105c0.023 2.433 0.077 4.274 0.16 5.165a14.885 14.885 0 0 0 2.918 9.117 6.939 6.939 0 0 0 3.357 2.435h0.02v-17.822z" opacity=".353"/>
     </g>
   </svg>
   <svg width="16" height="20" x="160">
     <defs>
-      <mask id="E">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.917 59.76l5.5 5.5 40.853 -40.854 -5.5 -5.5 -40.853 40.854" filter="null"/>
-      </mask>
-      <mask id="D">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="u">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.917 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="C">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="t">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#C)" opacity=".432" transform="translate(3.738 4.604) scale(.2368)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#D)" opacity=".663" transform="translate(1.134 1.494) scale(.38142)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 14.786l-0.08 -0.008a4.437 4.437 0 0 1 -2.85 -1.725 6.578 6.578 0 0 1 -1.278 -3.755c-0.054 -0.596 -0.054 -1.904 -0.054 -2.632a1.31 1.31 0 0 1 1.084 -1.295l3.178 -0.545 3.176 0.545a1.31 1.31 0 0 1 1.086 1.295c0 0.727 0 2.036 -0.057 2.632a6.578 6.578 0 0 1 -1.278 3.755 4.437 4.437 0 0 1 -2.85 1.725l-0.077 0.008zm-2.842 -8.031c0 1.154 -0.034 1.96 0 2.344a5.38 5.38 0 0 0 1.057 3.113 3 3 0 0 0 1.785 1.14 2.999 2.999 0 0 0 1.784 -1.14 5.381 5.381 0 0 0 1.058 -3.113c0.034 -0.384 0 -1.19 0 -2.344l-2.842 -0.487 -2.842 0.487z" opacity=".432"/>
+    <g mask="url(#t)" opacity=".663" transform="translate(1.134 1.494) scale(.38142)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#E)" transform="translate(1.588 2.036) scale(.35625)">
+    <g fill="#7F00D6" mask="url(#u)" transform="translate(1.588 2.036) scale(.35625)">
       <use href="#shape-0"/>
       <path d="M10.437 13.056l-6.44 1.102c0.023 2.427 0.077 4.264 0.16 5.152a14.85 14.85 0 0 0 2.91 9.095 6.922 6.922 0 0 0 3.35 2.43h0.02v-17.78z" opacity=".346"/>
     </g>
   </svg>
   <svg width="16" height="20" x="176">
     <defs>
-      <mask id="H">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.86 59.76l5.5 5.5 40.853 -40.854 -5.5 -5.5 -40.853 40.854" filter="null"/>
-      </mask>
-      <mask id="G">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="w">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.86 59.76l5.5 5.5 40.853 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="F">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="v">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#F)" opacity=".5" transform="translate(3.095 3.836) scale(.27252)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#G)" opacity=".731" transform="translate(.523 .764) scale(.41539)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 15.554l-0.092 -0.01a5.106 5.106 0 0 1 -3.28 -1.984 7.57 7.57 0 0 1 -1.471 -4.322c-0.062 -0.686 -0.062 -2.191 -0.062 -3.03a1.509 1.509 0 0 1 1.248 -1.49l3.657 -0.627 3.655 0.628a1.509 1.509 0 0 1 1.25 1.49c0 0.837 0 2.343 -0.065 3.03a7.57 7.57 0 0 1 -1.472 4.321 5.106 5.106 0 0 1 -3.28 1.984l-0.088 0.01zm-3.27 -9.243c0 1.328 -0.04 2.256 0 2.698a6.192 6.192 0 0 0 1.215 3.582 3.453 3.453 0 0 0 2.055 1.313 3.451 3.451 0 0 0 2.054 -1.313 6.193 6.193 0 0 0 1.216 -3.582c0.04 -0.442 0 -1.37 0 -2.698l-3.27 -0.56 -3.27 0.56z" opacity=".5"/>
+    <g mask="url(#v)" opacity=".731" transform="translate(.523 .764) scale(.41539)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#H)" transform="translate(1.053 1.397) scale(.38597)">
+    <g fill="#7F00D6" mask="url(#w)" transform="translate(1.053 1.397) scale(.38597)">
       <use href="#shape-0"/>
       <path d="M10.314 13.077l-6.425 1.1c0.023 2.42 0.077 4.253 0.159 5.14a14.814 14.814 0 0 0 2.904 9.073 6.906 6.906 0 0 0 3.341 2.423h0.02v-17.736z" opacity=".338"/>
     </g>
   </svg>
   <svg width="16" height="20" x="192">
     <defs>
-      <mask id="K">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.8 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.855 40.854" filter="null"/>
-      </mask>
-      <mask id="J">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="y">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.8 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="I">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="x">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#I)" opacity=".568" transform="translate(2.395 3) scale(.3114)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#J)" opacity=".795" transform="translate(.028 .173) scale(.44288)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 16.39l-0.105 -0.011a5.835 5.835 0 0 1 -3.748 -2.267 8.65 8.65 0 0 1 -1.681 -4.939c-0.071 -0.784 -0.071 -2.504 -0.071 -3.462a1.724 1.724 0 0 1 1.426 -1.702l4.179 -0.717 4.177 0.717a1.724 1.724 0 0 1 1.428 1.703c0 0.956 0 2.677 -0.075 3.461a8.65 8.65 0 0 1 -1.681 4.939 5.835 5.835 0 0 1 -3.748 2.267l-0.101 0.01zm-3.737 -10.562c0 1.518 -0.046 2.578 0 3.083a7.076 7.076 0 0 0 1.39 4.094 3.946 3.946 0 0 0 2.347 1.499 3.944 3.944 0 0 0 2.347 -1.5 7.077 7.077 0 0 0 1.39 -4.093c0.046 -0.505 0 -1.565 0 -3.083l-3.737 -0.64 -3.737 0.64z" opacity=".568"/>
+    <g mask="url(#x)" opacity=".795" transform="translate(.028 .173) scale(.44288)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#K)" transform="translate(.62 .88) scale(.41002)">
+    <g fill="#7F00D6" mask="url(#y)" transform="translate(.62 .88) scale(.41002)">
       <use href="#shape-0"/>
       <path d="M10.19 13.098l-6.41 1.098c0.024 2.415 0.078 4.243 0.16 5.127a14.778 14.778 0 0 0 2.897 9.051 6.89 6.89 0 0 0 3.333 2.418h0.02v-17.694z" opacity=".331"/>
     </g>
   </svg>
   <svg width="16" height="20" x="208">
     <defs>
-      <mask id="N">
+      <mask id="A">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.741 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="M">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="z">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="L">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#L)" opacity=".635" transform="translate(1.695 2.164) scale(.35028)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#M)" opacity=".852" transform="translate(-.303 -.223) scale(.46128)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.226l-0.118 -0.013a6.563 6.563 0 0 1 -4.216 -2.55 9.73 9.73 0 0 1 -1.891 -5.555c-0.08 -0.882 -0.08 -2.817 -0.08 -3.894a1.939 1.939 0 0 1 1.605 -1.915l4.7 -0.807 4.698 0.807a1.94 1.94 0 0 1 1.607 1.916c0 1.075 0 3.011 -0.084 3.893a9.73 9.73 0 0 1 -1.892 5.555 6.563 6.563 0 0 1 -4.216 2.55l-0.113 0.013zm-4.203 -11.88c0 1.707 -0.052 2.9 0 3.467a7.96 7.96 0 0 0 1.562 4.605 4.438 4.438 0 0 0 2.641 1.686 4.436 4.436 0 0 0 2.64 -1.686 7.96 7.96 0 0 0 1.563 -4.605c0.052 -0.567 0 -1.76 0 -3.468l-4.203 -0.72 -4.203 0.72z" opacity=".635"/>
+    <g mask="url(#z)" opacity=".852" transform="translate(-.303 -.223) scale(.46128)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#N)" transform="translate(.33 .533) scale(.42612)">
+    <g fill="#7F00D6" mask="url(#A)" transform="translate(.33 .533) scale(.42612)">
       <use href="#shape-0"/>
-      <path d="M10.067 13.12l-6.394 1.094c0.023 2.41 0.077 4.233 0.159 5.115a14.747 14.747 0 0 0 2.89 9.03 6.873 6.873 0 0 0 3.325 2.412h0.02v-17.652z" opacity=".324"/>
+      <path d="M10.067 13.12l-6.394 1.094c0.023 2.41 0.077 4.233 0.159 5.115a14.743 14.743 0 0 0 2.89 9.03 6.873 6.873 0 0 0 3.325 2.412h0.02v-17.652z" opacity=".324"/>
     </g>
   </svg>
   <svg width="16" height="20" x="224">
     <defs>
-      <mask id="Q">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.68 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.855 40.854" filter="null"/>
-      </mask>
-      <mask id="P">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="C">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.68 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="O">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="B">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#O)" opacity=".699" transform="matrix(.386 0 0 .386 1.052 1.396)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#P)" opacity=".902" transform="matrix(.468 0 0 .468 -.424 -.367)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.994l-0.13 -0.014a7.232 7.232 0 0 1 -4.646 -2.81 10.723 10.723 0 0 1 -2.084 -6.122c-0.088 -0.972 -0.088 -3.104 -0.088 -4.291a2.137 2.137 0 0 1 1.768 -2.11l5.18 -0.89 5.178 0.89a2.137 2.137 0 0 1 1.77 2.111c0 1.185 0 3.318 -0.093 4.29a10.723 10.723 0 0 1 -2.084 6.122 7.232 7.232 0 0 1 -4.646 2.81l-0.125 0.014zm-4.632 -13.092c0 1.881 -0.057 3.196 0 3.821a8.771 8.771 0 0 0 1.722 5.074 4.891 4.891 0 0 0 2.91 1.86 4.888 4.888 0 0 0 2.909 -1.86 8.772 8.772 0 0 0 1.723 -5.074c0.057 -0.625 0 -1.94 0 -3.821l-4.632 -0.794 -4.632 0.794z" opacity=".699"/>
+    <g mask="url(#B)" opacity=".902" transform="matrix(.468 0 0 .468 -.424 -.367)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#Q)" transform="matrix(.432 0 0 .432 .224 .407)">
+    <g fill="#7F00D6" mask="url(#C)" transform="matrix(.432 0 0 .432 .224 .407)">
       <use href="#shape-0"/>
       <path d="M9.944 13.14l-6.378 1.093c0.023 2.403 0.076 4.222 0.158 5.103a14.707 14.707 0 0 0 2.883 9.007 6.856 6.856 0 0 0 3.317 2.406h0.02v-17.608z" opacity=".316"/>
     </g>
   </svg>
   <svg width="16" height="20" x="240">
     <defs>
-      <mask id="T">
+      <mask id="E">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.62 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="S">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="D">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="R">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#R)" opacity=".761" transform="translate(.522 .763) scale(.41544)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#S)" opacity=".943" transform="translate(-.402 -.34) scale(.46679)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.627l-0.14 -0.015a7.784 7.784 0 0 1 -5 -3.025 11.54 11.54 0 0 1 -2.243 -6.588c-0.095 -1.046 -0.095 -3.341 -0.095 -4.619a2.3 2.3 0 0 1 1.903 -2.271l5.575 -0.957 5.572 0.957a2.3 2.3 0 0 1 1.906 2.272c0 1.275 0 3.572 -0.1 4.618a11.54 11.54 0 0 1 -2.243 6.588 7.784 7.784 0 0 1 -5 3.025l-0.135 0.015zm-4.985 -14.091c0 2.025 -0.061 3.44 0 4.113a9.44 9.44 0 0 0 1.853 5.461 5.264 5.264 0 0 0 3.132 2 5.261 5.261 0 0 0 3.13 -2 9.441 9.441 0 0 0 1.855 -5.461c0.061 -0.673 0 -2.088 0 -4.113l-4.985 -0.854 -4.985 0.854z" opacity=".761"/>
+    <g mask="url(#D)" opacity=".943" transform="translate(-.402 -.34) scale(.46679)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#T)" transform="translate(.24 .427) scale(.43108)">
+    <g fill="#7F00D6" mask="url(#E)" transform="translate(.24 .427) scale(.43108)">
       <use href="#shape-0"/>
-      <path d="M9.822 13.162l-6.364 1.09c0.023 2.397 0.077 4.212 0.158 5.09a14.67 14.67 0 0 0 2.877 8.986 6.84 6.84 0 0 0 3.309 2.4h0.02v-17.566z" opacity=".309"/>
+      <path d="M9.822 13.162l-6.364 1.09c0.023 2.397 0.077 4.212 0.158 5.09a14.672 14.672 0 0 0 2.877 8.986 6.84 6.84 0 0 0 3.309 2.4h0.02v-17.566z" opacity=".309"/>
     </g>
   </svg>
   <svg width="16" height="20" x="256">
     <defs>
-      <mask id="W">
+      <mask id="G">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.558 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="V">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="F">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="U">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#U)" opacity=".817" transform="translate(.162 .333) scale(.43543)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#V)" opacity=".974" transform="translate(-.34 -.267) scale(.46335)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 19.056l-0.146 -0.015a8.158 8.158 0 0 1 -5.241 -3.17 12.095 12.095 0 0 1 -2.351 -6.906c-0.1 -1.096 -0.1 -3.502 -0.1 -4.84a2.41 2.41 0 0 1 1.995 -2.381l5.843 -1.003 5.84 1.003a2.41 2.41 0 0 1 1.998 2.382c0 1.336 0 3.743 -0.105 4.84a12.095 12.095 0 0 1 -2.351 6.905 8.158 8.158 0 0 1 -5.24 3.17l-0.142 0.015zm-5.225 -14.768c0 2.123 -0.064 3.605 0 4.31a9.894 9.894 0 0 0 1.942 5.725 5.517 5.517 0 0 0 3.283 2.096 5.514 5.514 0 0 0 3.281 -2.096 9.895 9.895 0 0 0 1.944 -5.724c0.064 -0.706 0 -2.188 0 -4.311l-5.225 -0.895 -5.225 0.895z" opacity=".817"/>
+    <g mask="url(#F)" opacity=".974" transform="translate(-.34 -.267) scale(.46335)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#W)" transform="translate(.287 .482) scale(.4285)">
+    <g fill="#7F00D6" mask="url(#G)" transform="translate(.287 .482) scale(.4285)">
       <use href="#shape-0"/>
       <path d="M9.7 13.183l-6.348 1.087c0.022 2.392 0.076 4.202 0.157 5.078a14.637 14.637 0 0 0 2.87 8.965 6.823 6.823 0 0 0 3.3 2.394h0.02v-17.524z" opacity=".301"/>
     </g>
   </svg>
   <svg width="16" height="20" x="272">
     <defs>
-      <mask id="Z">
+      <mask id="I">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.496 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="Y">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="H">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="X">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#X)" opacity=".868" transform="translate(.03 .175) scale(.4428)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#Y)" opacity=".993" transform="translate(-.244 -.153) scale(.45802)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 19.215l-0.149 -0.016a8.297 8.297 0 0 1 -5.33 -3.224 12.3 12.3 0 0 1 -2.39 -7.022c-0.101 -1.115 -0.101 -3.561 -0.101 -4.923a2.451 2.451 0 0 1 2.028 -2.42l5.942 -1.02 5.94 1.02a2.451 2.451 0 0 1 2.03 2.422c0 1.359 0 3.806 -0.106 4.92a12.3 12.3 0 0 1 -2.391 7.023 8.297 8.297 0 0 1 -5.33 3.224l-0.143 0.016zm-5.314 -15.019c0 2.159 -0.065 3.667 0 4.384a10.061 10.061 0 0 0 1.976 5.821 5.61 5.61 0 0 0 3.338 2.132 5.608 5.608 0 0 0 3.337 -2.132 10.063 10.063 0 0 0 1.977 -5.821c0.065 -0.717 0 -2.225 0 -4.384l-5.314 -0.91 -5.314 0.91z" opacity=".868"/>
+    <g mask="url(#H)" opacity=".993" transform="translate(-.244 -.153) scale(.45802)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#Z)" transform="translate(.359 .568) scale(.4245)">
+    <g fill="#7F00D6" mask="url(#I)" transform="translate(.359 .568) scale(.4245)">
       <use href="#shape-0"/>
-      <path d="M9.578 13.204l-6.333 1.084c0.023 2.386 0.076 4.192 0.157 5.066a14.594 14.594 0 0 0 2.863 8.943 6.807 6.807 0 0 0 3.293 2.39h0.02v-17.484z" opacity=".294"/>
+      <path d="M9.578 13.204l-6.333 1.084c0.023 2.386 0.076 4.192 0.157 5.066a14.602 14.602 0 0 0 2.863 8.943 6.807 6.807 0 0 0 3.293 2.39h0.02v-17.483z" opacity=".294"/>
     </g>
   </svg>
   <svg width="16" height="20" x="288">
     <defs>
-      <mask id="ac">
+      <mask id="K">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.433 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="ab">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="J">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aa">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aa)" opacity=".913" transform="translate(.046 .195) scale(.44187)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#ab)" transform="translate(-.12 -.004) scale(.45111)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 19.195l-0.148 -0.016a8.28 8.28 0 0 1 -5.319 -3.217 12.274 12.274 0 0 1 -2.386 -7.008c-0.1 -1.112 -0.1 -3.553 -0.1 -4.912a2.446 2.446 0 0 1 2.024 -2.416l5.929 -1.017 5.927 1.017a2.446 2.446 0 0 1 2.027 2.418c0 1.356 0 3.798 -0.106 4.91a12.274 12.274 0 0 1 -2.387 7.008 8.28 8.28 0 0 1 -5.318 3.217l-0.143 0.016zm-5.302 -14.987c0 2.154 -0.065 3.659 0 4.374a10.04 10.04 0 0 0 1.97 5.81 5.599 5.599 0 0 0 3.332 2.127 5.596 5.596 0 0 0 3.33 -2.128 10.042 10.042 0 0 0 1.972 -5.809c0.065 -0.715 0 -2.22 0 -4.374l-5.302 -0.908 -5.302 0.908z" opacity=".913"/>
+    <g mask="url(#J)" transform="translate(-.12 -.004) scale(.45111)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#ac)" transform="translate(.451 .679) scale(.41936)">
+    <g fill="#7F00D6" mask="url(#K)" transform="translate(.451 .679) scale(.41936)">
       <use href="#shape-0"/>
       <path d="M9.457 13.225l-6.318 1.081c0.022 2.38 0.076 4.183 0.156 5.055a14.567 14.567 0 0 0 2.856 8.921 6.79 6.79 0 0 0 3.285 2.383h0.02v-17.44z" opacity=".287"/>
     </g>
   </svg>
   <svg width="16" height="20" x="304">
     <defs>
-      <mask id="af">
+      <mask id="M">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.37 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="ae">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="L">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="ad">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#ad)" opacity=".949" transform="translate(.094 .251) scale(.43924)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#ae)" transform="translate(.027 .172) scale(.44294)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 19.138l-0.148 -0.015a8.23 8.23 0 0 1 -5.286 -3.198 12.201 12.201 0 0 1 -2.372 -6.966c-0.1 -1.106 -0.1 -3.533 -0.1 -4.883a2.431 2.431 0 0 1 2.012 -2.401l5.894 -1.012 5.891 1.012a2.432 2.432 0 0 1 2.015 2.402c0 1.348 0 3.776 -0.105 4.882a12.201 12.201 0 0 1 -2.372 6.966 8.23 8.23 0 0 1 -5.287 3.198l-0.142 0.015zm-5.27 -14.897c0 2.14 -0.065 3.636 0 4.348a9.98 9.98 0 0 0 1.959 5.774 5.566 5.566 0 0 0 3.311 2.115 5.562 5.562 0 0 0 3.31 -2.115 9.982 9.982 0 0 0 1.96 -5.774c0.065 -0.712 0 -2.207 0 -4.348l-5.27 -0.903 -5.27 0.903z" opacity=".949"/>
+    <g mask="url(#L)" transform="translate(.027 .172) scale(.44294)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#af)" transform="translate(.56 .808) scale(.41333)">
+    <g fill="#7F00D6" mask="url(#M)" transform="translate(.56 .808) scale(.41333)">
       <use href="#shape-0"/>
-      <path d="M9.336 13.246l-6.303 1.079c0.023 2.374 0.075 4.172 0.156 5.042a14.536 14.536 0 0 0 2.849 8.9 6.774 6.774 0 0 0 3.277 2.377h0.02v-17.398z" opacity=".279"/>
+      <path d="M9.336 13.246l-6.303 1.079c0.023 2.374 0.075 4.172 0.156 5.042a14.532 14.532 0 0 0 2.849 8.9 6.774 6.774 0 0 0 3.277 2.377h0.02v-17.398z" opacity=".279"/>
     </g>
   </svg>
   <svg width="16" height="20" x="320">
     <defs>
-      <mask id="ai">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.307 59.76l5.5 5.5 40.853 -40.854 -5.5 -5.5 -40.853 40.854" filter="null"/>
-      </mask>
-      <mask id="ah">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="O">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.307 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <clipPath id="ag">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
+      <mask id="N">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
+      </mask>
     </defs>
-    <g clip-path="url(#ag)" opacity=".977" transform="translate(.167 .34) scale(.43515)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#ah)" transform="translate(.191 .368) scale(.43382)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 19.05l-0.146 -0.015a8.153 8.153 0 0 1 -5.238 -3.168 12.088 12.088 0 0 1 -2.35 -6.901c-0.099 -1.096 -0.099 -3.5 -0.099 -4.838a2.409 2.409 0 0 1 1.994 -2.379l5.839 -1.002 5.837 1.002a2.41 2.41 0 0 1 1.996 2.38c0 1.336 0 3.741 -0.105 4.837a12.088 12.088 0 0 1 -2.35 6.9 8.153 8.153 0 0 1 -5.237 3.17l-0.141 0.014zm-5.222 -14.759c0 2.122 -0.064 3.603 0 4.308a9.888 9.888 0 0 0 1.941 5.72 5.514 5.514 0 0 0 3.281 2.096 5.51 5.51 0 0 0 3.28 -2.095 9.889 9.889 0 0 0 1.942 -5.72c0.064 -0.706 0 -2.187 0 -4.309l-5.222 -0.894 -5.222 0.894z" opacity=".977"/>
+    <g mask="url(#N)" transform="translate(.191 .368) scale(.43382)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#ai)" transform="translate(.68 .952) scale(.40665)">
+    <g fill="#7F00D6" mask="url(#O)" transform="translate(.68 .952) scale(.40665)">
       <use href="#shape-0"/>
       <path d="M9.215 13.266l-6.288 1.077c0.023 2.369 0.076 4.162 0.156 5.03a14.497 14.497 0 0 0 2.842 8.879 6.758 6.758 0 0 0 3.27 2.372h0.02v-17.358z" opacity=".272"/>
     </g>
   </svg>
   <svg width="16" height="20" x="336">
     <defs>
-      <mask id="al">
+      <mask id="Q">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.244 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="ak">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="P">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aj">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aj)" opacity=".994" transform="translate(.263 .453) scale(.42985)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#ak)" transform="translate(.367 .578) scale(.42407)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.936l-0.144 -0.015a8.054 8.054 0 0 1 -5.174 -3.13 11.94 11.94 0 0 1 -2.321 -6.816c-0.098 -1.082 -0.098 -3.457 -0.098 -4.78a2.38 2.38 0 0 1 1.969 -2.35l5.768 -0.99 5.766 0.99a2.38 2.38 0 0 1 1.971 2.352c0 1.32 0 3.696 -0.103 4.778a11.94 11.94 0 0 1 -2.321 6.817 8.054 8.054 0 0 1 -5.174 3.13l-0.139 0.014zm-5.158 -14.579c0 2.096 -0.063 3.56 0 4.256a9.767 9.767 0 0 0 1.917 5.65 5.447 5.447 0 0 0 3.241 2.07 5.444 5.444 0 0 0 3.24 -2.07 9.769 9.769 0 0 0 1.918 -5.65c0.063 -0.697 0 -2.16 0 -4.256l-5.158 -0.883 -5.158 0.883z" opacity=".994"/>
+    <g mask="url(#P)" transform="translate(.367 .578) scale(.42407)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#al)" transform="translate(.807 1.104) scale(.3996)">
+    <g fill="#7F00D6" mask="url(#Q)" transform="translate(.807 1.104) scale(.3996)">
       <use href="#shape-0"/>
       <path d="M9.095 13.287l-6.273 1.074c0.023 2.363 0.075 4.152 0.156 5.018a14.463 14.463 0 0 0 2.835 8.858 6.742 6.742 0 0 0 3.262 2.366h0.02v-17.316z" opacity=".265"/>
     </g>
   </svg>
   <svg width="16" height="20" x="352">
     <defs>
-      <mask id="ao">
+      <mask id="S">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.18 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="an">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="R">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="am">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#am)" transform="translate(.375 .588) scale(.42359)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#an)" transform="matrix(.414 0 0 .414 .548 .794)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.802l-0.142 -0.015a7.937 7.937 0 0 1 -5.099 -3.084 11.766 11.766 0 0 1 -2.287 -6.718c-0.097 -1.066 -0.097 -3.406 -0.097 -4.709a2.345 2.345 0 0 1 1.94 -2.316l5.685 -0.975 5.682 0.975a2.345 2.345 0 0 1 1.943 2.317c0 1.3 0 3.642 -0.102 4.708a11.766 11.766 0 0 1 -2.287 6.718 7.937 7.937 0 0 1 -5.099 3.084l-0.137 0.015zm-5.083 -14.367c0 2.065 -0.062 3.507 0 4.193a9.625 9.625 0 0 0 1.89 5.569 5.367 5.367 0 0 0 3.193 2.04 5.364 5.364 0 0 0 3.192 -2.04 9.626 9.626 0 0 0 1.891 -5.569c0.062 -0.686 0 -2.128 0 -4.193l-5.083 -0.87 -5.083 0.87z"/>
+    <g mask="url(#R)" transform="matrix(.414 0 0 .414 .548 .794)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#ao)" transform="translate(.937 1.258) scale(.3924)">
+    <g fill="#7F00D6" mask="url(#S)" transform="translate(.937 1.258) scale(.3924)">
       <use href="#shape-0"/>
-      <path d="M8.975 13.308l-6.258 1.071c0.023 2.358 0.076 4.143 0.156 5.006a14.428 14.428 0 0 0 2.827 8.837 6.726 6.726 0 0 0 3.254 2.36h0.02v-17.274z" opacity=".257"/>
+      <path d="M8.975 13.308l-6.258 1.071c0.023 2.358 0.076 4.143 0.156 5.006a14.428 14.428 0 0 0 2.828 8.837 6.726 6.726 0 0 0 3.254 2.36h0.02v-17.274z" opacity=".257"/>
     </g>
   </svg>
   <svg width="16" height="20" x="368">
     <defs>
-      <mask id="ar">
+      <mask id="U">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.116 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aq">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="T">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="ap">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#ap)" transform="translate(.501 .738) scale(.4166)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aq)" transform="translate(.73 1.01) scale(.40393)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.651l-0.14 -0.014a7.806 7.806 0 0 1 -5.014 -3.033 11.572 11.572 0 0 1 -2.25 -6.607c-0.095 -1.049 -0.095 -3.35 -0.095 -4.631a2.306 2.306 0 0 1 1.909 -2.278l5.59 -0.96 5.588 0.96a2.306 2.306 0 0 1 1.91 2.279c0 1.278 0 3.581 -0.1 4.63a11.572 11.572 0 0 1 -2.249 6.607 7.806 7.806 0 0 1 -5.014 3.033l-0.135 0.014zm-5 -14.13c0 2.032 -0.06 3.45 0 4.125a9.466 9.466 0 0 0 1.86 5.477 5.279 5.279 0 0 0 3.14 2.005 5.276 5.276 0 0 0 3.14 -2.005 9.467 9.467 0 0 0 1.86 -5.477c0.06 -0.675 0 -2.093 0 -4.124l-5 -0.856 -5 0.856z"/>
+    <g mask="url(#T)" transform="translate(.73 1.01) scale(.40393)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#ar)" transform="translate(1.064 1.41) scale(.38535)">
+    <g fill="#7F00D6" mask="url(#U)" transform="translate(1.064 1.41) scale(.38535)">
       <use href="#shape-0"/>
       <path d="M8.856 13.328l-6.243 1.069c0.023 2.352 0.075 4.133 0.155 4.994a14.394 14.394 0 0 0 2.822 8.816 6.71 6.71 0 0 0 3.246 2.355h0.02v-17.234z" opacity=".25"/>
     </g>
   </svg>
   <svg width="16" height="20" x="384">
     <defs>
-      <mask id="au">
+      <mask id="W">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M11.053 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="at">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="V">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="as">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#as)" transform="translate(.636 .899) scale(.40912)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#at)" transform="translate(.905 1.22) scale(.39418)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.49l-0.137 -0.014a7.665 7.665 0 0 1 -4.925 -2.978 11.365 11.365 0 0 1 -2.209 -6.489c-0.093 -1.03 -0.093 -3.29 -0.093 -4.548a2.265 2.265 0 0 1 1.874 -2.237l5.49 -0.942 5.488 0.942a2.265 2.265 0 0 1 1.876 2.238c0 1.256 0 3.518 -0.098 4.547a11.365 11.365 0 0 1 -2.21 6.489 7.665 7.665 0 0 1 -4.923 2.978l-0.133 0.015zm-4.91 -13.875c0 1.994 -0.06 3.387 0 4.05a9.296 9.296 0 0 0 1.826 5.378 5.184 5.184 0 0 0 3.084 1.97 5.181 5.181 0 0 0 3.083 -1.97 9.297 9.297 0 0 0 1.826 -5.378c0.06 -0.663 0 -2.056 0 -4.05l-4.909 -0.841 -4.91 0.84z"/>
+    <g mask="url(#V)" transform="translate(.905 1.22) scale(.39418)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#au)" transform="translate(1.184 1.554) scale(.37867)">
+    <g fill="#7F00D6" mask="url(#W)" transform="translate(1.184 1.554) scale(.37867)">
       <use href="#shape-0"/>
-      <path d="M8.738 13.349l-6.229 1.066c0.023 2.347 0.075 4.123 0.155 4.982a14.36 14.36 0 0 0 2.815 8.795 6.694 6.694 0 0 0 3.239 2.35h0.02v-17.194z" opacity=".243"/>
+      <path d="M8.738 13.349l-6.229 1.066c0.023 2.347 0.075 4.123 0.155 4.982a14.36 14.36 0 0 0 2.815 8.795 6.694 6.694 0 0 0 3.239 2.35h0.02v-17.193z" opacity=".243"/>
     </g>
   </svg>
   <svg width="16" height="20" x="400">
     <defs>
-      <mask id="ax">
+      <mask id="Y">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.989 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aw">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="X">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="av">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#av)" transform="translate(.775 1.065) scale(.4014)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aw)" transform="translate(1.069 1.416) scale(.38506)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.325l-0.135 -0.014a7.52 7.52 0 0 1 -4.831 -2.923 11.15 11.15 0 0 1 -2.168 -6.366c-0.091 -1.01 -0.091 -3.228 -0.091 -4.462a2.222 2.222 0 0 1 1.839 -2.195l5.386 -0.924 5.384 0.924a2.222 2.222 0 0 1 1.841 2.196c0 1.232 0 3.45 -0.096 4.461a11.15 11.15 0 0 1 -2.168 6.366 7.52 7.52 0 0 1 -4.83 2.923l-0.131 0.014zm-4.817 -13.615c0 1.957 -0.059 3.324 0 3.974a9.12 9.12 0 0 0 1.79 5.277 5.086 5.086 0 0 0 3.027 1.933 5.083 5.083 0 0 0 3.025 -1.933 9.122 9.122 0 0 0 1.792 -5.277c0.059 -0.65 0 -2.017 0 -3.974l-4.817 -0.824 -4.817 0.824z"/>
+    <g mask="url(#X)" transform="translate(1.069 1.416) scale(.38506)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#ax)" transform="translate(1.293 1.683) scale(.37264)">
+    <g fill="#7F00D6" mask="url(#Y)" transform="translate(1.293 1.683) scale(.37264)">
       <use href="#shape-0"/>
-      <path d="M8.62 13.369l-6.214 1.064c0.023 2.34 0.075 4.113 0.154 4.97a14.326 14.326 0 0 0 2.809 8.774 6.678 6.678 0 0 0 3.23 2.344h0.02v-17.151z" opacity=".235"/>
+      <path d="M8.62 13.369l-6.214 1.064c0.023 2.34 0.075 4.113 0.154 4.97a14.326 14.326 0 0 0 2.809 8.774 6.678 6.678 0 0 0 3.23 2.344h0.02v-17.152z" opacity=".235"/>
     </g>
   </svg>
   <svg width="16" height="20" x="416">
     <defs>
-      <mask id="aA">
+      <mask id="aa">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.925 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="az">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="Z">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="ay">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#ay)" transform="translate(.914 1.23) scale(.39368)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#az)" transform="translate(1.216 1.592) scale(.37689)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 18.159l-0.132 -0.014a7.376 7.376 0 0 1 -4.739 -2.866 10.936 10.936 0 0 1 -2.126 -6.244c-0.09 -0.99 -0.09 -3.166 -0.09 -4.376a2.18 2.18 0 0 1 1.804 -2.153l5.283 -0.906 5.28 0.906a2.18 2.18 0 0 1 1.806 2.154c0 1.208 0 3.384 -0.094 4.375a10.936 10.936 0 0 1 -2.126 6.244 7.376 7.376 0 0 1 -4.738 2.866l-0.128 0.014zm-4.724 -13.353c0 1.92 -0.058 3.26 0 3.898a8.945 8.945 0 0 0 1.756 5.175 4.988 4.988 0 0 0 2.968 1.896 4.986 4.986 0 0 0 2.967 -1.896 8.947 8.947 0 0 0 1.757 -5.175c0.058 -0.638 0 -1.979 0 -3.898l-4.724 -0.809 -4.724 0.81z"/>
+    <g mask="url(#Z)" transform="translate(1.216 1.592) scale(.37689)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aA)" transform="translate(1.385 1.794) scale(.3675)">
+    <g fill="#7F00D6" mask="url(#aa)" transform="translate(1.385 1.794) scale(.3675)">
       <use href="#shape-0"/>
-      <path d="M8.502 13.389l-6.199 1.061c0.023 2.336 0.075 4.104 0.154 4.96a14.293 14.293 0 0 0 2.802 8.753 6.663 6.663 0 0 0 3.223 2.337h0.02v-17.111z" opacity=".228"/>
+      <path d="M8.502 13.389l-6.199 1.061c0.023 2.336 0.075 4.104 0.154 4.96a14.293 14.293 0 0 0 2.802 8.753 6.663 6.663 0 0 0 3.223 2.338h0.02v-17.112z" opacity=".228"/>
     </g>
   </svg>
   <svg width="16" height="20" x="432">
     <defs>
-      <mask id="aD">
+      <mask id="ac">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.862 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aC">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="ab">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aB">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aB)" transform="translate(1.048 1.392) scale(.3862)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aC)" transform="translate(1.34 1.74) scale(.36998)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.998l-0.13 -0.013a7.236 7.236 0 0 1 -4.648 -2.812 10.728 10.728 0 0 1 -2.086 -6.125c-0.088 -0.972 -0.088 -3.106 -0.088 -4.294a2.138 2.138 0 0 1 1.77 -2.111l5.182 -0.89 5.18 0.89a2.138 2.138 0 0 1 1.772 2.112c0 1.186 0 3.32 -0.093 4.293a10.728 10.728 0 0 1 -2.086 6.125 7.236 7.236 0 0 1 -4.648 2.812l-0.125 0.013zm-4.634 -13.099c0 1.883 -0.057 3.198 0 3.824a8.775 8.775 0 0 0 1.722 5.077 4.894 4.894 0 0 0 2.912 1.86 4.89 4.89 0 0 0 2.91 -1.86 8.777 8.777 0 0 0 1.724 -5.077c0.057 -0.626 0 -1.941 0 -3.824l-4.634 -0.794 -4.634 0.794z"/>
+    <g mask="url(#ab)" transform="translate(1.34 1.74) scale(.36998)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aD)" transform="translate(1.457 1.88) scale(.3635)">
+    <g fill="#7F00D6" mask="url(#ac)" transform="translate(1.457 1.88) scale(.3635)">
       <use href="#shape-0"/>
-      <path d="M8.386 13.409l-6.186 1.059c0.023 2.33 0.075 4.094 0.154 4.947a14.26 14.26 0 0 0 2.795 8.733 6.647 6.647 0 0 0 3.216 2.333h0.02v-17.072z" opacity=".221"/>
+      <path d="M8.386 13.409l-6.185 1.059c0.023 2.33 0.075 4.094 0.154 4.947a14.26 14.26 0 0 0 2.795 8.733 6.647 6.647 0 0 0 3.216 2.333h0.02v-17.072z" opacity=".221"/>
     </g>
   </svg>
   <svg width="16" height="20" x="448">
     <defs>
-      <mask id="aG">
+      <mask id="ae">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.799 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aF">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="ad">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aE">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aE)" transform="translate(1.174 1.542) scale(.37921)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aF)" transform="translate(1.436 1.855) scale(.36465)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.848l-0.127 -0.014a7.105 7.105 0 0 1 -4.565 -2.76 10.534 10.534 0 0 1 -2.047 -6.015c-0.087 -0.954 -0.087 -3.05 -0.087 -4.215a2.1 2.1 0 0 1 1.737 -2.073l5.089 -0.874 5.086 0.874a2.1 2.1 0 0 1 1.74 2.074c0 1.164 0 3.26 -0.091 4.214a10.534 10.534 0 0 1 -2.048 6.014 7.105 7.105 0 0 1 -4.564 2.761l-0.123 0.014zm-4.55 -12.862c0 1.849 -0.056 3.14 0 3.754a8.617 8.617 0 0 0 1.691 4.985 4.805 4.805 0 0 0 2.859 1.826 4.802 4.802 0 0 0 2.858 -1.826 8.618 8.618 0 0 0 1.693 -4.985c0.055 -0.614 0 -1.905 0 -3.754l-4.551 -0.78 -4.55 0.78z"/>
+    <g mask="url(#ad)" transform="translate(1.436 1.855) scale(.36465)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aG)" transform="translate(1.503 1.935) scale(.36092)">
+    <g fill="#7F00D6" mask="url(#ae)" transform="translate(1.503 1.935) scale(.36092)">
       <use href="#shape-0"/>
-      <path d="M8.27 13.429l-6.17 1.056c0.022 2.325 0.074 4.085 0.153 4.936a14.226 14.226 0 0 0 2.789 8.713 6.632 6.632 0 0 0 3.208 2.326h0.02v-17.03z" opacity=".213"/>
+      <path d="M8.27 13.429l-6.17 1.056c0.022 2.325 0.074 4.085 0.153 4.936a14.226 14.226 0 0 0 2.789 8.713 6.632 6.632 0 0 0 3.208 2.327h0.02v-17.032z" opacity=".213"/>
     </g>
   </svg>
   <svg width="16" height="20" x="464">
     <defs>
-      <mask id="aJ">
+      <mask id="ag">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.736 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aI">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="af">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aH">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aH)" transform="translate(1.287 1.677) scale(.37295)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aI)" transform="translate(1.498 1.929) scale(.36121)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.713l-0.125 -0.013a6.988 6.988 0 0 1 -4.49 -2.716 10.36 10.36 0 0 1 -2.013 -5.914c-0.085 -0.939 -0.085 -3 -0.085 -4.146a2.064 2.064 0 0 1 1.708 -2.039l5.005 -0.859 5.002 0.859a2.065 2.065 0 0 1 1.711 2.04c0 1.145 0 3.206 -0.09 4.145a10.36 10.36 0 0 1 -2.013 5.914 6.988 6.988 0 0 1 -4.49 2.716l-0.12 0.013zm-4.475 -12.65c0 1.819 -0.055 3.089 0 3.693a8.474 8.474 0 0 0 1.663 4.903 4.726 4.726 0 0 0 2.812 1.795 4.723 4.723 0 0 0 2.81 -1.795 8.475 8.475 0 0 0 1.665 -4.903c0.055 -0.604 0 -1.874 0 -3.692l-4.475 -0.767 -4.475 0.767z"/>
+    <g mask="url(#af)" transform="translate(1.498 1.929) scale(.36121)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aJ)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#ag)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
-      <path d="M8.155 13.449l-6.156 1.053c0.022 2.32 0.074 4.075 0.153 4.925a14.193 14.193 0 0 0 2.782 8.692 6.616 6.616 0 0 0 3.2 2.322h0.02v-16.991z" opacity=".206"/>
+      <path d="M8.155 13.449l-6.156 1.053c0.022 2.32 0.074 4.075 0.153 4.925a14.193 14.193 0 0 0 2.782 8.692 6.616 6.616 0 0 0 3.2 2.322h0.02v-16.992z" opacity=".206"/>
     </g>
   </svg>
   <svg width="16" height="20" x="480">
     <defs>
-      <mask id="aM">
+      <mask id="ai">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.673 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aL">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M9.077 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
+      <mask id="ah">
+        <use fill="#fff" stroke="#fff" stroke-width="0" href="#shape-3" filter="null"/>
       </mask>
-      <clipPath id="aK">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aK)" transform="translate(1.382 1.79) scale(.36765)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aL)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.6l-0.124 -0.014a6.888 6.888 0 0 1 -4.425 -2.677 10.213 10.213 0 0 1 -1.985 -5.83c-0.084 -0.926 -0.084 -2.957 -0.084 -4.087a2.035 2.035 0 0 1 1.685 -2.01l4.933 -0.847 4.931 0.847a2.035 2.035 0 0 1 1.687 2.01c0 1.13 0 3.161 -0.089 4.087a10.213 10.213 0 0 1 -1.985 5.83 6.888 6.888 0 0 1 -4.425 2.677l-0.119 0.013zm-4.412 -12.47c0 1.792 -0.054 3.044 0 3.64a8.354 8.354 0 0 0 1.64 4.832 4.658 4.658 0 0 0 2.772 1.77 4.656 4.656 0 0 0 2.77 -1.77 8.355 8.355 0 0 0 1.642 -4.833c0.054 -0.595 0 -1.847 0 -3.64l-4.412 -0.755 -4.412 0.756z"/>
+    <g mask="url(#ah)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aM)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#ai)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
-      <path d="M8.04 13.468l-6.14 1.052c0.022 2.314 0.073 4.065 0.152 4.913a14.16 14.16 0 0 0 2.776 8.672 6.6 6.6 0 0 0 3.193 2.317h0.02v-16.954z" opacity=".199"/>
+      <path d="M8.04 13.468l-6.141 1.052c0.022 2.314 0.073 4.065 0.152 4.913a14.16 14.16 0 0 0 2.776 8.672 6.6 6.6 0 0 0 3.193 2.317h0.02v-16.954z" opacity=".199"/>
     </g>
   </svg>
   <svg width="16" height="20" x="496">
     <defs>
-      <mask id="aP">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.61 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.855 40.854" filter="null"/>
+      <mask id="ak">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.61 59.76l5.5 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aO">
+      <mask id="aj">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M8.243 58.758l6.362 6.474 40.854 -40.854 -6.355 -6.474 -40.861 40.854" filter="null"/>
       </mask>
-      <clipPath id="aN">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aN)" transform="translate(1.456 1.878) scale(.36356)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aO)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.511l-0.122 -0.012a6.812 6.812 0 0 1 -4.376 -2.648 10.1 10.1 0 0 1 -1.963 -5.765c-0.083 -0.915 -0.083 -2.924 -0.083 -4.042a2.012 2.012 0 0 1 1.665 -1.988l4.879 -0.837 4.876 0.837a2.013 2.013 0 0 1 1.668 1.989c0 1.116 0 3.126 -0.087 4.04a10.1 10.1 0 0 1 -1.963 5.766 6.812 6.812 0 0 1 -4.376 2.648l-0.118 0.012zm-4.363 -12.33c0 1.772 -0.053 3.01 0 3.599a8.261 8.261 0 0 0 1.622 4.779 4.607 4.607 0 0 0 2.741 1.75 4.604 4.604 0 0 0 2.74 -1.75 8.262 8.262 0 0 0 1.623 -4.78c0.053 -0.588 0 -1.826 0 -3.599l-4.363 -0.747 -4.363 0.747z"/>
+    <g mask="url(#aj)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aP)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#ak)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
-      <path d="M7.927 13.488l-6.128 1.049c0.022 2.308 0.074 4.056 0.152 4.902a14.134 14.134 0 0 0 2.77 8.652 6.586 6.586 0 0 0 3.186 2.311h0.02v-16.914z" opacity=".191"/>
+      <path d="M7.927 13.488l-6.128 1.049c0.022 2.308 0.074 4.056 0.152 4.902a14.128 14.128 0 0 0 2.77 8.652 6.586 6.586 0 0 0 3.186 2.311h0.02v-16.914z" opacity=".191"/>
     </g>
   </svg>
   <svg width="16" height="20" x="512">
     <defs>
-      <mask id="aS">
-        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.55 59.76l5.498 5.5 40.855 -40.854 -5.5 -5.5 -40.853 40.854" filter="null"/>
+      <mask id="am">
+        <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.55 59.76l5.498 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aR">
+      <mask id="al">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M5.98 56.039l8.701 9.117 40.854 -40.854 -8.675 -9.117 -40.88 40.854" filter="null"/>
       </mask>
-      <clipPath id="aQ">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aQ)" transform="translate(1.503 1.935) scale(.36093)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aR)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <path fill="#0C0C0C" fill-opacity=".2" d="M8 17.455l-0.121 -0.013a6.763 6.763 0 0 1 -4.344 -2.628 10.026 10.026 0 0 1 -1.95 -5.724c-0.082 -0.908 -0.082 -2.903 -0.082 -4.012a1.998 1.998 0 0 1 1.654 -1.974l4.843 -0.83 4.841 0.83a1.998 1.998 0 0 1 1.656 1.975c0 1.107 0 3.103 -0.087 4.011a10.026 10.026 0 0 1 -1.949 5.724 6.763 6.763 0 0 1 -4.344 2.628l-0.117 0.013zm-4.331 -12.242c0 1.76 -0.053 2.988 0 3.573a8.201 8.201 0 0 0 1.61 4.745 4.573 4.573 0 0 0 2.721 1.738 4.57 4.57 0 0 0 2.72 -1.738 8.202 8.202 0 0 0 1.611 -4.745c0.053 -0.585 0 -1.814 0 -3.573l-4.331 -0.742 -4.331 0.742z"/>
+    <g mask="url(#al)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aS)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#am)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
       <path d="M7.814 13.507l-6.113 1.047c0.022 2.303 0.073 4.047 0.151 4.89a14.095 14.095 0 0 0 2.764 8.633 6.57 6.57 0 0 0 3.178 2.306h0.02v-16.876z" opacity=".184"/>
     </g>
   </svg>
   <svg width="16" height="20" x="528">
     <defs>
-      <mask id="aV">
+      <mask id="ao">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.488 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aU">
+      <mask id="an">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M2.648 52.034l12.145 13.01 40.854 -40.854 -12.091 -13.01 -40.908 40.854" filter="null"/>
       </mask>
-      <clipPath id="aT">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aT)" transform="matrix(.36 0 0 .36 1.52 1.955)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aU)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#an)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aV)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#ao)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
-      <path d="M7.702 13.526l-6.099 1.044c0.022 2.299 0.073 4.038 0.151 4.88a14.063 14.063 0 0 0 2.757 8.613 6.556 6.556 0 0 0 3.172 2.3h0.02v-16.836z" opacity=".176"/>
+      <path d="M7.702 13.526l-6.099 1.044c0.022 2.299 0.073 4.038 0.151 4.88a14.063 14.063 0 0 0 2.757 8.613 6.556 6.556 0 0 0 3.172 2.3h0.02v-16.837z" opacity=".176"/>
     </g>
   </svg>
   <svg width="16" height="20" x="544">
     <defs>
-      <mask id="aY">
+      <mask id="aq">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.428 59.76l5.499 5.5 40.855 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="aX">
+      <mask id="ap">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M-1.397 47.174l16.326 17.734 40.854 -40.854 -16.238 -17.734 -40.942 40.854" filter="null"/>
       </mask>
-      <clipPath id="aW">
-        <path fill="#fff" d="M-20.673 21.406l36.25 40.25 40.854 -40.855 -36 -40.249 -41.104 40.854"/>
-      </clipPath>
     </defs>
-    <g clip-path="url(#aW)" transform="matrix(.36 0 0 .36 1.52 1.955)">
-      <use fill="context-fill" fill-opacity="context-fill-opacity" href="#shape-0"/>
-    </g>
-    <g mask="url(#aX)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <use fill="#0C0C0C" fill-opacity=".2" href="#shape-4"/>
+    <g mask="url(#ap)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use fill="#ED00B5" href="#shape-0"/>
     </g>
-    <g fill="context-fill" fill-opacity="context-fill-opacity" mask="url(#aY)" transform="matrix(.36 0 0 .36 1.52 1.955)">
+    <g fill="#7F00D6" mask="url(#aq)" transform="matrix(.36 0 0 .36 1.52 1.955)">
       <use href="#shape-0"/>
-      <path d="M7.592 13.545l-6.086 1.042c0.022 2.293 0.073 4.029 0.151 4.869a14.037 14.037 0 0 0 2.75 8.593 6.541 6.541 0 0 0 3.165 2.296h0.02v-16.8z" opacity=".169"/>
+      <path d="M7.592 13.545l-6.086 1.042c0.022 2.293 0.073 4.029 0.151 4.869a14.032 14.032 0 0 0 2.75 8.593 6.541 6.541 0 0 0 3.165 2.296h0.02v-16.8z" opacity=".169"/>
     </g>
   </svg>
   <svg width="16" height="20" x="560">
     <defs>
-      <mask id="bb">
+      <mask id="as">
         <path fill="#fff" stroke="#fff" stroke-width="0" d="M10.368 59.76l5.5 5.5 40.854 -40.854 -5.5 -5.5 -40.854 40.854" filter="null"/>
       </mask>
-      <mask id="ba">
+      <mask id="ar">
         <path fill="#fff&quo