1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-19 16:34:34 -04:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Keivan Beigi
a34e69b35b Notification API Cleanup 2016-12-27 23:52:20 -08:00
486 changed files with 994 additions and 13533 deletions

View File

@@ -2,6 +2,4 @@
Provide a description of the feature request or bug, the more details the better.
When possible include a log!
Please use our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
Please use https://forums.sonarr.tv/ for support or other questions. (When in doubt, use the forums)

9
.gitignore vendored
View File

@@ -127,18 +127,9 @@ bin
obj
output/*
#Packages
Radarr_*/
Radarr_*.zip
Radarr_*.gz
#OS X metadata files
._*
.DS_Store
_start
_temp_*/**/*
#AppVeyor
/tools-cake/
/_artifacts/

View File

@@ -1,14 +0,0 @@
language: csharp
solution: src/NzbDrone.sln
script: # the following commands are just examples, use whatever your build process requires
- ./build.sh
- chmod +x test.sh
# - ./test.sh Linux Unit Takes far too long, maybe even crashes travis :/
install:
- sudo apt-get install nodejs
- sudo apt-get install npm
after_success:
- chmod +x package.sh
- ./package.sh
notifications:
- webhooks: https://discordapp.com/api/webhooks/266910310219251712/V-QvCcnYkg3O8PMevcAJOJyCgrYkZQoF2pupLDGbaISNUECmYPd6LRwl3avKHsPyfgWP

BIN
7za.dll

Binary file not shown.

BIN
7za.exe

Binary file not shown.

BIN
7zxa.dll

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -1,572 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
<title>SVG</title>
<desc>Created with Sketch.</desc>
<defs>
<ellipse id="path-1" cx="512" cy="512" rx="512" ry="512"></ellipse>
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="1024" height="1024" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<mask id="mask-4" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="1024" height="1024" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<polygon id="path-5" points="0 0 1007.8334 0 1007.8334 1181.7303 0 1181.7303"></polygon>
<polygon id="path-7" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-9" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-11" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-13" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-15" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-17" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-19" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-21" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-23" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-25" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-27" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-29" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-31" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-33" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-35" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-37" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-39" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-41" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-43" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<polygon id="path-45" points="0 0.308593451 979.971467 0.308593451 979.971467 66.8717453 0 66.8717453"></polygon>
<path d="M211.257613,211.421878 C134.335253,288.344238 86.7577838,394.611489 86.7577838,511.991053 C86.7577838,629.370617 134.335253,735.637868 211.257613,812.560228 L511.826788,511.991053 L211.257613,211.421878 Z" id="path-47"></path>
<path d="M639.447177,208.78225 C562.524817,285.704609 514.947349,391.97186 514.947349,509.351425 C514.947349,626.730989 562.524817,732.99824 639.447177,809.9206 L940.016353,509.351425 L639.447177,208.78225 Z" id="path-49"></path>
<ellipse id="path-51" cx="512" cy="512" rx="512" ry="512"></ellipse>
<mask id="mask-52" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="1024" height="1024" fill="white">
<use xlink:href="#path-51"></use>
</mask>
</defs>
<g id="Logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="SVG">
<mask id="mask-3" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Mask" stroke="#FFC231" mask="url(#mask-2)" stroke-width="40" fill="#050808">
<use mask="url(#mask-4)" xlink:href="#path-1"></use>
</g>
<g id="Grid" mask="url(#mask-3)">
<g transform="translate(23.843025, 1.692150)">
<mask id="mask-6" fill="white">
<use xlink:href="#path-5"></use>
</mask>
<g id="Duplicate-control" stroke="none" fill="none"></g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g id="Group" transform="translate(0.000000, 0.924454)">
<mask id="mask-8" fill="white">
<use xlink:href="#path-7"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-8)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g id="Group" transform="translate(27.861934, 50.883783)">
<mask id="mask-10" fill="white">
<use xlink:href="#path-9"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-10)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 901.189447)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-12" fill="white">
<use xlink:href="#path-11"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-12)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-14" fill="white">
<use xlink:href="#path-13"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-14)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 801.270788)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-16" fill="white">
<use xlink:href="#path-15"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-16)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-18" fill="white">
<use xlink:href="#path-17"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-18)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 700.391372)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-20" fill="white">
<use xlink:href="#path-19"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-20)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-22" fill="white">
<use xlink:href="#path-21"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-22)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 600.472713)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-24" fill="white">
<use xlink:href="#path-23"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-24)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-26" fill="white">
<use xlink:href="#path-25"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-26)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 500.554053)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-28" fill="white">
<use xlink:href="#path-27"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-28)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-30" fill="white">
<use xlink:href="#path-29"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-30)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 400.635394)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-32" fill="white">
<use xlink:href="#path-31"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-32)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-34" fill="white">
<use xlink:href="#path-33"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-34)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 299.755978)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-36" fill="white">
<use xlink:href="#path-35"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-36)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-38" fill="white">
<use xlink:href="#path-37"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-38)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 199.837319)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-40" fill="white">
<use xlink:href="#path-39"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.91846539e-13 50.2309573 1.73194792e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-40)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-42" fill="white">
<use xlink:href="#path-41"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-42)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
<g id="Group-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-6)">
<g transform="translate(0.000000, 99.918659)" id="Group">
<g transform="translate(0.000000, 0.924454)">
<mask id="mask-44" fill="white">
<use xlink:href="#path-43"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-44)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
<g transform="translate(27.861934, 50.883783)">
<mask id="mask-46" fill="white">
<use xlink:href="#path-45"></use>
</mask>
<g id="Duplicate-control"></g>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="28.8226902 0.308593451 57.6453804 16.9493814 57.6453804 50.2309573 28.8226902 66.8717453 1.95399252e-13 50.2309573 1.76747506e-13 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="951.148777 0.308593451 979.971467 16.9493814 979.971467 50.2309573 951.148777 66.8717453 922.326087 50.2309573 922.326087 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="893.503397 0.308593451 922.326087 16.9493814 922.326087 50.2309573 893.503397 66.8717453 864.680706 50.2309573 864.680706 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="835.858016 0.308593451 864.680706 16.9493814 864.680706 50.2309573 835.858016 66.8717453 807.035326 50.2309573 807.035326 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="778.212636 0.308593451 807.035326 16.9493814 807.035326 50.2309573 778.212636 66.8717453 749.389945 50.2309573 749.389945 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="720.567255 0.308593451 749.389945 16.9493814 749.389945 50.2309573 720.567255 66.8717453 691.744565 50.2309573 691.744565 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="662.921875 0.308593451 691.744565 16.9493814 691.744565 50.2309573 662.921875 66.8717453 634.099185 50.2309573 634.099185 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="605.276494 0.308593451 634.099185 16.9493814 634.099185 50.2309573 605.276494 66.8717453 576.453804 50.2309573 576.453804 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="547.631114 0.308593451 576.453804 16.9493814 576.453804 50.2309573 547.631114 66.8717453 518.808424 50.2309573 518.808424 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="489.985734 0.308593451 518.808424 16.9493814 518.808424 50.2309573 489.985734 66.8717453 461.163043 50.2309573 461.163043 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="432.340353 0.308593451 461.163043 16.9493814 461.163043 50.2309573 432.340353 66.8717453 403.517663 50.2309573 403.517663 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="374.694973 0.308593451 403.517663 16.9493814 403.517663 50.2309573 374.694973 66.8717453 345.872283 50.2309573 345.872283 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="317.049592 0.308593451 345.872283 16.9493814 345.872283 50.2309573 317.049592 66.8717453 288.226902 50.2309573 288.226902 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="259.404212 0.308593451 288.226902 16.9493814 288.226902 50.2309573 259.404212 66.8717453 230.581522 50.2309573 230.581522 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="201.758831 0.308593451 230.581522 16.9493814 230.581522 50.2309573 201.758831 66.8717453 172.936141 50.2309573 172.936141 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="144.113451 0.308593451 172.936141 16.9493814 172.936141 50.2309573 144.113451 66.8717453 115.290761 50.2309573 115.290761 16.9493814"></polygon>
<polygon id="Polygon" stroke="#999999" mask="url(#mask-46)" points="86.4680706 0.308593451 115.290761 16.9493814 115.290761 50.2309573 86.4680706 66.8717453 57.6453804 50.2309573 57.6453804 16.9493814"></polygon>
</g>
</g>
</g>
</g>
</g>
<mask id="mask-48" fill="white">
<use xlink:href="#path-47"></use>
</mask>
<use id="Combined-Shape" fill="#F1F1F1" xlink:href="#path-47"></use>
<mask id="mask-50" fill="white">
<use xlink:href="#path-49"></use>
</mask>
<use id="Combined-Shape" fill="#F1F1F1" transform="translate(727.481851, 509.351425) rotate(-180.000000) translate(-727.481851, -509.351425) " xlink:href="#path-49"></use>
<circle id="Oval-2" fill="#FFC231" cx="512.387624" cy="512.387624" r="135.118088"></circle>
<path d="M691.584224,554.79626 L741.584224,554.79626 L741.584224,848.113106 L691.584224,848.113106 L691.584224,554.79626 Z M691.584224,668.27622 L707.760695,668.27622 L707.760695,848.113106 L691.584224,848.113106 L691.584224,668.27622 Z M725.407754,668.27622 L741.584224,668.27622 L741.584224,848.113106 L725.407754,848.113106 L725.407754,668.27622 Z" id="Combined-Shape" fill="#FFC231" transform="translate(716.584224, 701.454683) rotate(133.000000) translate(-716.584224, -701.454683) "></path>
<path d="M288.802242,169.956176 L338.802242,169.956176 L338.802242,463.273022 L288.802242,463.273022 L288.802242,169.956176 Z M288.802242,283.436136 L304.978713,283.436136 L304.978713,463.273022 L288.802242,463.273022 L288.802242,283.436136 Z M322.625772,283.436136 L338.802242,283.436136 L338.802242,463.273022 L322.625772,463.273022 L322.625772,283.436136 Z" id="Combined-Shape" fill="#FFC231" transform="translate(313.802242, 316.614599) scale(-1, -1) rotate(133.000000) translate(-313.802242, -316.614599) "></path>
<path d="M816.093378,100.047294 C731.060203,37.1735645 625.871277,0 512,0 C398.30327,0 293.262295,37.0596891 208.297793,99.7583476 L404.58707,301.155391 C436.776006,284.750117 473.221118,275.499672 511.826788,275.499672 C550.704585,275.499672 587.391258,284.880988 619.746562,301.503373 L816.093378,100.047294 Z" id="Combined-Shape" fill="#F1F1F1"></path>
<path d="M816.093378,823.047294 C731.060203,760.173564 625.871277,723 512,723 C398.30327,723 293.262295,760.059689 208.297793,822.758348 L404.58707,1024.15539 C436.776006,1007.75012 473.221118,998.499672 511.826788,998.499672 C550.704585,998.499672 587.391258,1007.88099 619.746562,1024.50337 L816.093378,823.047294 Z" id="Combined-Shape" fill="#F1F1F1" transform="translate(512.195585, 873.751687) scale(1, -1) translate(-512.195585, -873.751687) "></path>
<use id="Grid-Mask" stroke="#FFC231" mask="url(#mask-52)" stroke-width="40" xlink:href="#path-51"></use>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 98 KiB

240
Logo/Sonarr.svg Normal file
View File

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="218px"
height="218px" viewBox="0 0 218 218" enable-background="new 0 0 218 218" xml:space="preserve">
<symbol id="hex_grid" viewBox="-114.25 -98.617 228.55 197.233">
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#989898" stroke-width="0.5" stroke-linecap="square" stroke-miterlimit="1" d="
M72.15,90.3l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7V90.3z M62.85,95.7l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7V95.7l4.65,2.7
l4.65-2.7 M62.85,90.3l4.65-2.7l4.65,2.7 M62.85,79.55v-5.4l4.65-2.7l4.65,2.7v5.4L67.5,82.2L62.85,79.55L58.2,82.2l-4.65-2.65
M72.15,74.15l4.7-2.7l4.65,2.7v5.4l-4.65,2.65l-4.7-2.65 M76.85,87.6v-5.4 M67.5,87.6v-5.4 M81.5,95.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7l4.65,2.7l4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4
l4.65-2.7v-5.4L109.4,31v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7
V-31l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4l-4.65-2.7v-5.4l4.65-2.7v-5.4l-4.65-2.65v-5.4l4.65-2.7v-5.4
l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7
l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7L7-98.4l-4.65,2.7l-4.65-2.7
l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7
l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.7-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7l-4.65-2.7l-4.65,2.7v5.4l-4.65,2.7
v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65
v5.4l-4.65,2.7v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7V31l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7
v5.4l4.65,2.7v5.4l-4.65,2.7v5.4l4.65,2.65v5.4l-4.65,2.7v5.4l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7
l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7L7,95.7l4.65,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.7,2.7l4.65-2.7l4.65,2.7l4.65-2.7l4.65,2.7
l4.65-2.7 M44.25,95.7v-5.4l4.65-2.7l4.65,2.7 M44.25,79.55v-5.4l4.65-2.7l4.65,2.7v5.4L48.9,82.2L44.25,79.55L39.6,82.2
l-4.65-2.65 M58.2,87.6v-5.4 M48.9,87.6v-5.4 M53.55,63.35v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L53.55,63.35l-4.65,2.7l-4.65-2.7
v-5.4l4.65-2.7l4.65,2.7 M62.85,74.15l-4.65-2.7v-5.4 M53.55,74.15l4.65-2.7 M48.9,71.45v-5.4 M48.9,55.25v-5.4l4.65-2.65
l4.65,2.65v5.4 M67.5,71.45v-5.4l4.65-2.7l4.7,2.7v5.4 M67.5,66.05l-4.65-2.7 M58.2,49.85l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M72.15,63.35v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.7 M76.85,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M67.5,55.25l4.65,2.7
M34.95,95.7v-5.4l4.65-2.7l4.65,2.7 M16.3,95.7v-5.4l4.65-2.7l4.65,2.7v5.4 M25.6,90.3l4.7-2.7l4.65,2.7 M25.6,79.55v-5.4l4.7-2.7
l4.65,2.7v5.4L30.3,82.2L25.6,79.55l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M20.95,87.6v-5.4 M39.6,87.6v-5.4 M30.3,87.6
v-5.4 M7,95.7v-5.4l4.65-2.7l4.65,2.7 M-2.3,95.7v-5.4l4.65-2.7L7,90.3 M2.35,82.2l-4.65-2.65v-5.4l4.65-2.7L7,74.15v5.4L2.35,82.2
z M16.3,79.55l-4.65,2.65L7,79.55 M2.35,87.6v-5.4 M11.65,87.6v-5.4 M16.3,74.15l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M2.35,71.45
v-5.4L7,63.35l4.65,2.7 M2.35,49.85L7,47.2l4.65,2.65v5.4L7,57.95l-4.65-2.7V49.85L-2.3,47.2v-5.4l4.65-2.7L7,41.8v5.4
M11.65,55.25l4.65,2.7v5.4 M7,74.15l4.65-2.7 M7,57.95v5.4 M30.3,71.45v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M16.3,57.95
l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M30.3,66.05l-4.7-2.7 M30.3,49.85l4.65-2.65l4.65,2.65v5.4l-4.65,2.7l-4.65-2.7V49.85l-4.7-2.65
v-5.4l-4.65-2.7v-5.4L25.6,31l4.7,2.7v5.4l-4.7,2.7 M11.65,49.85l4.65-2.65l4.65,2.65v5.4 M25.6,57.95l4.7-2.7 M34.95,57.95v5.4
M34.95,47.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M25.6,31v-5.4l4.7-2.7l4.65,2.7V31l-4.65,2.7 M34.95,25.6l4.65-2.7l4.65,2.7
V31l-4.65,2.7L34.95,31 M30.3,39.1l4.65,2.7 M39.6,39.1v-5.4 M20.95,39.1l-4.65,2.7l-4.65-2.7v-5.4L16.3,31l4.65,2.7 M16.3,41.8
v5.4 M2.35,33.7L-2.3,31v-5.4l4.65-2.7L7,25.6V31L2.35,33.7z M7,25.6l4.65-2.7l4.65,2.7V31 M2.35,39.1v-5.4 M11.65,33.7L7,31
M7,41.8l4.65-2.7 M11.65,17.5L7,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L11.65,17.5z M11.65,22.9v-5.4 M2.35,22.9v-5.4L7,14.85 M7,9.45
l-4.65-2.7v-5.4L7-1.35l4.65,2.7v5.4 M34.95,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L39.6,17.5L34.95,14.85z M39.6,22.9v-5.4 M25.6,25.6
l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4 M16.3,9.45l4.65-2.7l4.65,2.7v5.4 M34.95,9.45l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M11.65,1.35l4.65-2.7l4.65,2.7v5.4 M25.6,9.45l4.7-2.7 M30.3,17.5l4.65-2.65 M16.3,25.6l4.65-2.7 M20.95,17.5l-4.65-2.65
M76.85,49.85l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M62.85,47.2v-5.4l4.65-2.7l4.65,2.7 M62.85,25.6l4.65-2.7l4.65,2.7V31
l-4.65,2.7L62.85,31V25.6l-4.65-2.7v-5.4 M72.15,25.6l4.7-2.7l4.65,2.7V31l-4.65,2.7l-4.7-2.7 M76.85,39.1v-5.4 M67.5,39.1v-5.4
M53.55,47.2v-5.4l4.65-2.7l4.65,2.7 M44.25,41.8l4.65-2.7l4.65,2.7 M44.25,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7L44.25,31
M62.85,31l-4.65,2.7L53.55,31 M58.2,39.1v-5.4 M48.9,39.1v-5.4 M53.55,14.85v-5.4l4.65-2.7l4.65,2.7v5.4L58.2,17.5L53.55,14.85
L48.9,17.5l-4.65-2.65 M48.9,22.9v-5.4 M53.55,9.45l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M44.25,9.45l4.65-2.7 M76.85,22.9v-5.4
l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M76.85,17.5l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M67.5,22.9v-5.4l4.65-2.65 M67.5,17.5
l-4.65-2.65 M72.15,9.45l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4 M62.85,9.45l4.65-2.7 M53.55,25.6l4.65-2.7 M44.25,63.35l-4.65,2.7
M39.6,55.25l4.65,2.7 M39.6,71.45l4.65,2.7 M67.5,49.85l4.65-2.65 M48.9,49.85l-4.65-2.65 M25.6,47.2l-4.65,2.65 M104.75,87.6
l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65V87.6l4.65,2.7 M109.4,79.55l-4.65,2.65 M100.1,95.7v-5.4 M81.5,90.3l4.65-2.7
l4.65,2.7v5.4 M81.5,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65 M90.8,79.55l4.65,2.65 M86.15,87.6v-5.4 M90.8,90.3
l4.65-2.7 M95.45,71.45v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L95.45,71.45l-4.65,2.7 M86.15,55.25l4.65,2.7v5.4l-4.65,2.7
l-4.65-2.7 M86.15,71.45v-5.4 M95.45,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7L95.45,55.25l-4.65,2.7 M100.1,63.35v-5.4
M90.8,63.35l4.65,2.7 M109.4,63.35l-4.65,2.7 M104.75,71.45l4.65,2.7 M104.75,55.25l4.65,2.7 M100.1,79.55v-5.4 M100.1,47.2v-5.4
l4.65-2.7l4.65,2.7 M100.1,41.8l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M109.4,31l-4.65,2.7 M81.5,41.8l4.65-2.7l4.65,2.7v5.4
l-4.65,2.65 M86.15,22.9l4.65,2.7V31l-4.65,2.7L81.5,31 M100.1,31v-5.4l4.65-2.7l4.65,2.7 M90.8,31l4.65,2.7 M86.15,39.1v-5.4
M90.8,41.8l4.65-2.7 M86.15,17.5l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M90.8,14.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65
M81.5,9.45l4.65-2.7l4.65,2.7 M86.15,6.75v-5.4l4.65-2.7l4.65,2.7v5.4 M100.1,14.85l4.65,2.65v5.4 M109.4,14.85l-4.65,2.65
M100.1,9.45l4.65-2.7l4.65,2.7 M95.45,1.35l4.65-2.7l4.65,2.7v5.4 M95.45,22.9l4.65,2.7 M109.4,47.2l-4.65,2.65 M90.8,47.2
l4.65,2.65 M104.75-9.45l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65V-9.45l4.65,2.7 M109.4-17.5l-4.65,2.65 M100.1-1.35v-5.4
M90.8-1.35v-5.4l4.65-2.7 M81.5-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4L81.5-6.75v5.4l-4.65,2.7 M90.8-6.75l-4.65-2.7
M95.45-14.85L90.8-17.5v-5.4l4.65-2.7l4.65,2.7v5.4 M76.85-14.85l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7v5.4 M86.15-14.85l4.65-2.65
M95.45-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L95.45-31z M95.45-25.6V-31 M90.8-22.9l-4.65-2.7V-31l4.65-2.7 M86.15-31
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M86.15-41.8v-5.4l4.65-2.65l4.65,2.65v5.4 M100.1-33.7l4.65,2.7v5.4l-4.65,2.7 M109.4-33.7
l-4.65,2.7 M95.45-47.2l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M104.75-41.8l4.65,2.7 M81.5-22.9l4.65-2.7 M104.75-25.6l4.65,2.7
M100.1-49.85v-5.4l4.65-2.7l4.65,2.7 M109.4-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M104.75-63.35v5.4 M100.1-55.25
l-4.65-2.7v-5.4l4.65-2.7 M86.15-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M86.15-74.15l4.65,2.7v5.4l-4.65,2.7l-4.65-2.7v-5.4
L86.15-74.15v-5.4l4.65-2.65l4.65,2.65 M90.8-71.45l4.65-2.7l4.65,2.7 M95.45-63.35l-4.65-2.7 M90.8-55.25l4.65-2.7 M86.15-57.95
v-5.4 M95.45-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M81.5-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65 M81.5-82.2v-5.4l4.65-2.7
l4.65,2.7v5.4 M86.15-90.3v-5.4 M104.75-95.7v5.4l-4.65,2.7l-4.65-2.7v-5.4 M100.1-82.2v-5.4 M95.45-90.3l-4.65,2.7 M109.4-82.2
l-4.65,2.65 M104.75-90.3l4.65,2.7 M109.4-49.85l-4.65,2.65 M72.15-1.35v-5.4l4.7-2.7 M67.5,1.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7
M72.15-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M67.5-14.85v5.4 M53.55-1.35v-5.4l4.65-2.7l4.65,2.7 M48.9,1.35
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M44.25-22.9l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65V-22.9l-4.65-2.7V-31 M53.55-17.5
l4.65,2.65v5.4 M48.9-9.45v-5.4 M53.55-33.7v-5.4l4.65-2.7l4.65,2.7v5.4L58.2-31L53.55-33.7z M62.85-22.9l-4.65-2.7V-31 M48.9-25.6
V-31l4.65-2.7 M48.9-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M48.9-41.8v-5.4l4.65-2.65l4.65,2.65v5.4 M76.85-25.6V-31l4.65-2.7
M76.85-31l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7 M62.85-33.7L67.5-31v5.4 M72.15-39.1l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4
M62.85-39.1l4.65-2.7 M72.15-33.7L67.5-31 M53.55-22.9l4.65-2.7 M58.2-14.85l4.65-2.65 M30.3,1.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7
v5.4 M30.3-9.45v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M16.3-1.35v-5.4l4.65-2.7l4.65,2.7 M30.3-14.85l-4.7-2.65v-5.4l4.7-2.7
l4.65,2.7v5.4 M25.6-17.5l-4.65,2.65L16.3-17.5v-5.4l4.65-2.7l4.65,2.7 M20.95-14.85v5.4 M16.3-6.75l-4.65-2.7v-5.4l4.65-2.65
M2.35,1.35l-4.65-2.7v-5.4l4.65-2.7L7-6.75v5.4 M7-17.5l-4.65,2.65L-2.3-17.5v-5.4l4.65-2.7L7-22.9V-17.5l4.65,2.65 M11.65-9.45
L7-6.75 M2.35-9.45v-5.4 M11.65-31L7-33.7v-5.4l4.65-2.7l4.65,2.7v5.4L11.65-31z M16.3-22.9l-4.65-2.7V-31 M2.35-25.6V-31L7-33.7
M7-39.1l-4.65-2.7v-5.4L7-49.85l4.65,2.65v5.4 M44.25-33.7L39.6-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M20.95-25.6V-31l4.65-2.7
l4.7,2.7v5.4 M20.95-47.2l4.65-2.65l4.7,2.65v5.4l-4.7,2.7l-4.65-2.7V-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M30.3-47.2
l4.65-2.65l4.65,2.65v5.4 M30.3-41.8l4.65,2.7 M25.6-33.7v-5.4 M34.95-33.7L30.3-31 M34.95-22.9l4.65-2.7 M20.95-31l-4.65-2.7
M16.3-39.1l4.65-2.7 M7-22.9l4.65-2.7 M34.95-55.25l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L34.95-55.25v5.4 M25.6-49.85v-5.4
l4.7-2.7 M30.3-63.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7v5.4 M25.6-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M30.3-74.15
v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M20.95-63.35v5.4 M7-49.85v-5.4l4.65-2.7l4.65,2.7 M2.35-47.2l-4.65-2.65v-5.4l4.65-2.7
L7-55.25 M2.35-63.35l-4.65-2.7v-5.4l4.65-2.7L7-71.45v5.4L2.35-63.35z M16.3-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M11.65-57.95v-5.4l4.65-2.7 M2.35-57.95v-5.4 M7-66.05l4.65,2.7 M11.65-74.15L7-71.45 M2.35-74.15v-5.4L7-82.2l4.65,2.65
M11.65-95.7v5.4L7-87.6l-4.65-2.7v-5.4 M20.95-95.7v5.4l-4.65,2.7l-4.65-2.7 M7-87.6v5.4 M16.3-87.6v5.4 M20.95-90.3l4.65,2.7v5.4
l-4.65,2.65 M30.3-79.55l-4.7-2.65 M30.3-95.7v5.4l-4.7,2.7 M48.9-95.7v5.4l-4.65,2.7l-4.65-2.7v-5.4 M34.95-82.2v-5.4l4.65-2.7
M30.3-90.3l4.65,2.7 M72.15-49.85v-5.4l4.7-2.7l4.65,2.7 M67.5-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M67.5-74.15l4.65,2.7v5.4
l-4.65,2.7l-4.65-2.7v-5.4L67.5-74.15v-5.4l4.65-2.65l4.7,2.65 M81.5-66.05l-4.65,2.7l-4.7-2.7 M72.15-71.45l4.7-2.7 M76.85-63.35
v5.4 M67.5-57.95v-5.4 M53.55-49.85v-5.4l4.65-2.7l4.65,2.7 M48.9-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M44.25-66.05v-5.4
l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L44.25-66.05l-4.65,2.7 M62.85-66.05l-4.65,2.7l-4.65-2.7 M53.55-71.45l4.65-2.7l4.65,2.7
M58.2-57.95v-5.4 M48.9-57.95v-5.4 M48.9-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M48.9-79.55l-4.65-2.65v-5.4 M58.2-95.7v5.4
l-4.65,2.7l-4.65-2.7 M53.55-87.6v5.4 M58.2-79.55l4.65-2.65l4.65,2.65 M62.85-82.2v-5.4l4.65-2.7l4.65,2.7v5.4 M67.5-90.3v-5.4
M76.85-95.7v5.4l-4.7,2.7 M58.2-90.3l4.65,2.7 M44.25-17.5l-4.65,2.65 M39.6-9.45l4.65,2.7 M39.6-74.15l4.65,2.7 M39.6-57.95
l4.65,2.7 M44.25-49.85L39.6-47.2 M62.85-49.85L58.2-47.2 M16.3-49.85l-4.65,2.65 M44.25-82.2l-4.65,2.65 M76.85-90.3l4.65,2.7
M81.5-49.85l-4.65,2.65 M86.15,1.35l-4.65-2.7 M44.25-1.35l-4.65,2.7 M62.85-1.35l-4.65,2.7 M109.4-1.35l-4.65,2.7 M25.6-1.35
l-4.65,2.7 M-95.4,95.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-86.1,90.3l4.7-2.7l4.65,2.7v5.4 M-104.7,95.7v-5.4l4.65-2.7l4.65,2.7
M-100.05,82.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-100.05,82.2z M-95.4,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65
M-86.1,74.15l4.7-2.7l4.65,2.7v5.4l-4.65,2.65l-4.7-2.65 M-100.05,87.6v-5.4 M-90.75,87.6v-5.4 M-81.4,87.6v-5.4 M-109.35,87.6
l4.65,2.7 M-104.7,79.55l-4.65,2.65 M-109.35,55.25l4.65,2.7v5.4l-4.65,2.7 M-109.35,71.45l4.65,2.7 M-90.75,66.05l-4.65-2.7v-5.4
l4.65-2.7l4.65,2.7v5.4L-90.75,66.05v5.4 M-86.1,57.95l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7 M-81.4,71.45v-5.4 M-100.05,71.45
v-5.4l4.65-2.7 M-95.4,57.95l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-81.4,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-100.05,66.05l-4.65-2.7 M-104.7,57.95l4.65-2.7 M-86.1,41.8l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4L-86.1,41.8z M-81.4,49.85
l-4.7-2.65v-5.4 M-100.05,49.85l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-95.4,31l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7V31
l4.65,2.7 M-86.1,31v-5.4l4.7-2.7l4.65,2.7V31l-4.65,2.7 M-100.05,39.1v-5.4 M-90.75,39.1l-4.65,2.7 M-109.35,39.1l4.65,2.7
M-104.7,31l-4.65,2.7 M-109.35,6.75l4.65,2.7v5.4l-4.65,2.65 M-86.1,14.85v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.65L-86.1,14.85z
M-81.4,22.9v-5.4 M-86.1,25.6l-4.65-2.7v-5.4l4.65-2.65 M-100.05,22.9v-5.4l4.65-2.65l4.65,2.65 M-100.05,6.75v-5.4l4.65-2.7
l4.65,2.7v5.4l-4.65,2.7L-100.05,6.75z M-81.4,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-90.75,6.75l4.65,2.7 M-95.4,14.85v-5.4
M-95.4,25.6l4.65-2.7 M-100.05,17.5l-4.65-2.65 M-104.7,9.45l4.65-2.7 M-109.35,22.9l4.65,2.7 M-86.1,47.2l-4.65,2.65
M-104.7,47.2l-4.65,2.65 M-11.6,95.7v-5.4l4.65-2.7l4.65,2.7 M-20.9,95.7v-5.4l4.65-2.7l4.65,2.7 M-16.25,82.2l-4.65-2.65v-5.4
l4.65-2.7l4.65,2.7v5.4L-16.25,82.2v5.4 M-2.3,79.55l-4.65,2.65l-4.65-2.65 M-6.95,82.2v5.4 M-30.2,95.7v-5.4l4.65-2.7l4.65,2.7
M-39.55,95.7v-5.4l4.7-2.7l4.65,2.7 M-39.55,79.55v-5.4l4.7-2.7l4.65,2.7v5.4l-4.65,2.65L-39.55,79.55l-4.65,2.65l-4.65-2.65
M-20.9,79.55l-4.65,2.65l-4.65-2.65 M-34.85,87.6v-5.4 M-25.55,87.6v-5.4 M-20.9,74.15l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M-30.2,74.15l4.65-2.7 M-25.55,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-39.55,74.15l-4.65-2.7v-5.4l4.65-2.7l4.7,2.7v5.4
M-30.2,57.95l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-39.55,63.35v-5.4l4.7-2.7 M-30.2,63.35l-4.65,2.7 M-11.6,74.15l4.65-2.7
l4.65,2.7 M-6.95,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95,66.05v5.4 M-16.25,66.05l4.65-2.7 M-11.6,57.95l-4.65-2.7v-5.4
l4.65-2.65l4.65,2.65v5.4 M-16.25,55.25l-4.65,2.7 M-48.85,95.7v-5.4l4.65-2.7l4.65,2.7 M-58.15,95.7v-5.4l4.65-2.7l4.65,2.7
M-58.15,79.55v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-58.15,79.55l-4.65,2.65l-4.65-2.65 M-44.2,87.6v-5.4 M-53.5,87.6v-5.4
M-67.45,95.7v-5.4l4.65-2.7l4.65,2.7 M-76.75,90.3l4.65-2.7l4.65,2.7 M-76.75,74.15l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65
M-62.8,87.6v-5.4 M-72.1,87.6v-5.4 M-67.45,74.15l4.65-2.7l4.65,2.7 M-62.8,71.45v-5.4l4.65-2.7l4.65,2.7v5.4 M-62.8,66.05
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-76.75,63.35l4.65,2.7v5.4 M-62.8,55.25v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-67.45,63.35l-4.65,2.7 M-72.1,55.25l4.65,2.7 M-48.85,74.15l4.65-2.7 M-44.2,66.05l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7
M-53.5,49.85l4.65-2.65l4.65,2.65v5.4 M-53.5,66.05l4.65-2.7 M-53.5,55.25l4.65,2.7 M-48.85,47.2v-5.4l4.65-2.7l4.65,2.7v5.4
l-4.65,2.65 M-58.15,47.2v-5.4l4.65-2.7l4.65,2.7 M-58.15,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7V25.6l-4.65-2.7v-5.4
M-48.85,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7 M-44.2,39.1v-5.4 M-53.5,39.1v-5.4 M-62.8,49.85l-4.65-2.65v-5.4l4.65-2.7
l4.65,2.7 M-76.75,47.2v-5.4l4.65-2.7l4.65,2.7 M-76.75,25.6l4.65-2.7l4.65,2.7V31l-4.65,2.7l-4.65-2.7 M-58.15,31l-4.65,2.7
l-4.65-2.7 M-72.1,39.1v-5.4 M-62.8,39.1v-5.4 M-67.45,14.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-67.45,14.85l-4.65,2.65
l-4.65-2.65 M-72.1,22.9v-5.4 M-62.8,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-72.1,6.75l4.65,2.7 M-44.2,22.9v-5.4l4.65-2.65
l4.7,2.65v5.4l-4.7,2.7 M-44.2,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-48.85,14.85l-4.65,2.65l-4.65-2.65 M-53.5,22.9v-5.4
M-44.2,6.75v-5.4l4.65-2.7l4.7,2.7v5.4l-4.7,2.7 M-53.5,6.75l4.65,2.7 M-67.45,25.6l4.65-2.7 M-11.6,47.2v-5.4l4.65-2.7l4.65,2.7
M-11.6,41.8l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-16.25,33.7L-20.9,31v-5.4l4.65-2.7l4.65,2.7V31 M-2.3,31l-4.65,2.7
M-30.2,47.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-39.55,41.8l4.7-2.7l4.65,2.7 M-34.85,22.9l4.65,2.7V31l-4.65,2.7l-4.7-2.7
M-20.9,31l-4.65,2.7L-30.2,31 M-34.85,39.1v-5.4 M-25.55,39.1v-5.4 M-20.9,25.6l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M-25.55,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-25.55,6.75v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-30.2,14.85l-4.65,2.65
M-34.85,6.75l4.65,2.7 M-6.95,17.5l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95,17.5v5.4l-4.65,2.7 M-11.6,14.85l-4.65,2.65
M-16.25,6.75l4.65,2.7 M-16.25,1.35l4.65-2.7l4.65,2.7v5.4 M-6.95,22.9l4.65,2.7 M-30.2,25.6l4.65-2.7 M-16.25,39.1l-4.65,2.7
M-67.45,47.2l-4.65,2.65 M-2.3,47.2l-4.65,2.65 M-34.85,49.85l-4.7-2.65 M-16.25,49.85l-4.65-2.65 M-81.4,39.1l4.65,2.7
M-11.6-1.35v-5.4l4.65-2.7l4.65,2.7 M-11.6-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-16.25-14.85l-4.65-2.65v-5.4l4.65-2.7
l4.65,2.7v5.4 M-2.3-17.5l-4.65,2.65 M-20.9-1.35v-5.4l4.65-2.7 M-20.9-6.75l-4.65-2.7v-5.4l4.65-2.65 M-25.55-9.45l-4.65,2.7
l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65 M-30.2-6.75v5.4l-4.65,2.7 M-39.55-1.35v-5.4l4.7-2.7 M-34.85-14.85l-4.7-2.65v-5.4l4.7-2.7
l4.65,2.7v5.4 M-30.2-33.7v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7L-30.2-33.7l-4.65,2.7l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7 M-20.9-22.9
l-4.65-2.7V-31 M-34.85-25.6V-31 M-39.55-39.1l-4.65-2.7v-5.4l4.65-2.65l4.7,2.65v5.4 M-25.55-41.8v-5.4l4.65-2.65l4.65,2.65v5.4
l-4.65,2.7 M-6.95-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95-31v5.4l-4.65,2.7 M-16.25-25.6V-31l4.65-2.7 M-16.25-41.8
l4.65,2.7 M-16.25-47.2l4.65-2.65l4.65,2.65v5.4 M-30.2-22.9l4.65-2.7 M-16.25-31l-4.65-2.7 M-6.95-25.6l4.65,2.7 M-44.2,1.35
l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-58.15-1.35v-5.4l4.65-2.7l4.65,2.7 M-58.15-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4
M-62.8-14.85l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4 M-39.55-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-44.2-9.45v-5.4
M-53.5-14.85l4.65-2.65 M-62.8,1.35l-4.65-2.7v-5.4l4.65-2.7 M-76.75-6.75l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4L-76.75-6.75
v5.4 M-76.75-17.5v-5.4l4.65-2.7l4.65,2.7 M-67.45-17.5l-4.65,2.65 M-72.1-9.45l4.65,2.7 M-67.45-33.7v-5.4l4.65-2.7l4.65,2.7v5.4
L-62.8-31L-67.45-33.7z M-62.8-25.6V-31 M-72.1-25.6V-31l4.65-2.7 M-72.1-31l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-76.75-39.1
l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-62.8-41.8v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7 M-44.2-25.6V-31l4.65-2.7 M-44.2-31
l-4.65-2.7v-5.4l4.65-2.7 M-48.85-33.7L-53.5-31l-4.65-2.7 M-48.85-22.9l-4.65-2.7V-31 M-53.5-41.8l4.65,2.7 M-58.15-22.9l4.65-2.7
M-58.15-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-48.85-55.25l4.65-2.7l4.65,2.7v5.4 M-58.15-71.45l4.65-2.7l4.65,2.7v5.4
l-4.65,2.7l-4.65-2.7V-71.45z M-48.85-71.45l4.65-2.7l4.65,2.7v5.4l-4.65,2.7l-4.65-2.7 M-44.2-57.95v-5.4 M-53.5-57.95v-5.4
M-76.75-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-67.45-55.25l4.65-2.7l4.65,2.7 M-76.75-55.25l-4.65-2.7v-5.4l4.65-2.7
l4.65,2.7v5.4 M-81.4-63.35l-4.7-2.7v-5.4l4.7-2.7l4.65,2.7v5.4 M-81.4-74.15v-5.4l4.65-2.65l4.65,2.65v5.4l-4.65,2.7
M-58.15-66.05l-4.65,2.7l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-62.8-57.95v-5.4 M-72.1-74.15l4.65,2.7 M-67.45-66.05l-4.65,2.7
M-67.45-82.2v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65L-67.45-82.2l-4.65,2.65 M-76.75-82.2v-5.4l4.65-2.7l4.65,2.7 M-72.1-90.3
v-5.4 M-62.8-90.3v-5.4 M-53.5-74.15v-5.4l4.65-2.65l4.65,2.65v5.4 M-58.15-82.2l4.65,2.65 M-58.15-87.6l4.65-2.7l4.65,2.7v5.4
M-53.5-90.3v-5.4 M-44.2-95.7v5.4l-4.65,2.7 M-62.8-74.15v-5.4 M-11.6-49.85v-5.4l4.65-2.7l4.65,2.7 M-20.9-49.85v-5.4l4.65-2.7
l4.65,2.7 M-16.25-63.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4L-16.25-63.35v5.4 M-2.3-66.05l-4.65,2.7l-4.65-2.7 M-11.6-71.45
l4.65-2.7l4.65,2.7 M-6.95-63.35v5.4 M-25.55-47.2l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-39.55-55.25l4.7-2.7l4.65,2.7
M-39.55-71.45l4.7-2.7l4.65,2.7v5.4l-4.65,2.7l-4.7-2.7 M-20.9-71.45l-4.65-2.7v-5.4l4.65-2.65l4.65,2.65v5.4 M-20.9-66.05
l-4.65,2.7l-4.65-2.7 M-25.55-74.15l-4.65,2.7 M-34.85-63.35v5.4 M-25.55-57.95v-5.4 M-34.85-74.15v-5.4l4.65-2.65l4.65,2.65
M-44.2-79.55l4.65-2.65l4.7,2.65 M-39.55-82.2v-5.4l4.7-2.7l4.65,2.7v5.4 M-34.85-90.3v-5.4 M-16.25-95.7v5.4l-4.65,2.7l-4.65-2.7
v-5.4 M-25.55-90.3l-4.65,2.7 M-20.9-82.2v-5.4 M-6.95-79.55l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7v5.4L-6.95-79.55v5.4 M-16.25-79.55
l4.65-2.65 M-11.6-87.6l-4.65-2.7 M-6.95-95.7v5.4 M-44.2-90.3l4.65,2.7 M-62.8-47.2l-4.65-2.65 M-44.2-47.2l-4.65-2.65
M-30.2-49.85l-4.65,2.65 M-2.3-49.85l-4.65,2.65 M-95.4-1.35v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.7 M-86.1-6.75l4.7-2.7
M-100.05,1.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7 M-95.4-17.5l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7V-17.5z M-95.4-22.9
l4.65-2.7l4.65,2.7v5.4l-4.65,2.65l-4.65-2.65 M-81.4-14.85l-4.7-2.65 M-100.05-9.45v-5.4 M-90.75-14.85v5.4 M-109.35-9.45
l4.65,2.7 M-104.7-17.5l-4.65,2.65 M-109.35-41.8l4.65,2.7v5.4l-4.65,2.7 M-90.75-25.6V-31l4.65-2.7l4.7,2.7v5.4l-4.7,2.7
M-100.05-25.6V-31l4.65-2.7l4.65,2.7 M-100.05-47.2l4.65-2.65l4.65,2.65v5.4l-4.65,2.7l-4.65-2.7V-47.2l-4.65-2.65 M-90.75-41.8
l4.65,2.7v5.4 M-86.1-39.1l4.7-2.7 M-95.4-33.7v-5.4 M-109.35-25.6l4.65,2.7 M-100.05-31l-4.65-2.7 M-104.7-39.1l4.65-2.7
M-95.4-49.85v-5.4l4.65-2.7l4.65,2.7v5.4l-4.65,2.65 M-86.1-55.25l4.7-2.7 M-95.4-55.25l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4
M-100.05-63.35l-4.65-2.7v-5.4l4.65-2.7l4.65,2.7v5.4 M-95.4-71.45l4.65-2.7l4.65,2.7 M-86.1-66.05l-4.65,2.7 M-109.35-57.95
l4.65,2.7v5.4l-4.65,2.65 M-109.35-74.15l4.65,2.7 M-104.7-66.05l-4.65,2.7 M-109.35-90.3l4.65,2.7v5.4l-4.65,2.65 M-81.4-79.55
l-4.7-2.65v-5.4l4.7-2.7l4.65,2.7 M-86.1-82.2l-4.65,2.65l-4.65-2.65v-5.4l4.65-2.7l4.65,2.7 M-100.05-74.15v-5.4l4.65-2.65
M-95.4-87.6l-4.65-2.7v-5.4 M-81.4-95.7v5.4 M-90.75-95.7v5.4 M-90.75-79.55v5.4 M-104.7-55.25l4.65-2.7 M-100.05-79.55
l-4.65-2.65 M-104.7-87.6l4.65-2.7 M-81.4-47.2l-4.7-2.65 M-76.75-33.7L-81.4-31 M-81.4-25.6l4.65,2.7 M-67.45-1.35l-4.65,2.7
M-104.7-1.35l-4.65,2.7 M-81.4,1.35l-4.7-2.7 M-25.55,1.35l-4.65-2.7 M-53.5,1.35l4.65-2.7 M-2.3-1.35l-4.65,2.7 M-2.3,57.95
l4.65-2.7 M2.35,66.05l-4.65-2.7 M-2.3-39.1l4.65-2.7 M2.35-31l-4.65-2.7 M2.35-79.55L-2.3-82.2 M-2.3-87.6l4.65-2.7 M-2.3,9.45
l4.65-2.7 M2.35,17.5l-4.65-2.65"/>
</symbol>
<g id="Layer_1">
</g>
<g id="Layer_6">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#EFEEEE" d="M217.5,108.95c0,29.833-10.533,55.399-31.6,76.7
c-0.7,0.833-1.484,1.6-2.351,2.3c-3.466,3.399-7.134,6.483-11,9.25c-18.267,13.467-39.366,20.2-63.3,20.2
c-23.967,0-45.033-6.733-63.2-20.2c-4.8-3.4-9.3-7.25-13.5-11.55c-16.367-16.267-26.417-35.167-30.15-56.7
c-0.733-4.2-1.217-8.467-1.45-12.8c-0.1-2.4-0.15-4.801-0.15-7.2c0-2.534,0.05-4.95,0.15-7.25c0-0.233,0.066-0.467,0.2-0.7
c1.567-26.6,12.033-49.583,31.4-68.95C53.85,11.017,79.417,0.5,109.25,0.5c29.934,0,55.483,10.517,76.65,31.55
C206.967,53.483,217.5,79.117,217.5,108.95z"/>
</g>
<g id="Layer_5">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#010101" d="M195.45,43l-22.4,22.4c-8.833,13-13.25,27.867-13.25,44.6
c0,17.934,5.067,33.833,15.2,47.7l19,18.95c-2.5,3.066-5.2,6.066-8.1,9c-0.7,0.833-1.484,1.6-2.351,2.3
c-2.533,2.5-5.167,4.816-7.899,6.95L158.1,177.35c-13.934-10.733-30.133-16.1-48.6-16.1c-17.933,0-33.833,5.1-47.7,15.3
L43.25,195.15c-3.767-2.867-7.333-6.034-10.7-9.5c-2.8-2.801-5.417-5.667-7.85-8.601l19.15-19.2
c10.066-13.966,15.1-29.916,15.1-47.85c0-17.5-4.867-33.017-14.6-46.55l-21.05-21c2.833-3.6,5.917-7.067,9.25-10.4
c2.934-2.867,5.934-5.55,9-8.05L61.9,44.35C75.7,54.583,91.567,59.7,109.5,59.7c18.467,0,34.666-5.367,48.6-16.1L177.4,24.35
c2.899,2.367,5.732,4.933,8.5,7.7C189.367,35.583,192.55,39.233,195.45,43z"/>
</g>
<g id="Layer_4">
<defs>
<path id="SVGID_1_" d="M159.8,110c0-16.733,4.417-31.6,13.25-44.6l22.4-22.4c-2.9-3.767-6.083-7.417-9.55-10.95
c-2.768-2.767-5.601-5.333-8.5-7.7L158.1,43.6c-13.934,10.733-30.133,16.1-48.6,16.1c-17.933,0-33.8-5.117-47.6-15.35L41.55,24
c-3.066,2.5-6.066,5.183-9,8.05c-3.333,3.333-6.417,6.8-9.25,10.4l21.05,21c9.733,13.533,14.6,29.05,14.6,46.55
c0,17.934-5.034,33.884-15.1,47.85l-19.15,19.2c2.433,2.934,5.05,5.8,7.85,8.601c3.367,3.466,6.934,6.633,10.7,9.5L61.8,176.55
c13.867-10.2,29.767-15.3,47.7-15.3c18.467,0,34.666,5.366,48.6,16.1L175.65,194.9c2.732-2.134,5.366-4.45,7.899-6.95
c0.866-0.7,1.65-1.467,2.351-2.3c2.899-2.934,5.6-5.934,8.1-9l-19-18.95C164.867,143.833,159.8,127.934,159.8,110z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<use xlink:href="#hex_grid" width="228.55" height="197.233" x="-114.25" y="-98.617" transform="matrix(1.1415 0 0 -1.1415 105.5 107.75)" overflow="visible"/>
</g>
</g>
<g id="Layer_2">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#35C6F4" d="M79.1,110.95c-0.033-0.667-0.05-1.333-0.05-2
c0-0.7,0.017-1.366,0.05-2c0-0.067,0.017-0.134,0.05-0.2c0.434-7.367,3.333-13.733,8.7-19.1c5.9-5.833,12.983-8.75,21.25-8.75
c8.301,0,15.384,2.917,21.25,8.75c5.834,5.934,8.75,13.033,8.75,21.3c0,8.267-2.916,15.35-8.75,21.25
c-0.199,0.233-0.416,0.45-0.649,0.649c-0.967,0.934-1.983,1.784-3.05,2.551c-5.066,3.733-10.917,5.6-17.551,5.6
c-6.633,0-12.466-1.866-17.5-5.6c-1.333-0.934-2.583-2-3.75-3.2c-4.533-4.5-7.317-9.733-8.35-15.7
C79.3,113.334,79.167,112.15,79.1,110.95z M126.1,127.25l3.601,3.6L126.1,127.25z"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#35C6F4" stroke-width="2" stroke-miterlimit="1" d="
M158.6,60.25l-15,14.65 M31.7,33.1l40.75,40.65 M126.1,127.25l3.601,3.6 M157.05,158l27.65,28.6 M153.05,153.95l-10.75-11.2
M186.6,33l-28,27.25 M33.15,186.25l27.35-27.4"/>
<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#35C6F4" stroke-width="7" stroke-miterlimit="1" d="
M158.6,60.25l-16.949,17.2 M59.4,61.35L76.6,78.5 M60.5,158.85l16.75-17.399 M153.05,153.95l4,4.05 M139.45,140.4l13.6,13.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

View File

@@ -1,38 +0,0 @@
version: '0.2.0.{build}'
branches:
only:
- develop
assembly_info:
patch: true
file: 'src\NzbDrone.Common\Properties\SharedAssemblyInfo.cs'
assembly_version: '{version}'
assembly_file_version: '{version}'
assembly_informational_version: '{version}-rc1'
environment:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
install:
- git submodule update --init --recursive
build_script:
- ps: ./build-appveyor.ps1
test: off
# test:
# assemblies:
# - '_tests\*Test.dll'
# categories:
# except:
# - IntegrationTest
# - AutomationTest
artifacts:
- path: '_artifacts\*.zip'
- path: '_artifacts\*.tar.gz'
cache:
- '%USERPROFILE%\.nuget\packages'
- node_modules

View File

@@ -1,303 +0,0 @@
#addin "Cake.Npm"
#addin "SharpZipLib"
#addin "Cake.Compression"
// Build variables
var outputFolder = "./_output";
var outputFolderMono = outputFolder + "_mono";
var outputFolderOsx = outputFolder + "_osx";
var outputFolderOsxApp = outputFolderOsx + "_app";
var testPackageFolder = "./_tests";
var testSearchPattern = "*.Test/bin/x86/Release";
var sourceFolder = "./src";
var solutionFile = sourceFolder + "/NzbDrone.sln";
var updateFolder = outputFolder + "/NzbDrone.Update";
var updateFolderMono = outputFolderMono + "/NzbDrone.Update";
// Artifact variables
var artifactsFolder = "./_artifacts";
var artifactsFolderWindows = artifactsFolder + "/windows";
var artifactsFolderLinux = artifactsFolder + "/linux";
var artifactsFolderOsx = artifactsFolder + "/osx";
var artifactsFolderOsxApp = artifactsFolder + "/osx-app";
// Utility methods
public void RemoveEmptyFolders(string startLocation) {
foreach (var directory in System.IO.Directory.GetDirectories(startLocation))
{
RemoveEmptyFolders(directory);
if (System.IO.Directory.GetFiles(directory).Length == 0 &&
System.IO.Directory.GetDirectories(directory).Length == 0)
{
DeleteDirectory(directory, false);
}
}
}
public void CleanFolder(string path, bool keepConfigFiles) {
DeleteFiles(path + "/**/*.transform");
if (!keepConfigFiles) {
DeleteFiles(path + "/**/*.dll.config");
}
DeleteFiles(path + "/**/FluentValidation.resources.dll");
DeleteFiles(path + "/**/App.config");
DeleteFiles(path + "/**/*.less");
DeleteFiles(path + "/**/*.vshost.exe");
DeleteFiles(path + "/**/*.dylib");
RemoveEmptyFolders(path);
}
public void CreateMdbs(string path) {
foreach (var file in System.IO.Directory.EnumerateFiles(path, "*.pdb", System.IO.SearchOption.AllDirectories)) {
var actualFile = file.Substring(0, file.Length - 4);
if (FileExists(actualFile + ".exe")) {
StartProcess("./tools/pdb2mdb/pdb2mdb.exe", new ProcessSettings()
.WithArguments(args => args.Append(actualFile + ".exe")));
}
if (FileExists(actualFile + ".dll")) {
StartProcess("./tools/pdb2mdb/pdb2mdb.exe", new ProcessSettings()
.WithArguments(args => args.Append(actualFile + ".dll")));
}
}
}
// Build Tasks
Task("Compile").Does(() => {
// Build
if (DirectoryExists(outputFolder)) {
DeleteDirectory(outputFolder, true);
}
MSBuild(solutionFile, config =>
config.UseToolVersion(MSBuildToolVersion.VS2015)
.WithTarget("Clean")
.SetVerbosity(Verbosity.Minimal));
NuGetRestore(solutionFile);
MSBuild(solutionFile, config =>
config.UseToolVersion(MSBuildToolVersion.VS2015)
.SetPlatformTarget(PlatformTarget.x86)
.SetConfiguration("Release")
.WithProperty("AllowedReferenceRelatedFileExtensions", new string[] { ".pdb" })
.WithTarget("Build")
.SetVerbosity(Verbosity.Minimal));
CleanFolder(outputFolder, false);
// Add JsonNet
DeleteFiles(outputFolder + "/Newtonsoft.Json.*");
CopyFiles(sourceFolder + "/packages/Newtonsoft.Json.*/lib/net35/*.dll", outputFolder);
CopyFiles(sourceFolder + "/packages/Newtonsoft.Json.*/lib/net35/*.dll", updateFolder);
// Remove Mono stuff
DeleteFile(outputFolder + "/Mono.Posix.dll");
});
Task("Gulp").Does(() => {
Npm
.WithLogLevel(NpmLogLevel.Silent)
.FromPath(".")
.Install()
.RunScript("build");
});
Task("PackageMono").Does(() => {
// Start mono package
if (DirectoryExists(outputFolderMono)) {
DeleteDirectory(outputFolderMono, true);
}
CopyDirectory(outputFolder, outputFolderMono);
// Create MDBs
CreateMdbs(outputFolderMono);
// Remove PDBs
DeleteFiles(outputFolderMono + "/**/*.pdb");
// Remove service helpers
DeleteFiles(outputFolderMono + "/ServiceUninstall.*");
DeleteFiles(outputFolderMono + "/ServiceInstall.*");
// Remove native windows binaries
DeleteFiles(outputFolderMono + "/sqlite3.*");
DeleteFiles(outputFolderMono + "/MediaInfo.*");
// Adding NzbDrone.Core.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Core/NzbDrone.Core.dll.config", outputFolderMono + "/NzbDrone.Core.dll.config");
// Adding CurlSharp.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Common/CurlSharp.dll.config", outputFolderMono + "/CurlSharp.dll.config");
// Renaming Radarr.Console.exe to Radarr.exe
DeleteFiles(outputFolderMono + "/Radarr.exe*");
MoveFile(outputFolderMono + "/Radarr.Console.exe", outputFolderMono + "/Radarr.exe");
MoveFile(outputFolderMono + "/Radarr.Console.exe.config", outputFolderMono + "/Radarr.exe.config");
MoveFile(outputFolderMono + "/Radarr.Console.exe.mdb", outputFolderMono + "/Radarr.exe.mdb");
// Remove NzbDrone.Windows.*
DeleteFiles(outputFolderMono + "/NzbDrone.Windows.*");
// Adding NzbDrone.Mono to updatePackage
CopyFiles(outputFolderMono + "/NzbDrone.Mono.*", updateFolderMono);
});
Task("PackageOsx").Does(() => {
// Start osx package
if (DirectoryExists(outputFolderOsx)) {
DeleteDirectory(outputFolderOsx, true);
}
CopyDirectory(outputFolderMono, outputFolderOsx);
// Adding sqlite dylibs
CopyFiles(sourceFolder + "/Libraries/Sqlite/*.dylib", outputFolderOsx);
// Adding MediaInfo dylib
CopyFiles(sourceFolder + "/Libraries/MediaInfo/*.dylib", outputFolderOsx);
// Adding Startup script
CopyFile("./osx/Sonarr", outputFolderOsx + "/Sonarr");
});
Task("PackageOsxApp").Does(() => {
// Start osx app package
if (DirectoryExists(outputFolderOsxApp)) {
DeleteDirectory(outputFolderOsxApp, true);
}
CreateDirectory(outputFolderOsxApp);
// Copy osx package files
CopyDirectory("./osx/Radarr.app", outputFolderOsxApp + "/Radarr.app");
CopyDirectory(outputFolderOsx, outputFolderOsxApp + "/Radarr.app/Contents/MacOS");
});
Task("PackageTests").Does(() => {
// Start tests package
if (DirectoryExists(testPackageFolder)) {
DeleteDirectory(testPackageFolder, true);
}
CreateDirectory(testPackageFolder);
// Copy tests
CopyFiles(sourceFolder + "/" + testSearchPattern + "/*", testPackageFolder);
foreach (var directory in System.IO.Directory.GetDirectories(sourceFolder, "*.Test")) {
var releaseDirectory = directory + "/bin/x86/Release";
if (DirectoryExists(releaseDirectory)) {
foreach (var releaseSubDirectory in System.IO.Directory.GetDirectories(releaseDirectory)) {
Information(System.IO.Path.GetDirectoryName(releaseSubDirectory));
CopyDirectory(releaseSubDirectory, testPackageFolder + "/" + System.IO.Path.GetFileName(releaseSubDirectory));
}
}
}
// Install NUnit.ConsoleRunner
NuGetInstall("NUnit.ConsoleRunner", new NuGetInstallSettings {
Version = "3.2.0",
OutputDirectory = testPackageFolder
});
// Copy dlls
CopyFiles(outputFolder + "/*.dll", testPackageFolder);
// Copy scripts
CopyFiles("./*.sh", testPackageFolder);
// Create MDBs for tests
CreateMdbs(testPackageFolder);
// Remove config
DeleteFiles(testPackageFolder + "/*.log.config");
// Clean
CleanFolder(testPackageFolder, true);
// Adding NzbDrone.Core.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Core/NzbDrone.Core.dll.config", testPackageFolder + "/NzbDrone.Core.dll.config");
// Adding CurlSharp.dll.config (for dllmap)
CopyFile(sourceFolder + "/NzbDrone.Common/CurlSharp.dll.config", testPackageFolder + "/CurlSharp.dll.config");
// Adding CurlSharp libraries
CopyFiles(sourceFolder + "/ExternalModules/CurlSharp/libs/i386/*", testPackageFolder);
});
Task("CleanupWindowsPackage").Does(() => {
// Remove mono
DeleteFiles(outputFolder + "/NzbDrone.Mono.*");
// Adding NzbDrone.Windows to updatePackage
CopyFiles(outputFolder + "/NzbDrone.Windows.*", updateFolder);
});
Task("Build")
.IsDependentOn("Compile")
.IsDependentOn("Gulp")
.IsDependentOn("PackageMono")
.IsDependentOn("PackageOsx")
.IsDependentOn("PackageOsxApp")
.IsDependentOn("PackageTests")
.IsDependentOn("CleanupWindowsPackage");
// Build Artifacts
Task("CleanArtifacts").Does(() => {
if (DirectoryExists(artifactsFolder)) {
DeleteDirectory(artifactsFolder, true);
}
CreateDirectory(artifactsFolder);
});
Task("ArtifactsWindows").Does(() => {
CopyDirectory(outputFolder, artifactsFolderWindows + "/Radarr");
});
Task("ArtifactsLinux").Does(() => {
CopyDirectory(outputFolderMono, artifactsFolderLinux + "/Radarr");
});
Task("ArtifactsOsx").Does(() => {
CopyDirectory(outputFolderOsx, artifactsFolderOsx + "/Radarr");
});
Task("ArtifactsOsxApp").Does(() => {
CopyDirectory(outputFolderOsxApp, artifactsFolderOsxApp);
});
Task("CompressArtifacts").Does(() => {
var prefix = "";
if (AppVeyor.IsRunningOnAppVeyor) {
prefix += AppVeyor.Environment.Repository.Branch + ".";
prefix += AppVeyor.Environment.Build.Version + ".";
}
Zip(artifactsFolderWindows, artifactsFolder + "/Radarr." + prefix + "windows.zip");
GZipCompress(artifactsFolderLinux, artifactsFolder + "/Radarr." + prefix + "linux.tar.gz");
GZipCompress(artifactsFolderOsx, artifactsFolder + "/Radarr." + prefix + "osx.tar.gz");
Zip(artifactsFolderOsxApp, artifactsFolder + "/Radarr." + prefix + "osx-app.zip");
});
Task("Artifacts")
.IsDependentOn("CleanArtifacts")
.IsDependentOn("ArtifactsWindows")
.IsDependentOn("ArtifactsLinux")
.IsDependentOn("ArtifactsOsx")
.IsDependentOn("ArtifactsOsxApp")
.IsDependentOn("CompressArtifacts");
// Run
RunTarget("Build");
RunTarget("Artifacts");

View File

@@ -1,184 +0,0 @@
##########################################################################
# This is the Cake bootstrapper script for PowerShell.
# This file was downloaded from https://github.com/cake-build/resources
# Feel free to change this file to fit your needs.
##########################################################################
<#
.SYNOPSIS
This is a Powershell script to bootstrap a Cake build.
.DESCRIPTION
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
and execute your Cake build script with the parameters you provide.
.PARAMETER Script
The build script to execute.
.PARAMETER Target
The build script target to run.
.PARAMETER Configuration
The build configuration to use.
.PARAMETER Verbosity
Specifies the amount of information to be displayed.
.PARAMETER Experimental
Tells Cake to use the latest Roslyn release.
.PARAMETER WhatIf
Performs a dry run of the build script.
No tasks will be executed.
.PARAMETER Mono
Tells Cake to use the Mono scripting engine.
.PARAMETER SkipToolPackageRestore
Skips restoring of packages.
.PARAMETER ScriptArgs
Remaining arguments are added here.
.LINK
http://cakebuild.net
#>
[CmdletBinding()]
Param(
[string]$Script = "build-appveyor.cake",
[string]$Target = "Default",
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
[string]$Verbosity = "Verbose",
[switch]$Experimental,
[Alias("DryRun","Noop")]
[switch]$WhatIf,
[switch]$Mono,
[switch]$SkipToolPackageRestore,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$ScriptArgs
)
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
function MD5HashFile([string] $filePath)
{
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
{
return $null
}
[System.IO.Stream] $file = $null;
[System.Security.Cryptography.MD5] $md5 = $null;
try
{
$md5 = [System.Security.Cryptography.MD5]::Create()
$file = [System.IO.File]::OpenRead($filePath)
return [System.BitConverter]::ToString($md5.ComputeHash($file))
}
finally
{
if ($file -ne $null)
{
$file.Dispose()
}
}
}
Write-Host "Preparing to run build script..."
if(!$PSScriptRoot){
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
$TOOLS_DIR = Join-Path $PSScriptRoot "tools-cake"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
# Should we use mono?
$UseMono = "";
if($Mono.IsPresent) {
Write-Verbose -Message "Using the Mono based scripting engine."
$UseMono = "-mono"
}
# Should we use the new Roslyn?
$UseExperimental = "";
if($Experimental.IsPresent -and !($Mono.IsPresent)) {
Write-Verbose -Message "Using experimental version of Roslyn."
$UseExperimental = "-experimental"
}
# Is this a dry run?
$UseDryRun = "";
if($WhatIf.IsPresent) {
$UseDryRun = "-dryrun"
}
# Make sure tools folder exists
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
Write-Verbose -Message "Creating tools directory..."
New-Item -Path $TOOLS_DIR -Type directory | out-null
}
# Make sure that packages.config exist.
if (!(Test-Path $PACKAGES_CONFIG)) {
Write-Verbose -Message "Downloading packages.config..."
try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
Throw "Could not download packages.config."
}
}
# Try find NuGet.exe in path if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
}
}
# Try download NuGet.exe if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Downloading NuGet.exe..."
try {
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
} catch {
Throw "Could not download NuGet.exe."
}
}
# Save nuget.exe path to environment to be available to child processed
$ENV:NUGET_EXE = $NUGET_EXE
# Restore tools from NuGet?
if(-Not $SkipToolPackageRestore.IsPresent) {
Push-Location
Set-Location $TOOLS_DIR
# Check for changes in packages.config and remove installed tools if true.
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..."
Remove-Item * -Recurse -Exclude packages.config,nuget.exe
}
Write-Verbose -Message "Restoring tools from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occured while restoring NuGet tools."
}
else
{
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Make sure that Cake has been installed.
if (!(Test-Path $CAKE_EXE)) {
Throw "Could not find Cake.exe at $CAKE_EXE"
}
# Start Cake
Write-Host "Running build script..."
Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
exit $LASTEXITCODE

View File

@@ -154,8 +154,8 @@ PackageMono()
cp $sourceFolder/NzbDrone.Common/CurlSharp.dll.config $outputFolderMono
echo "Renaming NzbDrone.Console.exe to NzbDrone.exe"
rm $outputFolderMono/Radarr.exe*
for file in $outputFolderMono/Radarr.Console.exe*; do
rm $outputFolderMono/NzbDrone.exe*
for file in $outputFolderMono/NzbDrone.Console.exe*; do
mv "$file" "${file//.Console/}"
done
@@ -192,8 +192,8 @@ PackageOsxApp()
rm -rf $outputFolderOsxApp
mkdir $outputFolderOsxApp
cp -r ./osx/Radarr.app $outputFolderOsxApp
cp -r $outputFolderOsx $outputFolderOsxApp/Radarr.app/Contents/MacOS
cp -r ./osx/Sonarr.app $outputFolderOsxApp
cp -r $outputFolderOsx $outputFolderOsxApp/Sonarr.app/Contents/MacOS
echo "##teamcity[progressFinish 'Creating OS X App Package']"
}

View File

@@ -19,16 +19,13 @@ gulp.task('less', function() {
paths.src.root + 'Series/series.less',
paths.src.root + 'Activity/activity.less',
paths.src.root + 'AddSeries/addSeries.less',
paths.src.root + 'AddMovies/addMovies.less',
paths.src.root + 'Calendar/calendar.less',
paths.src.root + 'Cells/cells.less',
paths.src.root + 'ManualImport/manualimport.less',
paths.src.root + 'Settings/settings.less',
paths.src.root + 'System/Logs/logs.less',
paths.src.root + 'System/Update/update.less',
paths.src.root + 'System/Info/info.less',
paths.src.root + 'Movies/movies.less',
paths.src.root + 'System/Info/info.less'
];
return gulp.src(src)

View File

@@ -4,9 +4,9 @@
DIR=$(cd "$(dirname "$0")"; pwd)
#change these values to match your app
EXE_PATH="$DIR/Radarr.exe"
EXE_PATH="$DIR/NzbDrone.exe"
APPNAME="Sonarr"
#set up environment
if [[ -x '/opt/local/bin/mono' ]]; then
export PATH="/opt/local/bin:$PATH"
@@ -29,11 +29,11 @@ export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$HOME/lib:/usr/lo
#mono version check
REQUIRED_MAJOR=3
REQUIRED_MINOR=10
VERSION_TITLE="Cannot launch $APPNAME"
VERSION_MSG="$APPNAME requires Mono Runtime Environment(MRE) $REQUIRED_MAJOR.$REQUIRED_MINOR or later."
DOWNLOAD_URL="http://www.mono-project.com/download/#download-mac"
MONO_VERSION="$(mono --version | grep 'Mono JIT compiler version ' | cut -f5 -d\ )"
# if [[ -o DEBUG ]]; then osascript -e "display dialog \"MONO_VERSION: $MONO_VERSION\""; fi
@@ -42,7 +42,7 @@ MONO_VERSION_MAJOR="$(echo $MONO_VERSION | cut -f1 -d.)"
MONO_VERSION_MINOR="$(echo $MONO_VERSION | cut -f2 -d.)"
if [ -z "$MONO_VERSION" ] \
|| [ $MONO_VERSION_MAJOR -lt $REQUIRED_MAJOR ] \
|| [ $MONO_VERSION_MAJOR -eq $REQUIRED_MAJOR -a $MONO_VERSION_MINOR -lt $REQUIRED_MINOR ]
|| [ $MONO_VERSION_MAJOR -eq $REQUIRED_MAJOR -a $MONO_VERSION_MINOR -lt $REQUIRED_MINOR ]
then
osascript \
-e "set question to display dialog \"$VERSION_MSG\" with title \"$VERSION_TITLE\" buttons {\"Cancel\", \"Download...\"} default button 2" \
@@ -51,8 +51,8 @@ then
echo "$VERSION_MSG"
exit 1
fi
MONO_EXEC="exec mono --debug"
#run app using mono
$MONO_EXEC "$EXE_PATH"
$MONO_EXEC "$EXE_PATH"

View File

@@ -13,7 +13,7 @@
<key>CFBundleExecutable</key>
<string>Sonarr</string>
<key>CFBundleIconFile</key>
<string>radarr.icns</string>
<string>sonarr.icns</string>
<key>CFBundleIdentifier</key>
<string>com.osx.sonarr.tv</string>
<key>CFBundleInfoDictionaryVersion</key>

View File

@@ -1,68 +0,0 @@
if [ $# -eq 0 ]; then
if [ "$TRAVIS_PULL_REQUEST" != false ]; then
echo "Need to supply version argument" && exit;
fi
fi
# Use mono or .net depending on OS
case "$(uname -s)" in
CYGWIN*|MINGW32*|MINGW64*|MSYS*)
# on windows, use dotnet
runtime="dotnet"
;;
*)
# otherwise use mono
runtime="mono"
;;
esac
if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
VERSION="`date +%H:%M:%S`"
YEAR="`date +%Y`"
MONTH="`date +%m`"
DAY="`date +%d`"
else
VERSION=$1
fi
outputFolder='./_output'
outputFolderMono='./_output_mono'
outputFolderOsx='./_output_osx'
outputFolderOsxApp='./_output_osx_app'
tr -d "\r" < $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr > $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2
rm $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr
chmod +x $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2
mv $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2 $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr >& error.log
cp -r $outputFolder/ Radarr_Windows_$VERSION
cp -r $outputFolderMono/ Radarr_Mono_$VERSION
cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION
if [ $runtime = "dotnet" ] ; then
./7za.exe a Radarr_Windows_$VERSION.zip ./Radarr_Windows_$VERSION/*
./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar ./Radarr_Mono_$VERSION/* | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz
./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar ./_output_osx/* | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz
./7za.exe a -ttar -so Radarr_OSX_App_$VERSION.tar ./_output_osx_app/* | ./7za.exe a -si Radarr_OSX_App_$VERSION.tar.gz
else
zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION/* >& /dev/null
zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION/* >& /dev/null #TODO update for tar.gz
zip -r Radarr_OSX_$VERSION_App.zip Radarr_OSX_$VERSION/* >& /dev/null
fi
ftp -n ftp.leonardogalli.ch << END_SCRIPT
passive
quote USER $FTP_USER
quote PASS $FTP_PASS
mkdir builds
cd builds
mkdir $YEAR
cd $YEAR
mkdir $MONTH
cd $MONTH
mkdir $DAY
cd $DAY
binary
put Radarr_Windows_$VERSION.zip
put Radarr_Mono_$VERSION.zip
put Radarr_OSX_$VERSION.zip
quit
END_SCRIPT

View File

@@ -1,45 +1,27 @@
# Radarr [![Build Status](https://travis-ci.org/galli-leo/Radarr.svg?branch=develop)](https://travis-ci.org/galli-leo/Radarr)#
# Sonarr #
This fork of Sonarr aims to turn it into something like Couchpotato.
## Currently working:
* Adding new movies
* Manually searching for releases of movies.
* Automatically searching for releases.
* Automatically importing downloaded movies.
* Recognizing Special Editions, Director's Cut, etc.
* Identifying releases with hardcoded subs.
* Rarbg.to, Torznab and Newznab Indexer.
* QBittorrent and Deluge download client (Other clients are coming)
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
## Planned Features:
* Scanning PreDB to know when a new release is available.
* Fixing the other Indexers and download clients.
* Importing of Sonarr config.
## Download
The latest precompiled binary versions can be found here: https://github.com/galli-leo/Radarr/releases.
For more up to date versions (but also sometimes broken), daily builds can be found here:
* [OSX](https://leonardogalli.ch/radarr/builds/latest.php?os=osx)
* [Windows](https://leonardogalli.ch/radarr/builds/latest.php?os=windows)
* [Linux](https://leonardogalli.ch/radarr/builds/latest.php?os=mono)
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
## Major Features Include: ##
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
* Can watch for better quality of the movies you have and do an upgrade.
* Automatically detects new episodes
* Can scan your existing library and download any missing episodes
* Can watch for better quality of the episodes you already have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
* Automatic failed download handling will try another release if one fails
* Manual search so you can pick any release or to see why a release was not downloaded automatically.
* Full integration with SABNzbd and NzbGet.
* Full integration with XBMC, Plex (notification, library update, metadata).
* Manual search so you can pick any release or to see why a release was not downloaded automatically
* Fully configurable episode renaming
* Full integration with SABNzbd and NzbGet
* Full integration with XBMC, Plex (notification, library update, metadata)
* Full support for specials and multi-episode releases
* And a beautiful UI
## Configuring Development Environment: ##
### Requirements ###
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) or Mono
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
- [Git](http://git-scm.com/downloads)
- [NodeJS](http://nodejs.org/download/)
@@ -55,7 +37,7 @@ For more up to date versions (but also sometimes broken), daily builds can be fo
### Development ###
- Open `NzbDrone.sln` in Visual Studio or run the build.sh script, if Mono is installed.
- Open `NzbDrone.sln` in Visual Studio
- Make sure `NzbDrone.Console` is set as the startup project

Binary file not shown.

View File

@@ -2,4 +2,4 @@
using System.Reflection;
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: AssemblyVersion("10.0.0.*")]

View File

@@ -21,3 +21,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("260b2ff9-d3b7-4d8a-b720-a12c93d045e5")]
[assembly: AssemblyVersion("10.0.0.*")]

View File

@@ -39,8 +39,6 @@ namespace NzbDrone.Api.Config
SharedValidator.RuleFor(c => c.AnimeEpisodeFormat).ValidAnimeEpisodeFormat();
SharedValidator.RuleFor(c => c.SeriesFolderFormat).ValidSeriesFolderFormat();
SharedValidator.RuleFor(c => c.SeasonFolderFormat).ValidSeasonFolderFormat();
SharedValidator.RuleFor(c => c.StandardMovieFormat).ValidMovieFormat();
SharedValidator.RuleFor(c => c.MovieFolderFormat).ValidMovieFolderFormat();
}
private void UpdateNamingConfig(NamingConfigResource resource)
@@ -56,13 +54,7 @@ namespace NzbDrone.Api.Config
var nameSpec = _namingConfigService.GetConfig();
var resource = nameSpec.ToResource();
//if (resource.StandardEpisodeFormat.IsNotNullOrWhiteSpace())
//{
// var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
// basicConfig.AddToResource(resource);
//}
if (resource.StandardMovieFormat.IsNotNullOrWhiteSpace())
if (resource.StandardEpisodeFormat.IsNotNullOrWhiteSpace())
{
var basicConfig = _filenameBuilder.GetBasicNamingConfig(nameSpec);
basicConfig.AddToResource(resource);
@@ -81,50 +73,39 @@ namespace NzbDrone.Api.Config
var nameSpec = config.ToModel();
var sampleResource = new NamingSampleResource();
//var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
//var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
//var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
//var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
//var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
? "Invalid format"
: singleEpisodeSampleResult.FileName;
//sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
// ? "Invalid format"
// : singleEpisodeSampleResult.FileName;
sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null
? "Invalid format"
: multiEpisodeSampleResult.FileName;
//sampleResource.MultiEpisodeExample = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult) != null
// ? "Invalid format"
// : multiEpisodeSampleResult.FileName;
sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null
? "Invalid format"
: dailyEpisodeSampleResult.FileName;
//sampleResource.DailyEpisodeExample = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult) != null
// ? "Invalid format"
// : dailyEpisodeSampleResult.FileName;
sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null
? "Invalid format"
: animeEpisodeSampleResult.FileName;
//sampleResource.AnimeEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult) != null
// ? "Invalid format"
// : animeEpisodeSampleResult.FileName;
sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null
? "Invalid format"
: animeMultiEpisodeSampleResult.FileName;
//sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null
// ? "Invalid format"
// : animeMultiEpisodeSampleResult.FileName;
sampleResource.MovieExample = nameSpec.StandardMovieFormat.IsNullOrWhiteSpace()
? "Invalid Format"
: movieSampleResult.FileName;
//sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace()
// ? "Invalid format"
// : _filenameSampleService.GetSeriesFolderSample(nameSpec);
//sampleResource.SeasonFolderExample = nameSpec.SeasonFolderFormat.IsNullOrWhiteSpace()
// ? "Invalid format"
// : _filenameSampleService.GetSeasonFolderSample(nameSpec);
sampleResource.MovieFolderExample = nameSpec.MovieFolderFormat.IsNullOrWhiteSpace()
sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace()
? "Invalid format"
: _filenameSampleService.GetMovieFolderSample(nameSpec);
: _filenameSampleService.GetSeriesFolderSample(nameSpec);
sampleResource.SeasonFolderExample = nameSpec.SeasonFolderFormat.IsNullOrWhiteSpace()
? "Invalid format"
: _filenameSampleService.GetSeasonFolderSample(nameSpec);
return sampleResource.AsResponse();
}
@@ -137,25 +118,19 @@ namespace NzbDrone.Api.Config
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
var movieSampleResult = _filenameSampleService.GetMovieSample(nameSpec);
var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult);
var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult);
var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult);
var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult);
var animeMultiEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult);
//var standardMovieValidationResult = _filenameValidationService.ValidateMovieFilename(movieSampleResult); For now, let's hope the user is not stupid enough :/
var validationFailures = new List<ValidationFailure>();
//validationFailures.AddIfNotNull(singleEpisodeValidationResult);
//validationFailures.AddIfNotNull(multiEpisodeValidationResult);
//validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
//validationFailures.AddIfNotNull(animeEpisodeValidationResult);
//validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
//validationFailures.AddIfNotNull(standardMovieValidationResult);
validationFailures.AddIfNotNull(singleEpisodeValidationResult);
validationFailures.AddIfNotNull(multiEpisodeValidationResult);
validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
validationFailures.AddIfNotNull(animeEpisodeValidationResult);
validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
if (validationFailures.Any())
{

View File

@@ -7,8 +7,6 @@ namespace NzbDrone.Api.Config
{
public bool RenameEpisodes { get; set; }
public bool ReplaceIllegalCharacters { get; set; }
public string StandardMovieFormat { get; set; }
public string MovieFolderFormat { get; set; }
public int MultiEpisodeStyle { get; set; }
public string StandardEpisodeFormat { get; set; }
public string DailyEpisodeFormat { get; set; }
@@ -38,9 +36,7 @@ namespace NzbDrone.Api.Config
DailyEpisodeFormat = model.DailyEpisodeFormat,
AnimeEpisodeFormat = model.AnimeEpisodeFormat,
SeriesFolderFormat = model.SeriesFolderFormat,
SeasonFolderFormat = model.SeasonFolderFormat,
StandardMovieFormat = model.StandardMovieFormat,
MovieFolderFormat = model.MovieFolderFormat
SeasonFolderFormat = model.SeasonFolderFormat
//IncludeSeriesTitle
//IncludeEpisodeTitle
//IncludeQuality
@@ -68,14 +64,12 @@ namespace NzbDrone.Api.Config
RenameEpisodes = resource.RenameEpisodes,
ReplaceIllegalCharacters = resource.ReplaceIllegalCharacters,
//MultiEpisodeStyle = resource.MultiEpisodeStyle,
//StandardEpisodeFormat = resource.StandardEpisodeFormat,
//DailyEpisodeFormat = resource.DailyEpisodeFormat,
//AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
//SeriesFolderFormat = resource.SeriesFolderFormat,
//SeasonFolderFormat = resource.SeasonFolderFormat,
StandardMovieFormat = resource.StandardMovieFormat,
MovieFolderFormat = resource.MovieFolderFormat
MultiEpisodeStyle = resource.MultiEpisodeStyle,
StandardEpisodeFormat = resource.StandardEpisodeFormat,
DailyEpisodeFormat = resource.DailyEpisodeFormat,
AnimeEpisodeFormat = resource.AnimeEpisodeFormat,
SeriesFolderFormat = resource.SeriesFolderFormat,
SeasonFolderFormat = resource.SeasonFolderFormat
};
}
}

View File

@@ -9,8 +9,5 @@
public string AnimeMultiEpisodeExample { get; set; }
public string SeriesFolderExample { get; set; }
public string SeasonFolderExample { get; set; }
public string MovieExample { get; set; }
public string MovieFolderExample { get; set; }
}
}

View File

@@ -3,7 +3,6 @@ using Nancy;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.Series;
using NzbDrone.Api.Movie;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
@@ -35,18 +34,12 @@ namespace NzbDrone.Api.History
resource.Series = model.Series.ToResource();
resource.Episode = model.Episode.ToResource();
resource.Movie = model.Movie.ToResource();
if (model.Series != null)
{
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Series.Profile.Value, model.Quality);
}
if (model.Movie != null)
{
resource.QualityCutoffNotMet = _qualityUpgradableSpecification.CutoffNotMet(model.Movie.Profile.Value, model.Quality);
}
return resource;
}
@@ -54,8 +47,6 @@ namespace NzbDrone.Api.History
{
var episodeId = Request.Query.EpisodeId;
var movieId = Request.Query.MovieId;
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, Core.History.History>("date", SortDirection.Descending);
if (pagingResource.FilterKey == "eventType")
@@ -70,12 +61,6 @@ namespace NzbDrone.Api.History
pagingSpec.FilterExpression = h => h.EpisodeId == i;
}
if (movieId.HasValue)
{
int i = (int)movieId;
pagingSpec.FilterExpression = h => h.MovieId == i;
}
return ApplyToPage(_historyService.Paged, pagingSpec, MapToResource);
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Api.Movie;
using NzbDrone.Core.History;
using NzbDrone.Core.Qualities;
@@ -13,7 +12,6 @@ namespace NzbDrone.Api.History
public class HistoryResource : RestResource
{
public int EpisodeId { get; set; }
public int MovieId { get; set; }
public int SeriesId { get; set; }
public string SourceTitle { get; set; }
public QualityModel Quality { get; set; }
@@ -24,7 +22,7 @@ namespace NzbDrone.Api.History
public HistoryEventType EventType { get; set; }
public Dictionary<string, string> Data { get; set; }
public MovieResource Movie { get; set; }
public EpisodeResource Episode { get; set; }
public SeriesResource Series { get; set; }
}
@@ -41,7 +39,6 @@ namespace NzbDrone.Api.History
EpisodeId = model.EpisodeId,
SeriesId = model.SeriesId,
MovieId = model.MovieId,
SourceTitle = model.SourceTitle,
Quality = model.Quality,
//QualityCutoffNotMet

View File

@@ -26,7 +26,6 @@ namespace NzbDrone.Api.Indexers
private readonly Logger _logger;
private readonly ICached<RemoteEpisode> _remoteEpisodeCache;
private readonly ICached<RemoteMovie> _remoteMovieCache;
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
ISearchForNzb nzbSearchService,
@@ -50,7 +49,6 @@ namespace NzbDrone.Api.Indexers
PostValidator.RuleFor(s => s.Guid).NotEmpty();
_remoteEpisodeCache = cacheManager.GetCache<RemoteEpisode>(GetType(), "remoteEpisodes");
_remoteMovieCache = cacheManager.GetCache<RemoteMovie>(GetType(), "remoteMovies");
}
private Response DownloadRelease(ReleaseResource release)
@@ -61,26 +59,7 @@ namespace NzbDrone.Api.Indexers
{
_logger.Debug("Couldn't find requested release in cache, cache timeout probably expired.");
var remoteMovie = _remoteMovieCache.Find(release.Guid);
if (remoteMovie == null)
{
return new NotFoundResponse();
}
try
{
_downloadService.DownloadReport(remoteMovie);
}
catch (ReleaseDownloadException ex)
{
_logger.Error(ex, ex.Message);
throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed");
}
return release.AsResponse();
return new NotFoundResponse();
}
try
@@ -103,11 +82,6 @@ namespace NzbDrone.Api.Indexers
return GetEpisodeReleases(Request.Query.episodeId);
}
if (Request.Query.movieId != null)
{
return GetMovieReleases(Request.Query.movieId);
}
return GetRss();
}
@@ -128,27 +102,6 @@ namespace NzbDrone.Api.Indexers
return new List<ReleaseResource>();
}
private List<ReleaseResource> GetMovieReleases(int movieId)
{
try
{
var decisions = _nzbSearchService.MovieSearch(movieId, true);
var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisionsForMovies(decisions);
return MapDecisions(prioritizedDecisions);
}
catch (NotImplementedException ex)
{
_logger.Error(ex, "One or more indexer you selected does not support movie search yet: " + ex.Message);
}
catch (Exception ex)
{
_logger.Error(ex, "Movie search failed: " + ex.Message);
}
return new List<ReleaseResource>();
}
private List<ReleaseResource> GetRss()
{
var reports = _rssFetcherAndParser.Fetch();
@@ -160,15 +113,7 @@ namespace NzbDrone.Api.Indexers
protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
{
if (decision.IsForMovie)
{
_remoteMovieCache.Set(decision.RemoteMovie.Release.Guid, decision.RemoteMovie, TimeSpan.FromMinutes(30));
}
else
{
_remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
}
_remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
return base.MapDecision(decision, initialWeight);
}
}

View File

@@ -24,7 +24,6 @@ namespace NzbDrone.Api.Indexers
public string Indexer { get; set; }
public string ReleaseGroup { get; set; }
public string ReleaseHash { get; set; }
public string Edition { get; set; }
public string Title { get; set; }
public bool FullSeason { get; set; }
public int SeasonNumber { get; set; }
@@ -87,60 +86,6 @@ namespace NzbDrone.Api.Indexers
var parsedEpisodeInfo = model.RemoteEpisode.ParsedEpisodeInfo;
var remoteEpisode = model.RemoteEpisode;
var torrentInfo = (model.RemoteEpisode.Release as TorrentInfo) ?? new TorrentInfo();
var downloadAllowed = model.RemoteEpisode.DownloadAllowed;
if (model.IsForMovie)
{
downloadAllowed = model.RemoteMovie.DownloadAllowed;
var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
return new ReleaseResource
{
Guid = releaseInfo.Guid,
Quality = parsedMovieInfo.Quality,
//QualityWeight
Age = releaseInfo.Age,
AgeHours = releaseInfo.AgeHours,
AgeMinutes = releaseInfo.AgeMinutes,
Size = releaseInfo.Size,
IndexerId = releaseInfo.IndexerId,
Indexer = releaseInfo.Indexer,
ReleaseGroup = parsedMovieInfo.ReleaseGroup,
ReleaseHash = parsedMovieInfo.ReleaseHash,
Title = releaseInfo.Title,
FullSeason = parsedMovieInfo.FullSeason,
SeasonNumber = parsedMovieInfo.SeasonNumber,
Language = parsedMovieInfo.Language,
AirDate = "",
SeriesTitle = parsedMovieInfo.MovieTitle,
EpisodeNumbers = new int[0],
AbsoluteEpisodeNumbers = new int[0],
Approved = model.Approved,
TemporarilyRejected = model.TemporarilyRejected,
Rejected = model.Rejected,
TvdbId = releaseInfo.TvdbId,
TvRageId = releaseInfo.TvRageId,
Rejections = model.Rejections.Select(r => r.Reason).ToList(),
PublishDate = releaseInfo.PublishDate,
CommentUrl = releaseInfo.CommentUrl,
DownloadUrl = releaseInfo.DownloadUrl,
InfoUrl = releaseInfo.InfoUrl,
DownloadAllowed = downloadAllowed,
//ReleaseWeight
MagnetUrl = torrentInfo.MagnetUrl,
InfoHash = torrentInfo.InfoHash,
Seeders = torrentInfo.Seeders,
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
Protocol = releaseInfo.DownloadProtocol,
Edition = parsedMovieInfo.Edition,
IsDaily = false,
IsAbsoluteNumbering = false,
IsPossibleSpecialEpisode = false,
Special = parsedMovieInfo.Special,
};
}
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
return new ReleaseResource
@@ -174,7 +119,7 @@ namespace NzbDrone.Api.Indexers
CommentUrl = releaseInfo.CommentUrl,
DownloadUrl = releaseInfo.DownloadUrl,
InfoUrl = releaseInfo.InfoUrl,
DownloadAllowed = downloadAllowed,
DownloadAllowed = remoteEpisode.DownloadAllowed,
//ReleaseWeight
MagnetUrl = torrentInfo.MagnetUrl,

View File

@@ -231,11 +231,8 @@
<Compile Include="Series\SeasonResource.cs" />
<Compile Include="SeasonPass\SeasonPassModule.cs" />
<Compile Include="Series\SeriesEditorModule.cs" />
<Compile Include="Series\MovieLookupModule.cs" />
<Compile Include="Series\SeriesLookupModule.cs" />
<Compile Include="Series\MovieModule.cs" />
<Compile Include="Series\SeriesModule.cs" />
<Compile Include="Series\MovieResource.cs" />
<Compile Include="Series\SeriesResource.cs" />
<Compile Include="Series\SeasonStatisticsResource.cs" />
<Compile Include="System\Backup\BackupModule.cs" />

View File

@@ -6,5 +6,6 @@ using System.Runtime.InteropServices;
[assembly: Guid("4c0922d7-979e-4ff7-b44b-b8ac2100eeb5")]
[assembly: AssemblyVersion("10.0.0.*")]
[assembly: InternalsVisibleTo("NzbDrone.Core")]

View File

@@ -4,7 +4,6 @@ using NzbDrone.Api.REST;
using NzbDrone.Core.Qualities;
using NzbDrone.Api.Series;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movie;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Indexers;
using System.Linq;
@@ -15,7 +14,6 @@ namespace NzbDrone.Api.Queue
{
public SeriesResource Series { get; set; }
public EpisodeResource Episode { get; set; }
public MovieResource Movie { get; set; }
public QualityModel Quality { get; set; }
public decimal Size { get; set; }
public string Title { get; set; }
@@ -51,8 +49,7 @@ namespace NzbDrone.Api.Queue
TrackedDownloadStatus = model.TrackedDownloadStatus,
StatusMessages = model.StatusMessages,
DownloadId = model.DownloadId,
Protocol = model.Protocol,
Movie = model.Movie.ToResource()
Protocol = model.Protocol
};
}

View File

@@ -1,44 +0,0 @@
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource;
using System.Linq;
namespace NzbDrone.Api.Movie
{
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
{
private readonly ISearchForNewMovie _searchProxy;
public MovieLookupModule(ISearchForNewMovie searchProxy)
: base("/movies/lookup")
{
_searchProxy = searchProxy;
Get["/"] = x => Search();
}
private Response Search()
{
var imdbResults = _searchProxy.SearchForNewMovie((string)Request.Query.term);
return MapToResource(imdbResults).AsResponse();
}
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
{
foreach (var currentSeries in movies)
{
var resource = currentSeries.ToResource();
var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
if (poster != null)
{
resource.RemotePoster = poster.Url;
}
yield return resource;
}
}
}
}

View File

@@ -1,225 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.MovieStats;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
using NzbDrone.Core.Validation.Paths;
using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Validation;
using NzbDrone.SignalR;
namespace NzbDrone.Api.Movie
{
public class MovieModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
IHandle<EpisodeImportedEvent>,
IHandle<EpisodeFileDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
{
private readonly IMovieService _moviesService;
private readonly IMovieStatisticsService _moviesStatisticsService;
private readonly IMapCoversToLocal _coverMapper;
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService,
IMovieStatisticsService moviesStatisticsService,
ISceneMappingService sceneMappingService,
IMapCoversToLocal coverMapper,
RootFolderValidator rootFolderValidator,
MoviePathValidator moviesPathValidator,
MovieExistsValidator moviesExistsValidator,
DroneFactoryValidator droneFactoryValidator,
MovieAncestorValidator moviesAncestorValidator,
ProfileExistsValidator profileExistsValidator
)
: base(signalRBroadcaster)
{
_moviesService = moviesService;
_moviesStatisticsService = moviesStatisticsService;
_coverMapper = coverMapper;
GetResourceAll = AllMovie;
GetResourceById = GetMovie;
CreateResource = AddMovie;
UpdateResource = UpdateMovie;
DeleteResource = DeleteMovie;
Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId));
SharedValidator.RuleFor(s => s.Path)
.Cascade(CascadeMode.StopOnFirstFailure)
.IsValidPath()
.SetValidator(rootFolderValidator)
.SetValidator(moviesPathValidator)
.SetValidator(droneFactoryValidator)
.SetValidator(moviesAncestorValidator)
.When(s => !s.Path.IsNullOrWhiteSpace());
SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator);
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
PostValidator.RuleFor(s => s.Title).NotEmpty();
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
PutValidator.RuleFor(s => s.Path).IsValidPath();
}
private MovieResource GetMovie(int id)
{
var movies = _moviesService.GetMovie(id);
return MapToResource(movies);
}
private MovieResource MapToResource(Core.Tv.Movie movies)
{
if (movies == null) return null;
var resource = movies.ToResource();
MapCoversToLocal(resource);
FetchAndLinkMovieStatistics(resource);
PopulateAlternateTitles(resource);
return resource;
}
private List<MovieResource> AllMovie()
{
var moviesStats = _moviesStatisticsService.MovieStatistics();
var moviesResources = _moviesService.GetAllMovies().ToResource();
MapCoversToLocal(moviesResources.ToArray());
LinkMovieStatistics(moviesResources, moviesStats);
PopulateAlternateTitles(moviesResources);
return moviesResources;
}
private int AddMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel();
return _moviesService.AddMovie(model).Id;
}
private void UpdateMovie(MovieResource moviesResource)
{
var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id));
_moviesService.UpdateMovie(model);
BroadcastResourceChange(ModelAction.Updated, moviesResource);
}
private void DeleteMovie(int id)
{
var deleteFiles = false;
var deleteFilesQuery = Request.Query.deleteFiles;
if (deleteFilesQuery.HasValue)
{
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
}
_moviesService.DeleteMovie(id, deleteFiles);
}
private void MapCoversToLocal(params MovieResource[] movies)
{
foreach (var moviesResource in movies)
{
_coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images);
}
}
private void FetchAndLinkMovieStatistics(MovieResource resource)
{
LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id));
}
private void LinkMovieStatistics(List<MovieResource> resources, List<MovieStatistics> moviesStatistics)
{
var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId);
foreach (var movies in resources)
{
var stats = dictMovieStats.GetValueOrDefault(movies.Id);
if (stats == null) continue;
LinkMovieStatistics(movies, stats);
}
}
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
{
resource.SizeOnDisk = moviesStatistics.SizeOnDisk;
}
private void PopulateAlternateTitles(List<MovieResource> resources)
{
foreach (var resource in resources)
{
PopulateAlternateTitles(resource);
}
}
private void PopulateAlternateTitles(MovieResource resource)
{
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
//if (mappings == null) return;
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
}
public void Handle(EpisodeImportedEvent message)
{
//BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId);
}
public void Handle(EpisodeFileDeletedEvent message)
{
if (message.Reason == DeleteMediaFileReason.Upgrade) return;
//BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId);
}
public void Handle(MovieUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieEditedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MovieDeletedEvent message)
{
BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource());
}
public void Handle(MovieRenamedEvent message)
{
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
public void Handle(MediaCoversUpdatedEvent message)
{
//BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
}
}
}

View File

@@ -1,192 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Series;
namespace NzbDrone.Api.Movie
{
public class MovieResource : RestResource
{
public MovieResource()
{
Monitored = true;
}
//Todo: Sorters should be done completely on the client
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
//Todo: We should get the entire Profile instead of ID and Name separately
//View Only
public string Title { get; set; }
public List<AlternateTitleResource> AlternateTitles { get; set; }
public string SortTitle { get; set; }
public long? SizeOnDisk { get; set; }
public MovieStatusType Status { get; set; }
public string Overview { get; set; }
public DateTime? InCinemas { get; set; }
public List<MediaCover> Images { get; set; }
public string Website { get; set; }
public string RemotePoster { get; set; }
public int Year { get; set; }
//View & Edit
public string Path { get; set; }
public int ProfileId { get; set; }
//Editing Only
public bool Monitored { get; set; }
public int Runtime { get; set; }
public DateTime? LastInfoSync { get; set; }
public string CleanTitle { get; set; }
public string ImdbId { get; set; }
public int TmdbId { get; set; }
public string TitleSlug { get; set; }
public string RootFolderPath { get; set; }
public string Certification { get; set; }
public List<string> Genres { get; set; }
public HashSet<int> Tags { get; set; }
public DateTime Added { get; set; }
public AddMovieOptions AddOptions { get; set; }
public Ratings Ratings { get; set; }
public List<string> AlternativeTitles { get; set; }
//TODO: Add series statistics as a property of the series (instead of individual properties)
//Used to support legacy consumers
public int QualityProfileId
{
get
{
return ProfileId;
}
set
{
if (value > 0 && ProfileId == 0)
{
ProfileId = value;
}
}
}
}
public static class MovieResourceMapper
{
public static MovieResource ToResource(this Core.Tv.Movie model)
{
if (model == null) return null;
return new MovieResource
{
Id = model.Id,
TmdbId = model.TmdbId,
Title = model.Title,
//AlternateTitles
SortTitle = model.SortTitle,
InCinemas = model.InCinemas,
//TotalEpisodeCount
//EpisodeCount
//EpisodeFileCount
//SizeOnDisk
Status = model.Status,
Overview = model.Overview,
//NextAiring
//PreviousAiring
Images = model.Images,
Year = model.Year,
Path = model.Path,
ProfileId = model.ProfileId,
Monitored = model.Monitored,
Runtime = model.Runtime,
LastInfoSync = model.LastInfoSync,
CleanTitle = model.CleanTitle,
ImdbId = model.ImdbId,
TitleSlug = model.TitleSlug,
RootFolderPath = model.RootFolderPath,
Certification = model.Certification,
Website = model.Website,
Genres = model.Genres,
Tags = model.Tags,
Added = model.Added,
AddOptions = model.AddOptions,
AlternativeTitles = model.AlternativeTitles,
Ratings = model.Ratings
};
}
public static Core.Tv.Movie ToModel(this MovieResource resource)
{
if (resource == null) return null;
return new Core.Tv.Movie
{
Id = resource.Id,
TmdbId = resource.TmdbId,
Title = resource.Title,
//AlternateTitles
SortTitle = resource.SortTitle,
InCinemas = resource.InCinemas,
//TotalEpisodeCount
//EpisodeCount
//EpisodeFileCount
//SizeOnDisk
Overview = resource.Overview,
//NextAiring
//PreviousAiring
Images = resource.Images,
Year = resource.Year,
Path = resource.Path,
ProfileId = resource.ProfileId,
Monitored = resource.Monitored,
Runtime = resource.Runtime,
LastInfoSync = resource.LastInfoSync,
CleanTitle = resource.CleanTitle,
ImdbId = resource.ImdbId,
TitleSlug = resource.TitleSlug,
RootFolderPath = resource.RootFolderPath,
Certification = resource.Certification,
Website = resource.Website,
Genres = resource.Genres,
Tags = resource.Tags,
Added = resource.Added,
AddOptions = resource.AddOptions,
AlternativeTitles = resource.AlternativeTitles,
Ratings = resource.Ratings
};
}
public static Core.Tv.Movie ToModel(this MovieResource resource, Core.Tv.Movie movie)
{
movie.ImdbId = resource.ImdbId;
movie.TmdbId = resource.TmdbId;
movie.Path = resource.Path;
movie.ProfileId = resource.ProfileId;
movie.Monitored = resource.Monitored;
movie.RootFolderPath = resource.RootFolderPath;
movie.Tags = resource.Tags;
movie.AddOptions = resource.AddOptions;
return movie;
}
public static List<MovieResource> ToResource(this IEnumerable<Core.Tv.Movie> movies)
{
return movies.Select(ToResource).ToList();
}
}
}

View File

@@ -7,7 +7,7 @@ namespace NzbDrone.Api.System.Tasks
{
public string Name { get; set; }
public string TaskName { get; set; }
public double Interval { get; set; }
public int Interval { get; set; }
public DateTime LastExecution { get; set; }
public DateTime NextExecution { get; set; }
}

View File

@@ -8,7 +8,7 @@ using NzbDrone.Core.Jobs;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using Radarr.Host;
using NzbDrone.Host;
using NzbDrone.Test.Common;
using FluentAssertions;
using System.Linq;

View File

@@ -3,9 +3,8 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
using Radarr.Host;
using NzbDrone.Host;
using NzbDrone.Test.Common;
using Radarr.Host;
namespace NzbDrone.App.Test
{

View File

@@ -21,3 +21,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b47d34ef-05e8-4826-8a57-9dd05106c964")]
[assembly: AssemblyVersion("10.0.0.*")]

View File

@@ -3,7 +3,7 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using Radarr.Host;
using NzbDrone.Host;
using NzbDrone.Test.Common;
namespace NzbDrone.App.Test

View File

@@ -40,7 +40,7 @@ namespace NzbDrone.Automation.Test
_runner.KillAll();
_runner.Start();
driver.Url = "http://localhost:7878";
driver.Url = "http://localhost:8989";
var page = new PageBase(driver);
page.WaitForNoSpinner();

View File

@@ -20,3 +20,5 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6b8945f5-f5b5-4729-865d-f958fbd673d9")]
[assembly: AssemblyVersion("10.0.0.*")]

View File

@@ -49,7 +49,7 @@ namespace NzbDrone.Common.Test
public void GetValue_Success()
{
const string key = "Port";
const string value = "7878";
const string value = "8989";
var result = Subject.GetValue(key, value);
@@ -60,7 +60,7 @@ namespace NzbDrone.Common.Test
public void GetInt_Success()
{
const string key = "Port";
const int value = 7878;
const int value = 8989;
var result = Subject.GetValueInt(key, value);
@@ -95,7 +95,7 @@ namespace NzbDrone.Common.Test
[Test]
public void GetPort_Success()
{
const int value = 7878;
const int value = 8989;
var result = Subject.Port;

View File

@@ -263,7 +263,7 @@ namespace NzbDrone.Common.Test
[Test]
public void GetUpdateClientExePath()
{
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\Radarr.Update.exe".AsOsAgnostic());
GetIAppDirectoryInfo().GetUpdateClientExePath().Should().BeEquivalentTo(@"C:\Temp\nzbdrone_update\NzbDrone.Update.exe".AsOsAgnostic());
}
[Test]

View File

@@ -5,7 +5,7 @@ using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
using Radarr.Host;
using NzbDrone.Host;
using NzbDrone.Test.Common;
namespace NzbDrone.Common.Test

View File

@@ -6,33 +6,22 @@ namespace NzbDrone.Common.Cloud
{
IHttpRequestBuilderFactory Services { get; }
IHttpRequestBuilderFactory SkyHookTvdb { get; }
IHttpRequestBuilderFactory TMDB { get; }
IHttpRequestBuilderFactory TMDBSingle { get; }
}
public class SonarrCloudRequestBuilder : ISonarrCloudRequestBuilder
{
public SonarrCloudRequestBuilder()
{
Services = new HttpRequestBuilder("https://radarr.aeonlucid.com/v1/")
Services = new HttpRequestBuilder("http://services.sonarr.tv/v1/")
.CreateFactory();
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
.SetSegment("language", "en")
.CreateFactory();
TMDB = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}/{id}{secondaryRoute}")
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
.CreateFactory();
TMDBSingle = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}")
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
.CreateFactory();
}
public IHttpRequestBuilderFactory Services { get; private set; }
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
public IHttpRequestBuilderFactory TMDB { get; private set; }
public IHttpRequestBuilderFactory TMDBSingle { get; private set; }
}
}

View File

@@ -34,7 +34,7 @@ namespace NzbDrone.Common.EnvironmentInfo
}
else
{
AppDataFolder = Path.Combine(Environment.GetFolderPath(DATA_SPECIAL_FOLDER, Environment.SpecialFolderOption.None), "Radarr");
AppDataFolder = Path.Combine(Environment.GetFolderPath(DATA_SPECIAL_FOLDER, Environment.SpecialFolderOption.None), "NzbDrone");
}
StartUpFolder = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName;

View File

@@ -13,11 +13,11 @@ namespace NzbDrone.Common.Extensions
private const string NZBDRONE_DB = "nzbdrone.db";
private const string NZBDRONE_LOG_DB = "logs.db";
private const string NLOG_CONFIG_FILE = "nlog.config";
private const string UPDATE_CLIENT_EXE = "Radarr.Update.exe";
private const string UPDATE_CLIENT_EXE = "NzbDrone.Update.exe";
private const string BACKUP_FOLDER = "Backups";
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "nzbdrone_update" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "";
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "NzbDrone" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_BACKUP_FOLDER_NAME = "nzbdrone_backup" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_BACKUP_APPDATA_FOLDER_NAME = "nzbdrone_appdata_backup" + Path.DirectorySeparatorChar;
private static readonly string UPDATE_CLIENT_FOLDER_NAME = "NzbDrone.Update" + Path.DirectorySeparatorChar;

View File

@@ -35,8 +35,8 @@ namespace NzbDrone.Common.Processes
{
private readonly Logger _logger;
public const string NZB_DRONE_PROCESS_NAME = "Radarr";
public const string NZB_DRONE_CONSOLE_PROCESS_NAME = "Radarr.Console";
public const string NZB_DRONE_PROCESS_NAME = "NzbDrone";
public const string NZB_DRONE_CONSOLE_PROCESS_NAME = "NzbDrone.Console";
public ProcessProvider(Logger logger)
{

View File

@@ -9,3 +9,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b6eaa144-e13b-42e5-a738-c60d89c0f728")]
[assembly: AssemblyVersion("10.0.0.*")]

View File

@@ -2,9 +2,8 @@
using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("radarr.tv")]
[assembly: AssemblyCompany("sonarr.tv")]
[assembly: AssemblyProduct("NzbDrone")]
[assembly: AssemblyVersion("0.1.0.*")]
[assembly: AssemblyCopyright("GNU General Public v3")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -1,4 +1,4 @@
using Radarr.Host;
using NzbDrone.Host;
namespace NzbDrone.Console
{

View File

@@ -3,7 +3,7 @@ using System.Net.Sockets;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
using Radarr.Host;
using NzbDrone.Host;
namespace NzbDrone.Console
{
@@ -23,7 +23,7 @@ namespace NzbDrone.Console
{
System.Console.WriteLine("");
System.Console.WriteLine("");
Logger.Fatal(exception.Message + ". This can happen if another instance of Radarr is already running another application is using the same port (default: 7878) or the user has insufficient permissions");
Logger.Fatal(exception.Message + ". This can happen if another instance of Sonarr is already running another application is using the same port (default: 8989) or the user has insufficient permissions");
System.Console.WriteLine("Press enter to exit...");
System.Console.ReadLine();
Environment.Exit(1);

View File

@@ -9,7 +9,7 @@
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Console</RootNamespace>
<AssemblyName>Radarr.Console</AssemblyName>
<AssemblyName>NzbDrone.Console</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
@@ -54,7 +54,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Radarr.ico</ApplicationIcon>
<ApplicationIcon>..\NzbDrone.Host\NzbDrone.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>NzbDrone.Console.ConsoleApp</StartupObject>
@@ -139,9 +139,6 @@
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Radarr.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

View File

@@ -7,3 +7,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("NzbDrone.Host")]
[assembly: Guid("67AADCD9-89AA-4D95-8281-3193740E70E5")]
[assembly: AssemblyVersion("10.0.0.*")]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -178,9 +178,8 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
public void should_return_an_empty_list_when_none_are_appproved()
{
var decisions = new List<DownloadDecision>();
RemoteEpisode ep = null;
decisions.Add(new DownloadDecision(ep, new Rejection("Failure!")));
decisions.Add(new DownloadDecision(ep, new Rejection("Failure!")));
decisions.Add(new DownloadDecision(null, new Rejection("Failure!")));
decisions.Add(new DownloadDecision(null, new Rejection("Failure!")));
Subject.GetQualifiedReports(decisions).Should().BeEmpty();
}

View File

@@ -0,0 +1,120 @@
using System;
using FluentAssertions;
using FluentValidation.Results;
using NUnit.Framework;
using NzbDrone.Core.Notifications;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Validation;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.NotificationTests
{
[TestFixture]
public class NotificationBaseFixture : TestBase
{
class TestSetting : IProviderConfig
{
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult();
}
}
class TestNotificationWithOnDownload : NotificationBase<TestSetting>
{
public override string Name => "TestNotification";
public override string Link => "";
public override ValidationResult Test()
{
throw new NotImplementedException();
}
public override void OnDownload(DownloadMessage downloadMessage)
{
TestLogger.Info("OnDownload was called");
}
}
class TestNotificationWithAllEvents : NotificationBase<TestSetting>
{
public override string Name => "TestNotification";
public override string Link => "";
public override ValidationResult Test()
{
throw new NotImplementedException();
}
public override void OnGrab(GrabMessage grabMessage)
{
TestLogger.Info("OnGrab was called");
}
public override void OnDownload(DownloadMessage message)
{
TestLogger.Info("OnDownload was called");
}
public override void OnRename(Series series)
{
TestLogger.Info("OnRename was called");
}
}
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
{
public override string Name => "TestNotification";
public override string Link => "";
public override ValidationResult Test()
{
throw new NotImplementedException();
}
}
[Test]
public void should_support_OnUpgrade_should_link_to_OnDownload()
{
var notification = new TestNotificationWithOnDownload();
notification.SupportsOnDownload.Should().BeTrue();
notification.SupportsOnUpgrade.Should().BeTrue();
notification.SupportsOnGrab.Should().BeFalse();
notification.SupportsOnRename.Should().BeFalse();
}
[Test]
public void should_support_all_if_implemented()
{
var notification = new TestNotificationWithAllEvents();
notification.SupportsOnGrab.Should().BeTrue();
notification.SupportsOnDownload.Should().BeTrue();
notification.SupportsOnUpgrade.Should().BeTrue();
notification.SupportsOnRename.Should().BeTrue();
}
[Test]
public void should_support_none_if_none_are_implemented()
{
var notification = new TestNotificationWithNoEvents();
notification.SupportsOnGrab.Should().BeFalse();
notification.SupportsOnDownload.Should().BeFalse();
notification.SupportsOnUpgrade.Should().BeFalse();
notification.SupportsOnRename.Should().BeFalse();
}
}
}

View File

@@ -288,6 +288,7 @@
<Compile Include="MetadataSource\SkyHook\SkyHookProxySearchFixture.cs" />
<Compile Include="MetadataSource\SearchSeriesComparerFixture.cs" />
<Compile Include="MetadataSource\SkyHook\SkyHookProxyFixture.cs" />
<Compile Include="NotificationTests\NotificationBaseFixture.cs" />
<Compile Include="NotificationTests\SynologyIndexerFixture.cs" />
<Compile Include="OrganizerTests\FileNameBuilderTests\CleanTitleFixture.cs" />
<Compile Include="OrganizerTests\FileNameBuilderTests\EpisodeTitleCollapseFixture.cs" />

View File

@@ -25,4 +25,6 @@ using System.Runtime.InteropServices;
[assembly: Guid("699aed1b-015e-4f0d-9c81-d5557b05d260")]
[assembly: AssemblyVersion("10.0.0.*")]
[assembly: InternalsVisibleTo("NzbDrone.Core")]

View File

@@ -59,7 +59,7 @@ namespace NzbDrone.Core.Test.UpdateTests
Mocker.GetMock<IVerifyUpdates>().Setup(c => c.Verify(It.IsAny<UpdatePackage>(), It.IsAny<string>())).Returns(true);
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess()).Returns(new ProcessInfo { Id = 12 });
Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\Radarr.exe");
Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\NzbDrone.exe");
Mocker.GetMock<IConfigFileProvider>()
.SetupGet(s => s.UpdateAutomatically)

View File

@@ -133,7 +133,7 @@ namespace NzbDrone.Core.Configuration
}
}
public int Port => GetValueInt("Port", 7878);
public int Port => GetValueInt("Port", 8989);
public int SslPort => GetValueInt("SslPort", 9898);
@@ -303,12 +303,12 @@ namespace NzbDrone.Core.Configuration
if (contents.IsNullOrWhiteSpace())
{
throw new InvalidConfigFileException($"{_configFile} is empty. Please delete the config file and Radarr will recreate it.");
throw new InvalidConfigFileException($"{_configFile} is empty. Please delete the config file and Sonarr will recreate it.");
}
if (contents.All(char.IsControl))
{
throw new InvalidConfigFileException($"{_configFile} is corrupt. Please delete the config file and Radarr will recreate it.");
throw new InvalidConfigFileException($"{_configFile} is corrupt. Please delete the config file and Sonarr will recreate it.");
}
return XDocument.Parse(_diskProvider.ReadAllText(_configFile));
@@ -323,7 +323,7 @@ namespace NzbDrone.Core.Configuration
catch (XmlException ex)
{
throw new InvalidConfigFileException($"{_configFile} is corrupt is invalid. Please delete the config file and Radarr will recreate it.", ex);
throw new InvalidConfigFileException($"{_configFile} is corrupt is invalid. Please delete the config file and Sonarr will recreate it.", ex);
}
}

View File

@@ -41,32 +41,6 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("FirstAired").AsDateTime().Nullable()
.WithColumn("NextAiring").AsDateTime().Nullable();
Create.TableForModel("Movies")
.WithColumn("ImdbId").AsString().Unique()
.WithColumn("Title").AsString()
.WithColumn("TitleSlug").AsString().Unique()
.WithColumn("SortTitle").AsString().Nullable()
.WithColumn("CleanTitle").AsString()
.WithColumn("Status").AsInt32()
.WithColumn("Overview").AsString().Nullable()
.WithColumn("Images").AsString()
.WithColumn("Path").AsString()
.WithColumn("Monitored").AsBoolean()
.WithColumn("ProfileId").AsInt32()
.WithColumn("LastInfoSync").AsDateTime().Nullable()
.WithColumn("LastDiskSync").AsDateTime().Nullable()
.WithColumn("Runtime").AsInt32()
.WithColumn("InCinemas").AsDateTime().Nullable()
.WithColumn("Year").AsInt32().Nullable()
.WithColumn("Added").AsDateTime().Nullable()
.WithColumn("Actors").AsString().Nullable()
.WithColumn("Ratings").AsString().Nullable()
.WithColumn("Genres").AsString().Nullable()
.WithColumn("Tags").AsString().Nullable()
.WithColumn("Certification").AsString().Nullable()
.WithColumn("AddOptions").AsString().Nullable();
Create.TableForModel("Seasons")
.WithColumn("SeriesId").AsInt32()
.WithColumn("SeasonNumber").AsInt32()
@@ -105,8 +79,7 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Quality").AsString()
.WithColumn("Indexer").AsString()
.WithColumn("NzbInfoUrl").AsString().Nullable()
.WithColumn("ReleaseGroup").AsString().Nullable()
.WithColumn("MovieId").AsInt32().WithDefaultValue(0);
.WithColumn("ReleaseGroup").AsString().Nullable();
Create.TableForModel("Notifications")
.WithColumn("Name").AsString()

View File

@@ -21,12 +21,11 @@ namespace NzbDrone.Core.Datastore.Migration
//Add HeldReleases
Create.TableForModel("PendingReleases")
.WithColumn("SeriesId").AsInt32().WithDefaultValue(0)
.WithColumn("SeriesId").AsInt32()
.WithColumn("Title").AsString()
.WithColumn("Added").AsDateTime()
.WithColumn("ParsedEpisodeInfo").AsString()
.WithColumn("Release").AsString()
.WithColumn("MovieId").AsInt32().WithDefaultValue(0);
.WithColumn("Release").AsString();
}
}
}

View File

@@ -1,31 +0,0 @@
using FluentMigrator;
using Marr.Data.Mapping;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Datastore.Extensions;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(104)]
public class add_moviefiles_table : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Create.TableForModel("MovieFiles")
.WithColumn("MovieId").AsInt32()
.WithColumn("Path").AsString().Unique()
.WithColumn("Quality").AsString()
.WithColumn("Size").AsInt64()
.WithColumn("DateAdded").AsDateTime()
.WithColumn("SceneName").AsString().Nullable()
.WithColumn("MediaInfo").AsString().Nullable()
.WithColumn("ReleaseGroup").AsString().Nullable()
.WithColumn("RelativePath").AsString().Nullable();
Alter.Table("Movies").AddColumn("MovieFileId").AsInt32().WithDefaultValue(0);
}
}
}

View File

@@ -1,15 +0,0 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(105)]
public class fix_history_movieId : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("History")
.AddColumn("MovieId").AsInt32().WithDefaultValue(0);
}
}
}

View File

@@ -1,21 +0,0 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(106)]
public class add_tmdb_stuff : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Movies")
.AddColumn("TmdbId").AsInt32().WithDefaultValue(0);
Alter.Table("Movies")
.AddColumn("Website").AsString().Nullable();
Alter.Table("Movies")
.AlterColumn("ImdbId").AsString().Nullable();
Alter.Table("Movies")
.AddColumn("AlternativeTitles").AsString().Nullable();
}
}
}

View File

@@ -1,14 +0,0 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(107)]
public class fix_movie_files : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("MovieFiles").AlterColumn("Path").AsString().Nullable(); //Should be deleted, but to much work, ¯\_(ツ)_/¯
}
}
}

View File

@@ -1,15 +0,0 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(108)]
public class update_schedule_intervale : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("ScheduledTasks").AlterColumn("Interval").AsDouble();
Execute.Sql("UPDATE ScheduledTasks SET Interval=0.25 WHERE TypeName='NzbDrone.Core.Download.CheckForFinishedDownloadCommand'");
}
}
}

View File

@@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using System.Data;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(109)]
public class add_movie_formats_to_naming_config : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("NamingConfig").AddColumn("StandardMovieFormat").AsString().Nullable();
Alter.Table("NamingConfig").AddColumn("MovieFolderFormat").AsString().Nullable();
Execute.WithConnection(ConvertConfig);
}
private void ConvertConfig(IDbConnection conn, IDbTransaction tran)
{
using (IDbCommand namingConfigCmd = conn.CreateCommand())
{
namingConfigCmd.Transaction = tran;
namingConfigCmd.CommandText = @"SELECT * FROM NamingConfig LIMIT 1";
using (IDataReader namingConfigReader = namingConfigCmd.ExecuteReader())
{
while (namingConfigReader.Read())
{
// Output Settings
var movieTitlePattern = "";
var movieYearPattern = "({Release Year})";
var qualityFormat = "[{Quality Title}]";
movieTitlePattern = "{Movie Title}";
var standardMovieFormat = string.Format("{0} {1} {2}", movieTitlePattern,
movieYearPattern,
qualityFormat);
var movieFolderFormat = string.Format("{0} {1}", movieTitlePattern, movieYearPattern);
using (IDbCommand updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE NamingConfig " +
"SET StandardMovieFormat = '{0}', " +
"MovieFolderFormat = '{1}'",
standardMovieFormat,
movieFolderFormat);
updateCmd.Transaction = tran;
updateCmd.CommandText = text;
updateCmd.ExecuteNonQuery();
}
}
}
}
}
}
}

View File

@@ -60,6 +60,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
sw.Stop();
_announcer.ElapsedTime(sw.Elapsed);
}
}

View File

@@ -76,8 +76,6 @@ namespace NzbDrone.Core.Datastore
.Relationship()
.HasOne(s => s.Profile, s => s.ProfileId);
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles")
.Ignore(f => f.Path)
.Relationships.AutoMapICollectionOrComplexProperties()
@@ -86,21 +84,6 @@ namespace NzbDrone.Core.Datastore
query: (db, parent) => db.Query<Episode>().Where(c => c.EpisodeFileId == parent.Id).ToList())
.HasOne(file => file.Series, file => file.SeriesId);
Mapper.Entity<MovieFile>().RegisterModel("MovieFiles")
.Ignore(f => f.Path)
.Relationships.AutoMapICollectionOrComplexProperties()
.For("Movie")
.LazyLoad(condition: parent => parent.Id > 0,
query: (db, parent) => db.Query<Movie>().Where(c => c.MovieFileId == parent.Id).ToList())
.HasOne(file => file.Movie, file => file.MovieId);
Mapper.Entity<Movie>().RegisterModel("Movies")
.Ignore(s => s.RootFolderPath)
.Relationship()
.HasOne(s => s.Profile, s => s.ProfileId)
.HasOne(m => m.MovieFile, m => m.MovieFileId);
Mapper.Entity<Episode>().RegisterModel("Episodes")
.Ignore(e => e.SeriesTitle)
.Ignore(e => e.Series)
@@ -140,7 +123,6 @@ namespace NzbDrone.Core.Datastore
RegisterEmbeddedConverter();
RegisterProviderSettingConverter();
MapRepository.Instance.RegisterTypeConverter(typeof(int), new Int32Converter());
MapRepository.Instance.RegisterTypeConverter(typeof(double), new DoubleConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(DateTime), new UtcConverter());

View File

@@ -7,10 +7,6 @@ namespace NzbDrone.Core.DecisionEngine
public class DownloadDecision
{
public RemoteEpisode RemoteEpisode { get; private set; }
public RemoteMovie RemoteMovie { get; private set; }
public bool IsForMovie = false;
public IEnumerable<Rejection> Rejections { get; private set; }
public bool Approved => !Rejections.Any();
@@ -34,23 +30,6 @@ namespace NzbDrone.Core.DecisionEngine
public DownloadDecision(RemoteEpisode episode, params Rejection[] rejections)
{
RemoteEpisode = episode;
RemoteMovie = new RemoteMovie
{
Release = episode.Release,
ParsedEpisodeInfo = episode.ParsedEpisodeInfo
};
Rejections = rejections.ToList();
}
public DownloadDecision(RemoteMovie movie, params Rejection[] rejections)
{
RemoteMovie = movie;
RemoteEpisode = new RemoteEpisode
{
Release = movie.Release,
ParsedEpisodeInfo = movie.ParsedEpisodeInfo
};
IsForMovie = true;
Rejections = rejections.ToList();
}

View File

@@ -37,92 +37,9 @@ namespace NzbDrone.Core.DecisionEngine
public List<DownloadDecision> GetSearchDecision(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteriaBase)
{
if (searchCriteriaBase.Movie != null)
{
return GetMovieDecisions(reports, searchCriteriaBase).ToList();
}
return GetDecisions(reports, searchCriteriaBase).ToList();
}
private IEnumerable<DownloadDecision> GetMovieDecisions(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteria = null)
{
if (reports.Any())
{
_logger.ProgressInfo("Processing {0} releases", reports.Count);
}
else
{
_logger.ProgressInfo("No results found");
}
var reportNumber = 1;
foreach (var report in reports)
{
DownloadDecision decision = null;
_logger.ProgressTrace("Processing release {0}/{1}", reportNumber, reports.Count);
try
{
var parsedEpisodeInfo = Parser.Parser.ParseMovieTitle(report.Title);
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.MovieTitle.IsNullOrWhiteSpace())
{
RemoteMovie remoteEpisode = _parsingService.Map(parsedEpisodeInfo, "", searchCriteria);
remoteEpisode.Release = report;
if (remoteEpisode.Movie == null)
{
//remoteEpisode.DownloadAllowed = true; //Fuck you :)
//decision = GetDecisionForReport(remoteEpisode, searchCriteria);
decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown release. Movie not Found."));
}
else
{
if (parsedEpisodeInfo.Quality.HardcodedSubs.IsNotNullOrWhiteSpace())
{
remoteEpisode.DownloadAllowed = true;
decision = new DownloadDecision(remoteEpisode, new Rejection("Hardcoded subs found: " + parsedEpisodeInfo.Quality.HardcodedSubs));
}
else
{
remoteEpisode.DownloadAllowed = true;
decision = GetDecisionForReport(remoteEpisode, searchCriteria);
//decision = new DownloadDecision(remoteEpisode);
}
}
}
}
catch (Exception e)
{
_logger.Error(e, "Couldn't process release.");
var remoteEpisode = new RemoteEpisode { Release = report };
decision = new DownloadDecision(remoteEpisode, new Rejection("Unexpected error processing release"));
}
reportNumber++;
if (decision != null)
{
if (decision.Rejections.Any())
{
_logger.Debug("Release rejected for the following reasons: {0}", string.Join(", ", decision.Rejections));
}
else
{
_logger.Debug("Release accepted");
}
yield return decision;
}
}
}
private IEnumerable<DownloadDecision> GetDecisions(List<ReleaseInfo> reports, SearchCriteriaBase searchCriteria = null)
{
if (reports.Any())
@@ -163,9 +80,7 @@ namespace NzbDrone.Core.DecisionEngine
if (remoteEpisode.Series == null)
{
//remoteEpisode.DownloadAllowed = true; //Fuck you :)
//decision = GetDecisionForReport(remoteEpisode, searchCriteria);
decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown release. Series not Found."));
decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown Series"));
}
else if (remoteEpisode.Episodes.Empty())
{
@@ -205,14 +120,6 @@ namespace NzbDrone.Core.DecisionEngine
}
}
private DownloadDecision GetDecisionForReport(RemoteMovie remoteEpisode, SearchCriteriaBase searchCriteria = null)
{
var reasons = _specifications.Select(c => EvaluateSpec(c, remoteEpisode, searchCriteria))
.Where(c => c != null);
return new DownloadDecision(remoteEpisode, reasons.ToArray());
}
private DownloadDecision GetDecisionForReport(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria = null)
{
var reasons = _specifications.Select(c => EvaluateSpec(c, remoteEpisode, searchCriteria))
@@ -236,36 +143,8 @@ namespace NzbDrone.Core.DecisionEngine
{
e.Data.Add("report", remoteEpisode.Release.ToJson());
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title + ", with spec: " + spec.GetType().Name);
//return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
//return null;
}
return null;
}
private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteMovie remoteEpisode, SearchCriteriaBase searchCriteriaBase = null)
{
try
{
var result = spec.IsSatisfiedBy(remoteEpisode, searchCriteriaBase);
if (!result.Accepted)
{
return new Rejection(result.Reason, spec.Type);
}
}
catch (NotImplementedException e)
{
_logger.Info("Spec " + spec.GetType().Name + " does not care about movies.");
}
catch (Exception e)
{
e.Data.Add("report", remoteEpisode.Release.ToJson());
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title + ", with spec: " + spec.GetType().Name);
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
return null;
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title);
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));
}
return null;

View File

@@ -7,7 +7,6 @@ namespace NzbDrone.Core.DecisionEngine
public interface IPrioritizeDownloadDecision
{
List<DownloadDecision> PrioritizeDecisions(List<DownloadDecision> decisions);
List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions);
}
public class DownloadDecisionPriorizationService : IPrioritizeDownloadDecision
@@ -30,17 +29,5 @@ namespace NzbDrone.Core.DecisionEngine
.Union(decisions.Where(c => c.RemoteEpisode.Series == null))
.ToList();
}
public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions)
{
return decisions.Where(c => c.RemoteMovie.Movie != null)
/*.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
{
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
})
.SelectMany(c => c)*/
.Union(decisions.Where(c => c.RemoteMovie.Movie == null))
.ToList();
}
}
}

View File

@@ -8,7 +8,5 @@ namespace NzbDrone.Core.DecisionEngine
RejectionType Type { get; }
Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria);
Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria);
}
}

View File

@@ -107,58 +107,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
_logger.Debug("Item: {0}, meets size constraints.", subject);
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
_logger.Debug("Beginning size check for: {0}", subject);
var quality = subject.ParsedMovieInfo.Quality.Quality;
if (subject.Release.Size == 0)
{
_logger.Debug("Release has unknown size, skipping size check.");
return Decision.Accept();
}
var qualityDefinition = _qualityDefinitionService.Get(quality);
if (qualityDefinition.MinSize.HasValue)
{
var minSize = qualityDefinition.MinSize.Value.Megabytes();
//Multiply maxSize by Series.Runtime
minSize = minSize * subject.Movie.Runtime;
//If the parsed size is smaller than minSize we don't want it
if (subject.Release.Size < minSize)
{
var runtimeMessage = subject.Movie.Title;
_logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage);
return Decision.Reject("{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage);
}
}
if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0)
{
_logger.Debug("Max size is unlimited - skipping check.");
}
else
{
var maxSize = qualityDefinition.MaxSize.Value.Megabytes();
//Multiply maxSize by Series.Runtime
maxSize = maxSize * subject.Movie.Runtime;
//If the parsed size is greater than maxSize we don't want it
if (subject.Release.Size > maxSize)
{;
_logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} for {3}), rejecting.", subject, subject.Release.Size, maxSize, subject.Movie.Title);
return Decision.Reject("{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), subject.Movie.Title);
}
}
_logger.Debug("Item: {0}, meets size constraints.", subject);
return Decision.Accept();
}
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
@@ -56,10 +55,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
throw new NotImplementedException();
}
}
}

View File

@@ -2,7 +2,6 @@ using NLog;
using NzbDrone.Core.Blacklisting;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
using System;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@@ -29,13 +28,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
throw new NotImplementedException();
return Decision.Accept();
}
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Core.IndexerSearch.Definitions;
@@ -35,18 +34,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
if (subject.Movie.MovieFile.Value != null)
{
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Movie.Profile, subject.Movie.MovieFile.Value.Quality, subject.ParsedMovieInfo.Quality))
{
return Decision.Reject("Existing file meets cutoff: {0}", subject.Movie.Profile.Value.Cutoff);
}
}
return Decision.Accept();
}
}
}

View File

@@ -30,16 +30,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
if (subject.Episodes.Any(e => !e.AirDateUtc.HasValue || e.AirDateUtc.Value.After(DateTime.UtcNow)))
{
_logger.Debug("Full season release {0} rejected. All episodes haven't aired yet.", subject.Release.Title);
//return Decision.Reject("Full season release rejected. All episodes haven't aired yet.");
return Decision.Reject("Full season release rejected. All episodes haven't aired yet.");
}
}
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
throw new NotImplementedException();
}
}
}

View File

@@ -29,20 +29,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
var wantedLanguage = subject.Movie.Profile.Value.Language;
_logger.Debug("Checking if report meets language requirements. {0}", subject.ParsedMovieInfo.Language);
if (subject.ParsedMovieInfo.Language != wantedLanguage)
{
_logger.Debug("Report Language: {0} rejected because it is not wanted, wanted {1}", subject.ParsedMovieInfo.Language, wantedLanguage);
return Decision.Reject("{0} is wanted, but found {1}", wantedLanguage, subject.ParsedMovieInfo.Language);
}
return Decision.Accept();
}
}
}

View File

@@ -36,37 +36,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
_logger.Debug("Checking if report meets minimum age requirements. {0}", age);
if (age < minimumAge)
{
_logger.Debug("Only {0} minutes old, minimum age is {1} minutes", age, minimumAge);
return Decision.Reject("Only {0} minutes old, minimum age is {1} minutes", age, minimumAge);
}
_logger.Debug("Release is {0} minutes old, greater than minimum age of {1} minutes", age, minimumAge);
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
if (subject.Release.DownloadProtocol != Indexers.DownloadProtocol.Usenet)
{
_logger.Debug("Not checking minimum age requirement for non-usenet report");
return Decision.Accept();
}
var age = subject.Release.AgeMinutes;
var minimumAge = _configService.MinimumAge;
if (minimumAge == 0)
{
_logger.Debug("Minimum age is not set.");
return Decision.Accept();
}
_logger.Debug("Checking if report meets minimum age requirements. {0}", age);
if (age < minimumAge)

View File

@@ -1,5 +1,4 @@
using System;
using NLog;
using NLog;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
@@ -26,16 +25,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
if (subject.Release.Title.ToLower().Contains("sample") && subject.Release.Size < 70.Megabytes())
{
_logger.Debug("Sample release, rejecting.");
return Decision.Reject("Sample");
}
return Decision.Accept();
}
}
}

View File

@@ -38,24 +38,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
var delayProfile = _delayProfileService.BestForTags(subject.Movie.Tags);
if (subject.Release.DownloadProtocol == DownloadProtocol.Usenet && !delayProfile.EnableUsenet)
{
_logger.Debug("[{0}] Usenet is not enabled for this series", subject.Release.Title);
return Decision.Reject("Usenet is not enabled for this series");
}
if (subject.Release.DownloadProtocol == DownloadProtocol.Torrent && !delayProfile.EnableTorrent)
{
_logger.Debug("[{0}] Torrent is not enabled for this series", subject.Release.Title);
return Decision.Reject("Torrent is not enabled for this series");
}
return Decision.Accept();
}
}
}

View File

@@ -26,17 +26,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
_logger.Debug("Checking if report meets quality requirements. {0}", subject.ParsedMovieInfo.Quality);
if (!subject.Movie.Profile.Value.Items.Exists(v => v.Allowed && v.Quality == subject.ParsedMovieInfo.Quality.Quality))
{
_logger.Debug("Quality {0} rejected by Series' quality profile", subject.ParsedMovieInfo.Quality);
return Decision.Reject("{0} is not wanted in profile", subject.ParsedMovieInfo.Quality.Quality);
}
return Decision.Accept();
}
}
}

View File

@@ -50,32 +50,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
var queue = _queueService.GetQueue()
.Select(q => q.RemoteMovie).ToList();
var matchingSeries = queue.Where(q => q.Movie.Id == subject.Movie.Id);
foreach (var remoteEpisode in matchingSeries)
{
_logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0}", remoteEpisode.ParsedEpisodeInfo.Quality);
if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Movie.Profile, remoteEpisode.ParsedMovieInfo.Quality, subject.ParsedMovieInfo.Quality))
{
return Decision.Reject("Quality for release in queue already meets cutoff: {0}", remoteEpisode.ParsedEpisodeInfo.Quality);
}
_logger.Debug("Checking if release is higher quality than queued release. Queued quality is: {0}", remoteEpisode.ParsedMovieInfo.Quality);
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Movie.Profile, remoteEpisode.ParsedMovieInfo.Quality, subject.ParsedMovieInfo.Quality))
{
return Decision.Reject("Quality for release in queue is of equal or higher preference: {0}", remoteEpisode.ParsedMovieInfo.Quality);
}
}
return Decision.Accept();
}
}
}

View File

@@ -42,27 +42,5 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
if (subject.Release == null || subject.Release.Container.IsNullOrWhiteSpace())
{
return Decision.Accept();
}
if (_dvdContainerTypes.Contains(subject.Release.Container.ToLower()))
{
_logger.Debug("Release contains raw DVD, rejecting.");
return Decision.Reject("Raw DVD release");
}
if (_blurayContainerTypes.Contains(subject.Release.Container.ToLower()))
{
_logger.Debug("Release contains raw Bluray, rejecting.");
return Decision.Reject("Raw Bluray release");
}
return Decision.Accept();
}
}
}

View File

@@ -62,46 +62,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return Decision.Accept();
}
public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
_logger.Debug("Checking if release meets restrictions: {0}", subject);
var title = subject.Release.Title;
var restrictions = _restrictionService.AllForTags(subject.Movie.Tags);
var required = restrictions.Where(r => r.Required.IsNotNullOrWhiteSpace());
var ignored = restrictions.Where(r => r.Ignored.IsNotNullOrWhiteSpace());
foreach (var r in required)
{
var requiredTerms = r.Required.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
var foundTerms = ContainsAny(requiredTerms, title);
if (foundTerms.Empty())
{
var terms = string.Join(", ", requiredTerms);
_logger.Debug("[{0}] does not contain one of the required terms: {1}", title, terms);
return Decision.Reject("Does not contain one of the required terms: {0}", terms);
}
}
foreach (var r in ignored)
{
var ignoredTerms = r.Ignored.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
var foundTerms = ContainsAny(ignoredTerms, title);
if (foundTerms.Any())
{
var terms = string.Join(", ", foundTerms);
_logger.Debug("[{0}] contains these ignored terms: {1}", title, terms);
return Decision.Reject("Contains these ignored terms: {0}", terms);
}
}
_logger.Debug("[{0}] No restrictions apply, allowing", subject);
return Decision.Accept();
}
private static List<string> ContainsAny(List<string> terms, string title)
{
return terms.Where(t => title.ToLowerInvariant().Contains(t.ToLowerInvariant())).ToList();

Some files were not shown because too many files have changed in this diff Show More