This commit is contained in:
Бахирев 2024-06-08 00:21:19 +03:00
parent cc83f8b3d6
commit 82cb9a1cb6
107 changed files with 942 additions and 860 deletions

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><line class="cls-1" x1="71.52" y1="103.43" x2="54.95" y2="103.43"/><path class="cls-1" d="M55.24,34.05v-11.85l8.58,4.77"/><path class="cls-1" d="M65.6,54.08s-18.8-1.09-10.35-20.02v-11.85"/><path class="cls-1" d="M88.45,34.05v-11.85l-8.58,4.77s-8.69-3.59-16.04,0"/><path class="cls-1" d="M78.1,54.08s18.8-1.09,10.35-20.02v-11.85"/><path class="cls-1" d="M36.67,88.45h18.88c2.68,0,4.86,2.18,4.86,4.86s-2.18,4.86-4.86,4.86h-19.7c-5.37,0-9.72-3.16-9.72-8.53,0,0-.45-5.46,5.54-7.64-4.02-24.93,20.33-29.02,21.51-41.09"/><path class="cls-1" d="M44.28,67.56c24.52-1.91,15.26,20.84,15.26,20.84"/><path class="cls-1" d="M80.31,83.82h6.83c4.85,0,8.79,3.94,8.79,8.79v10.83h-24.4v-10.83c0-4.85,3.94-8.79,8.79-8.79Z"/><path class="cls-1" d="M90.35,84.47c1.08-.42,2.25-.64,3.47-.64h4.22c5.57,0,10.09,4.84,10.09,10.84v8.77h-24.4"/><path class="cls-1" d="M87.53,50.4c2.41,10.08-.25,26.6-1.55,33.42"/><path class="cls-1" d="M59.87,63.89l4.9,29.42c.92,3.27,5.48,5.23,6.74,5.32"/><line class="cls-1" x1="76.34" y1="84.37" x2="76.21" y2="74.01"/><line class="cls-1" x1="62.42" y1="39.69" x2="68.14" y2="40.78"/><line class="cls-1" x1="82.87" y1="39.69" x2="77.14" y2="40.78"/><line class="cls-1" x1="72.41" y1="45.95" x2="73.09" y2="45.95"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M27.1,34.19c10.23,2.5,23.21,4,37.35,4s27.12-1.5,37.35-4"/><path class="cls-1" d="M29.13,60.51c9.77,1.19,22.01,1.9,35.32,1.9s25.56-.71,35.33-1.9"/><g><line class="cls-1" x1="26.71" y1="29.29" x2="32.25" y2="100.94"/><line class="cls-1" x1="102.18" y1="29.29" x2="96.64" y2="100.94"/></g><g><line class="cls-1" x1="36.21" y1="56.72" x2="36.21" y2="43.28"/><line class="cls-1" x1="46.92" y1="56.72" x2="46.92" y2="43.28"/><line class="cls-1" x1="52.78" y1="56.72" x2="52.78" y2="43.28"/><line class="cls-1" x1="60.18" y1="56.72" x2="60.18" y2="43.28"/><line class="cls-1" x1="65.9" y1="56.72" x2="65.9" y2="43.28"/><line class="cls-1" x1="84.7" y1="56.72" x2="84.7" y2="43.28"/><line class="cls-1" x1="92.69" y1="56.72" x2="92.69" y2="43.28"/><line class="cls-1" x1="36.21" y1="50" x2="39.66" y2="50"/><line class="cls-1" x1="36.21" y1="43.28" x2="41.56" y2="43.28"/><line class="cls-1" x1="52.78" y1="43.28" x2="60.18" y2="56.72"/><line class="cls-1" x1="84.7" y1="50" x2="92.69" y2="50"/><path class="cls-1" d="M77.98,46.64c0-1.76-1.42-3.18-3.18-3.18s-3.18,1.42-3.18,3.18,1.42,3.18,3.18,3.18"/><path class="cls-1" d="M71.62,53.17c0,1.76,1.42,3.18,3.18,3.18s3.18-1.42,3.18-3.18-1.42-3.18-3.18-3.18"/></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><line class="cls-1" x1="50.53" y1="59.27" x2="102.69" y2="59.27"/><g><line class="cls-1" x1="26.14" y1="59.27" x2="41.58" y2="59.27"/><polyline class="cls-1" points="34.41 59.23 38.9 48.33 51.84 44.51 55.25 31.85 67.37 21.36 78.95 39.47 86.58 40.02 97.07 59.23"/><polyline class="cls-1" points="34.41 64.72 38.9 78.17 51.84 82.88 55.25 98.52 67.37 111.47 78.95 89.11 86.58 88.43 97.07 64.72"/><line class="cls-1" x1="67.37" y1="21.36" x2="62.76" y2="35.59"/><line class="cls-1" x1="74.86" y1="48.67" x2="62.76" y2="35.59"/><line class="cls-1" x1="64.81" y1="48.87" x2="74.86" y2="48.67"/><line class="cls-1" x1="57.43" y1="59.27" x2="64.81" y2="48.87"/></g></svg>

After

Width:  |  Height:  |  Size: 903 B

View file

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M86.47,26.74H30.06c-2.15,0-3.9,1.76-3.9,3.9V99.94c0,2.15,1.76,3.9,3.9,3.9h62.07c2.15,0,3.9-1.76,3.9-3.9V54.07"/><rect class="cls-1" x="36.7" y="82.18" width="26.55" height="10.74"/><polyline class="cls-1" points="63.83 61.1 36.7 61.1 36.7 71.83 86.47 71.83 86.47 64.61"/><polyline class="cls-1" points="72.81 40.01 36.7 40.01 36.7 50.75 64.02 50.75"/><polygon class="cls-1" points="81.4 59.73 70.27 62.66 73.39 51.53 100.52 24.98 108.53 32.99 81.4 59.73"/></svg> <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><polyline class="cls-1" points="87.62 58 87.62 49.94 73.77 49.94 59.92 49.94 59.92 61.74 66.51 61.74"/><rect class="cls-1" x="32.21" y="49.94" width="27.71" height="11.8"/><rect class="cls-1" x="46.06" y="38.14" width="27.71" height="11.8"/><rect class="cls-1" x="59.91" y="26.34" width="27.71" height="11.8"/><polyline class="cls-1" points="66.51 61.74 59.92 61.74 46.06 61.74 46.06 73.54 58.29 73.54"/><rect class="cls-1" x="73.77" y="38.14" width="13.85" height="11.8"/><rect class="cls-1" x="18.35" y="61.74" width="27.71" height="11.8"/></g><circle class="cls-1" cx="80.7" cy="80.39" r="23.43"/><circle class="cls-1" cx="80.7" cy="80.39" r="5.54"/></svg>

Before

Width:  |  Height:  |  Size: 725 B

After

Width:  |  Height:  |  Size: 902 B

View file

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M76.94,97.96h21.46c2.15,0,3.9-1.76,3.9-3.9V40.53"/><path class="cls-1" d="M80.44,20.86H36.33c-2.15,0-3.9,1.76-3.9,3.9v47.37"/><polyline class="cls-1" points="92.74 51.45 42.96 51.45 42.96 60.27 92.74 60.27 92.74 51.45"/><line class="cls-1" x1="80.44" y1="20.86" x2="102.3" y2="40.53"/><line class="cls-1" x1="32.42" y1="72.13" x2="42.96" y2="72.13"/><line class="cls-1" x1="47.05" y1="80.74" x2="42.96" y2="72.13"/><line class="cls-1" x1="47.05" y1="80.74" x2="57.91" y2="80.74"/><line class="cls-1" x1="62" y1="89.35" x2="57.91" y2="80.74"/><line class="cls-1" x1="62" y1="89.35" x2="72.85" y2="89.35"/><line class="cls-1" x1="76.94" y1="97.96" x2="72.85" y2="89.35"/><g><path class="cls-1" d="M26.53,82.13v21.93c0,2.15,1.76,3.9,3.9,3.9h40.61"/><line class="cls-1" x1="26.53" y1="82.13" x2="37.07" y2="82.13"/><line class="cls-1" x1="41.16" y1="90.74" x2="37.07" y2="82.13"/><line class="cls-1" x1="41.16" y1="90.74" x2="52.01" y2="90.74"/><line class="cls-1" x1="56.1" y1="99.35" x2="52.01" y2="90.74"/><line class="cls-1" x1="56.1" y1="99.35" x2="66.95" y2="99.35"/><line class="cls-1" x1="71.05" y1="107.96" x2="66.95" y2="99.35"/></g><path class="cls-1" d="M102.3,40.53h-18.75c-1.72,0-3.11-1.39-3.11-3.11V20.86"/><g><polyline class="cls-1" points="70.29 34.14 42.96 34.14 42.96 42.95 70.29 42.95"/><line class="cls-1" x1="70.29" y1="34.14" x2="70.29" y2="42.95"/></g><g><polyline class="cls-1" points="92.74 68.76 65.41 68.76 65.41 77.58 92.74 77.58"/><line class="cls-1" x1="92.74" y1="68.76" x2="92.74" y2="77.58"/></g></svg> <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><rect class="cls-1" x="76.64" y="85.87" width="27.71" height="11.8"/><rect class="cls-1" x="48.93" y="85.87" width="27.71" height="11.8"/><rect class="cls-1" x="90.49" y="97.67" width="13.85" height="11.8"/><rect class="cls-1" x="62.78" y="97.67" width="27.71" height="11.8"/><rect class="cls-1" x="90.49" y="74.07" width="13.85" height="11.8"/><rect class="cls-1" x="71.77" y="68.22" width="16.87" height="11.8" transform="translate(56.42 -32.47) rotate(34.68)"/><rect class="cls-1" x="74.32" y="17.8" width="16.87" height="11.8" transform="translate(28.19 -42.87) rotate(34.68)"/><rect class="cls-1" x="29.82" y="23.75" width="27.71" height="11.8" transform="translate(8.84 -10.02) rotate(14.54)"/><rect class="cls-1" x="81.79" y="44.1" width="27.71" height="11.8" transform="translate(-11.42 36.43) rotate(-20.38)"/><rect class="cls-1" x="35.08" y="97.67" width="27.71" height="11.8"/><g><path class="cls-1" d="M50.23,62.27l3.06-2.49-4.54-5.58-3.06,2.49c-4.95-3.57-11.86-3.55-16.82,.48-5.93,4.82-6.82,13.54-2,19.47s13.54,6.82,19.47,2c4.96-4.04,6.38-10.8,3.89-16.37Z"/><line class="cls-1" x1="50.98" y1="56.94" x2="53.68" y2="54.74"/><polygon class="cls-1" points="53.68 54.74 56.35 45.85 58.31 51.55 66.58 43.21 63.57 49.97 75.32 45.11 64.86 52.7 70.93 55.06 60.22 55 60.77 59.69 53.68 54.74"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><path class="cls-1" d="M39.02,21.82v28.15c0,3.24,1.68,6.08,4.22,7.71,1.67,1.07,2.73,2.86,2.65,4.84l-1.61,41.85c0,2.21,1.79,4,4,4h0c2.21,0,4-1.79,4-4l-1.61-41.96c-.07-1.95,.96-3.72,2.58-4.8,2.48-1.64,4.12-4.45,4.12-7.64V21.82"/><line class="cls-1" x1="45.21" y1="21.82" x2="45.21" y2="43.21"/><line class="cls-1" x1="51.18" y1="21.82" x2="51.18" y2="43.21"/></g><path class="cls-1" d="M89.81,37.71c0-9.53-5.02-17.25-11.21-17.25s-11.21,7.73-11.21,17.25c0,7.01,2.72,13.04,6.63,15.73,1.85,1.27,2.65,3.37,2.54,5.61l-1.86,45.32c0,2.21,1.79,4,4,4s4-1.79,4-4l-1.98-45.44c-.1-2.2,.77-4.28,2.57-5.55,3.86-2.72,6.54-8.71,6.54-15.66Z"/></svg>

After

Width:  |  Height:  |  Size: 873 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><line class="cls-1" x1="111.34" y1="56.44" x2="89" y2="78.78"/><line class="cls-1" x1="111.34" y1="56.44" x2="89" y2="34.1"/><polyline class="cls-1" points="89 78.78 89 64.42 39.83 64.42"/><line class="cls-1" x1="89" y1="48.46" x2="89" y2="34.1"/><line class="cls-1" x1="89" y1="48.46" x2="58.44" y2="48.46"/></g><g><line class="cls-1" x1="17.49" y1="72.39" x2="39.83" y2="50.05"/><line class="cls-1" x1="17.49" y1="72.39" x2="39.83" y2="94.73"/><line class="cls-1" x1="39.83" y1="50.05" x2="39.83" y2="64.42"/><line class="cls-1" x1="39.83" y1="80.37" x2="39.83" y2="94.73"/><line class="cls-1" x1="39.83" y1="80.37" x2="70.39" y2="80.37"/></g></svg>

After

Width:  |  Height:  |  Size: 894 B

View file

@ -1,2 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>
</svg>

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M22 3.41 16.71 8.7 20 12h-8V4l3.29 3.29L20.59 2zM3.41 22l5.29-5.29L12 20v-8H4l3.29 3.29L2 20.59z"></path></svg>

After

Width:  |  Height:  |  Size: 195 B

View file

@ -1,3 +1 @@
<svg viewBox="0 0 24 24" fill="#84858D" xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"></path></svg>
<path d="M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 215 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M21 11V3h-8l3.29 3.29-10 10L3 13v8h8l-3.29-3.29 10-10z"></path></svg>

After

Width:  |  Height:  |  Size: 153 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V10h16v11zm0-13H4V5h16v3z"></path></svg>

Before

Width:  |  Height:  |  Size: 225 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V9h14v10zM5 7V5h14v2H5zm2 4h10v2H7zm0 4h7v2H7z"></path></svg>

Before

Width:  |  Height:  |  Size: 246 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M17 12c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm1.65 7.35L16.5 17.2V14h1v2.79l1.85 1.85-.7.71zM18 3h-3.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H6c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h6.11c-.59-.57-1.07-1.25-1.42-2H6V5h2v3h8V5h2v5.08c.71.1 1.38.31 2 .6V5c0-1.1-.9-2-2-2zm-6 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"></path></svg>

After

Width:  |  Height:  |  Size: 428 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5zm-9.18-6.95L7.4 14.46 10.94 18l5.66-5.66-1.41-1.41-4.24 4.24z"></path></svg>

After

Width:  |  Height:  |  Size: 248 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M16.5 10V9h-2v1H12v1.5h1v4c0 .83.67 1.5 1.5 1.5h2c.83 0 1.5-.67 1.5-1.5v-4h1V10zm0 5.5h-2v-4h2zM20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2m0 12H4V6h5.17l2 2H20z"></path></svg>

After

Width:  |  Height:  |  Size: 314 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8m.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></svg>

After

Width:  |  Height:  |  Size: 279 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2m0 16H5V10h14zm0-12H5V6h14zM9 14H7v-2h2zm4 0h-2v-2h2zm4 0h-2v-2h2zm-8 4H7v-2h2zm4 0h-2v-2h2zm4 0h-2v-2h2z"></path></svg>

After

Width:  |  Height:  |  Size: 306 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M3 14c0 1.3.84 2.4 2 2.82V20H3v2h6v-2H7v-3.18C8.16 16.4 9 15.3 9 14V6H3zm2-6h2v3H5zm0 5h2v1c0 .55-.45 1-1 1s-1-.45-1-1zm15.64-4.46-.96-.32c-.41-.14-.68-.52-.68-.95V3c0-.55-.45-1-1-1h-3c-.55 0-1 .45-1 1v4.28c0 .43-.27.81-.68.95l-.96.32c-.81.28-1.36 1.04-1.36 1.9V20c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-9.56c0-.86-.55-1.62-1.36-1.9M16 4h1v1h-1zm4 16h-7v-2h7zm0-4h-7v-2h7zm0-4h-7v-1.56l.95-.32C15.18 9.72 16 8.57 16 7.28V7h1v.28c0 1.29.82 2.44 2.05 2.85l.95.31z"></path></svg>

After

Width:  |  Height:  |  Size: 553 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M5 5h2v3h10V5h2v5h2V5c0-1.1-.9-2-2-2h-4.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h6v-2H5zm7-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1"></path><path d="M21 11.5 15.51 17l-3.01-3-1.5 1.5 4.51 4.5 6.99-7z"></path></svg>

After

Width:  |  Height:  |  Size: 340 B

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M17 12c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm1.65 7.35L16.5 17.2V14h1v2.79l1.85 1.85-.7.71zM18 3h-3.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H6c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h6.11c-.59-.57-1.07-1.25-1.42-2H6V5h2v3h8V5h2v5.08c.71.1 1.38.31 2 .6V5c0-1.1-.9-2-2-2zm-6 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M7 11h2v2H7zm14-5v14c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2l.01-14c0-1.1.88-2 1.99-2h1V2h2v2h8V2h2v2h1c1.1 0 2 .9 2 2M5 8h14V6H5zm14 12V10H5v10zm-4-7h2v-2h-2zm-4 0h2v-2h-2z"></path></svg>

Before

Width:  |  Height:  |  Size: 428 B

After

Width:  |  Height:  |  Size: 266 B

View file

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View file

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 660 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#58866B"><path d="M22.65 34h3V22h-3ZM24 18.3q.7 0 1.175-.45.475-.45.475-1.15t-.475-1.2Q24.7 15 24 15q-.7 0-1.175.5-.475.5-.475 1.2t.475 1.15q.475.45 1.175.45ZM24 44q-4.1 0-7.75-1.575-3.65-1.575-6.375-4.3-2.725-2.725-4.3-6.375Q4 28.1 4 23.95q0-4.1 1.575-7.75 1.575-3.65 4.3-6.35 2.725-2.7 6.375-4.275Q19.9 4 24.05 4q4.1 0 7.75 1.575 3.65 1.575 6.35 4.275 2.7 2.7 4.275 6.35Q44 19.85 44 24q0 4.1-1.575 7.75-1.575 3.65-4.275 6.375t-6.35 4.3Q28.15 44 24 44Zm.05-3q7.05 0 12-4.975T41 23.95q0-7.05-4.95-12T24 7q-7.05 0-12.025 4.95Q7 16.9 7 24q0 7.05 4.975 12.025Q16.95 41 24.05 41ZM24 24Z"/></svg>

After

Width:  |  Height:  |  Size: 660 B

View file

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 893 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><line class="cls-1" x1="71.52" y1="103.43" x2="54.95" y2="103.43"/><path class="cls-1" d="M55.24,34.05v-11.85l8.58,4.77"/><path class="cls-1" d="M65.6,54.08s-18.8-1.09-10.35-20.02v-11.85"/><path class="cls-1" d="M88.45,34.05v-11.85l-8.58,4.77s-8.69-3.59-16.04,0"/><path class="cls-1" d="M78.1,54.08s18.8-1.09,10.35-20.02v-11.85"/><path class="cls-1" d="M36.67,88.45h18.88c2.68,0,4.86,2.18,4.86,4.86s-2.18,4.86-4.86,4.86h-19.7c-5.37,0-9.72-3.16-9.72-8.53,0,0-.45-5.46,5.54-7.64-4.02-24.93,20.33-29.02,21.51-41.09"/><path class="cls-1" d="M44.28,67.56c24.52-1.91,15.26,20.84,15.26,20.84"/><path class="cls-1" d="M80.31,83.82h6.83c4.85,0,8.79,3.94,8.79,8.79v10.83h-24.4v-10.83c0-4.85,3.94-8.79,8.79-8.79Z"/><path class="cls-1" d="M90.35,84.47c1.08-.42,2.25-.64,3.47-.64h4.22c5.57,0,10.09,4.84,10.09,10.84v8.77h-24.4"/><path class="cls-1" d="M87.53,50.4c2.41,10.08-.25,26.6-1.55,33.42"/><path class="cls-1" d="M59.87,63.89l4.9,29.42c.92,3.27,5.48,5.23,6.74,5.32"/><line class="cls-1" x1="76.34" y1="84.37" x2="76.21" y2="74.01"/><line class="cls-1" x1="62.42" y1="39.69" x2="68.14" y2="40.78"/><line class="cls-1" x1="82.87" y1="39.69" x2="77.14" y2="40.78"/><line class="cls-1" x1="72.41" y1="45.95" x2="73.09" y2="45.95"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M27.1,34.19c10.23,2.5,23.21,4,37.35,4s27.12-1.5,37.35-4"/><path class="cls-1" d="M29.13,60.51c9.77,1.19,22.01,1.9,35.32,1.9s25.56-.71,35.33-1.9"/><g><line class="cls-1" x1="26.71" y1="29.29" x2="32.25" y2="100.94"/><line class="cls-1" x1="102.18" y1="29.29" x2="96.64" y2="100.94"/></g><g><line class="cls-1" x1="36.21" y1="56.72" x2="36.21" y2="43.28"/><line class="cls-1" x1="46.92" y1="56.72" x2="46.92" y2="43.28"/><line class="cls-1" x1="52.78" y1="56.72" x2="52.78" y2="43.28"/><line class="cls-1" x1="60.18" y1="56.72" x2="60.18" y2="43.28"/><line class="cls-1" x1="65.9" y1="56.72" x2="65.9" y2="43.28"/><line class="cls-1" x1="84.7" y1="56.72" x2="84.7" y2="43.28"/><line class="cls-1" x1="92.69" y1="56.72" x2="92.69" y2="43.28"/><line class="cls-1" x1="36.21" y1="50" x2="39.66" y2="50"/><line class="cls-1" x1="36.21" y1="43.28" x2="41.56" y2="43.28"/><line class="cls-1" x1="52.78" y1="43.28" x2="60.18" y2="56.72"/><line class="cls-1" x1="84.7" y1="50" x2="92.69" y2="50"/><path class="cls-1" d="M77.98,46.64c0-1.76-1.42-3.18-3.18-3.18s-3.18,1.42-3.18,3.18,1.42,3.18,3.18,3.18"/><path class="cls-1" d="M71.62,53.17c0,1.76,1.42,3.18,3.18,3.18s3.18-1.42,3.18-3.18-1.42-3.18-3.18-3.18"/></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><line class="cls-1" x1="50.53" y1="59.27" x2="102.69" y2="59.27"/><g><line class="cls-1" x1="26.14" y1="59.27" x2="41.58" y2="59.27"/><polyline class="cls-1" points="34.41 59.23 38.9 48.33 51.84 44.51 55.25 31.85 67.37 21.36 78.95 39.47 86.58 40.02 97.07 59.23"/><polyline class="cls-1" points="34.41 64.72 38.9 78.17 51.84 82.88 55.25 98.52 67.37 111.47 78.95 89.11 86.58 88.43 97.07 64.72"/><line class="cls-1" x1="67.37" y1="21.36" x2="62.76" y2="35.59"/><line class="cls-1" x1="74.86" y1="48.67" x2="62.76" y2="35.59"/><line class="cls-1" x1="64.81" y1="48.87" x2="74.86" y2="48.67"/><line class="cls-1" x1="57.43" y1="59.27" x2="64.81" y2="48.87"/></g></svg>

After

Width:  |  Height:  |  Size: 903 B

View file

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M86.47,26.74H30.06c-2.15,0-3.9,1.76-3.9,3.9V99.94c0,2.15,1.76,3.9,3.9,3.9h62.07c2.15,0,3.9-1.76,3.9-3.9V54.07"/><rect class="cls-1" x="36.7" y="82.18" width="26.55" height="10.74"/><polyline class="cls-1" points="63.83 61.1 36.7 61.1 36.7 71.83 86.47 71.83 86.47 64.61"/><polyline class="cls-1" points="72.81 40.01 36.7 40.01 36.7 50.75 64.02 50.75"/><polygon class="cls-1" points="81.4 59.73 70.27 62.66 73.39 51.53 100.52 24.98 108.53 32.99 81.4 59.73"/></svg> <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><polyline class="cls-1" points="87.62 58 87.62 49.94 73.77 49.94 59.92 49.94 59.92 61.74 66.51 61.74"/><rect class="cls-1" x="32.21" y="49.94" width="27.71" height="11.8"/><rect class="cls-1" x="46.06" y="38.14" width="27.71" height="11.8"/><rect class="cls-1" x="59.91" y="26.34" width="27.71" height="11.8"/><polyline class="cls-1" points="66.51 61.74 59.92 61.74 46.06 61.74 46.06 73.54 58.29 73.54"/><rect class="cls-1" x="73.77" y="38.14" width="13.85" height="11.8"/><rect class="cls-1" x="18.35" y="61.74" width="27.71" height="11.8"/></g><circle class="cls-1" cx="80.7" cy="80.39" r="23.43"/><circle class="cls-1" cx="80.7" cy="80.39" r="5.54"/></svg>

Before

Width:  |  Height:  |  Size: 725 B

After

Width:  |  Height:  |  Size: 902 B

View file

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><path class="cls-1" d="M76.94,97.96h21.46c2.15,0,3.9-1.76,3.9-3.9V40.53"/><path class="cls-1" d="M80.44,20.86H36.33c-2.15,0-3.9,1.76-3.9,3.9v47.37"/><polyline class="cls-1" points="92.74 51.45 42.96 51.45 42.96 60.27 92.74 60.27 92.74 51.45"/><line class="cls-1" x1="80.44" y1="20.86" x2="102.3" y2="40.53"/><line class="cls-1" x1="32.42" y1="72.13" x2="42.96" y2="72.13"/><line class="cls-1" x1="47.05" y1="80.74" x2="42.96" y2="72.13"/><line class="cls-1" x1="47.05" y1="80.74" x2="57.91" y2="80.74"/><line class="cls-1" x1="62" y1="89.35" x2="57.91" y2="80.74"/><line class="cls-1" x1="62" y1="89.35" x2="72.85" y2="89.35"/><line class="cls-1" x1="76.94" y1="97.96" x2="72.85" y2="89.35"/><g><path class="cls-1" d="M26.53,82.13v21.93c0,2.15,1.76,3.9,3.9,3.9h40.61"/><line class="cls-1" x1="26.53" y1="82.13" x2="37.07" y2="82.13"/><line class="cls-1" x1="41.16" y1="90.74" x2="37.07" y2="82.13"/><line class="cls-1" x1="41.16" y1="90.74" x2="52.01" y2="90.74"/><line class="cls-1" x1="56.1" y1="99.35" x2="52.01" y2="90.74"/><line class="cls-1" x1="56.1" y1="99.35" x2="66.95" y2="99.35"/><line class="cls-1" x1="71.05" y1="107.96" x2="66.95" y2="99.35"/></g><path class="cls-1" d="M102.3,40.53h-18.75c-1.72,0-3.11-1.39-3.11-3.11V20.86"/><g><polyline class="cls-1" points="70.29 34.14 42.96 34.14 42.96 42.95 70.29 42.95"/><line class="cls-1" x1="70.29" y1="34.14" x2="70.29" y2="42.95"/></g><g><polyline class="cls-1" points="92.74 68.76 65.41 68.76 65.41 77.58 92.74 77.58"/><line class="cls-1" x1="92.74" y1="68.76" x2="92.74" y2="77.58"/></g></svg> <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><rect class="cls-1" x="76.64" y="85.87" width="27.71" height="11.8"/><rect class="cls-1" x="48.93" y="85.87" width="27.71" height="11.8"/><rect class="cls-1" x="90.49" y="97.67" width="13.85" height="11.8"/><rect class="cls-1" x="62.78" y="97.67" width="27.71" height="11.8"/><rect class="cls-1" x="90.49" y="74.07" width="13.85" height="11.8"/><rect class="cls-1" x="71.77" y="68.22" width="16.87" height="11.8" transform="translate(56.42 -32.47) rotate(34.68)"/><rect class="cls-1" x="74.32" y="17.8" width="16.87" height="11.8" transform="translate(28.19 -42.87) rotate(34.68)"/><rect class="cls-1" x="29.82" y="23.75" width="27.71" height="11.8" transform="translate(8.84 -10.02) rotate(14.54)"/><rect class="cls-1" x="81.79" y="44.1" width="27.71" height="11.8" transform="translate(-11.42 36.43) rotate(-20.38)"/><rect class="cls-1" x="35.08" y="97.67" width="27.71" height="11.8"/><g><path class="cls-1" d="M50.23,62.27l3.06-2.49-4.54-5.58-3.06,2.49c-4.95-3.57-11.86-3.55-16.82,.48-5.93,4.82-6.82,13.54-2,19.47s13.54,6.82,19.47,2c4.96-4.04,6.38-10.8,3.89-16.37Z"/><line class="cls-1" x1="50.98" y1="56.94" x2="53.68" y2="54.74"/><polygon class="cls-1" points="53.68 54.74 56.35 45.85 58.31 51.55 66.58 43.21 63.57 49.97 75.32 45.11 64.86 52.7 70.93 55.06 60.22 55 60.77 59.69 53.68 54.74"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><path class="cls-1" d="M39.02,21.82v28.15c0,3.24,1.68,6.08,4.22,7.71,1.67,1.07,2.73,2.86,2.65,4.84l-1.61,41.85c0,2.21,1.79,4,4,4h0c2.21,0,4-1.79,4-4l-1.61-41.96c-.07-1.95,.96-3.72,2.58-4.8,2.48-1.64,4.12-4.45,4.12-7.64V21.82"/><line class="cls-1" x1="45.21" y1="21.82" x2="45.21" y2="43.21"/><line class="cls-1" x1="51.18" y1="21.82" x2="51.18" y2="43.21"/></g><path class="cls-1" d="M89.81,37.71c0-9.53-5.02-17.25-11.21-17.25s-11.21,7.73-11.21,17.25c0,7.01,2.72,13.04,6.63,15.73,1.85,1.27,2.65,3.37,2.54,5.61l-1.86,45.32c0,2.21,1.79,4,4,4s4-1.79,4-4l-1.98-45.44c-.1-2.2,.77-4.28,2.57-5.55,3.86-2.72,6.54-8.71,6.54-15.66Z"/></svg>

After

Width:  |  Height:  |  Size: 873 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128.83 128.83"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.93px;}</style></defs><g><line class="cls-1" x1="111.34" y1="56.44" x2="89" y2="78.78"/><line class="cls-1" x1="111.34" y1="56.44" x2="89" y2="34.1"/><polyline class="cls-1" points="89 78.78 89 64.42 39.83 64.42"/><line class="cls-1" x1="89" y1="48.46" x2="89" y2="34.1"/><line class="cls-1" x1="89" y1="48.46" x2="58.44" y2="48.46"/></g><g><line class="cls-1" x1="17.49" y1="72.39" x2="39.83" y2="50.05"/><line class="cls-1" x1="17.49" y1="72.39" x2="39.83" y2="94.73"/><line class="cls-1" x1="39.83" y1="50.05" x2="39.83" y2="64.42"/><line class="cls-1" x1="39.83" y1="80.37" x2="39.83" y2="94.73"/><line class="cls-1" x1="39.83" y1="80.37" x2="70.39" y2="80.37"/></g></svg>

After

Width:  |  Height:  |  Size: 894 B

View file

@ -1,2 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>
</svg>

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M22 3.41 16.71 8.7 20 12h-8V4l3.29 3.29L20.59 2zM3.41 22l5.29-5.29L12 20v-8H4l3.29 3.29L2 20.59z"></path></svg>

After

Width:  |  Height:  |  Size: 195 B

View file

@ -1,3 +1 @@
<svg viewBox="0 0 24 24" fill="#84858D" xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"></path></svg>
<path d="M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 215 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M21 11V3h-8l3.29 3.29-10 10L3 13v8h8l-3.29-3.29 10-10z"></path></svg>

After

Width:  |  Height:  |  Size: 153 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V10h16v11zm0-13H4V5h16v3z"></path></svg>

Before

Width:  |  Height:  |  Size: 225 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V9h14v10zM5 7V5h14v2H5zm2 4h10v2H7zm0 4h7v2H7z"></path></svg>

Before

Width:  |  Height:  |  Size: 246 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M17 12c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm1.65 7.35L16.5 17.2V14h1v2.79l1.85 1.85-.7.71zM18 3h-3.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H6c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h6.11c-.59-.57-1.07-1.25-1.42-2H6V5h2v3h8V5h2v5.08c.71.1 1.38.31 2 .6V5c0-1.1-.9-2-2-2zm-6 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"></path></svg>

After

Width:  |  Height:  |  Size: 428 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5zm-9.18-6.95L7.4 14.46 10.94 18l5.66-5.66-1.41-1.41-4.24 4.24z"></path></svg>

After

Width:  |  Height:  |  Size: 248 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M16.5 10V9h-2v1H12v1.5h1v4c0 .83.67 1.5 1.5 1.5h2c.83 0 1.5-.67 1.5-1.5v-4h1V10zm0 5.5h-2v-4h2zM20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2m0 12H4V6h5.17l2 2H20z"></path></svg>

After

Width:  |  Height:  |  Size: 314 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8m.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></svg>

After

Width:  |  Height:  |  Size: 279 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2m0 16H5V10h14zm0-12H5V6h14zM9 14H7v-2h2zm4 0h-2v-2h2zm4 0h-2v-2h2zm-8 4H7v-2h2zm4 0h-2v-2h2zm4 0h-2v-2h2z"></path></svg>

After

Width:  |  Height:  |  Size: 306 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M3 14c0 1.3.84 2.4 2 2.82V20H3v2h6v-2H7v-3.18C8.16 16.4 9 15.3 9 14V6H3zm2-6h2v3H5zm0 5h2v1c0 .55-.45 1-1 1s-1-.45-1-1zm15.64-4.46-.96-.32c-.41-.14-.68-.52-.68-.95V3c0-.55-.45-1-1-1h-3c-.55 0-1 .45-1 1v4.28c0 .43-.27.81-.68.95l-.96.32c-.81.28-1.36 1.04-1.36 1.9V20c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-9.56c0-.86-.55-1.62-1.36-1.9M16 4h1v1h-1zm4 16h-7v-2h7zm0-4h-7v-2h7zm0-4h-7v-1.56l.95-.32C15.18 9.72 16 8.57 16 7.28V7h1v.28c0 1.29.82 2.44 2.05 2.85l.95.31z"></path></svg>

After

Width:  |  Height:  |  Size: 553 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M5 5h2v3h10V5h2v5h2V5c0-1.1-.9-2-2-2h-4.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h6v-2H5zm7-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1"></path><path d="M21 11.5 15.51 17l-3.01-3-1.5 1.5 4.51 4.5 6.99-7z"></path></svg>

After

Width:  |  Height:  |  Size: 340 B

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M17 12c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm1.65 7.35L16.5 17.2V14h1v2.79l1.85 1.85-.7.71zM18 3h-3.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H6c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h6.11c-.59-.57-1.07-1.25-1.42-2H6V5h2v3h8V5h2v5.08c.71.1 1.38.31 2 .6V5c0-1.1-.9-2-2-2zm-6 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#84858D"><path d="M7 11h2v2H7zm14-5v14c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2l.01-14c0-1.1.88-2 1.99-2h1V2h2v2h8V2h2v2h1c1.1 0 2 .9 2 2M5 8h14V6H5zm14 12V10H5v10zm-4-7h2v-2h-2zm-4 0h2v-2h-2z"></path></svg>

Before

Width:  |  Height:  |  Size: 428 B

After

Width:  |  Height:  |  Size: 266 B

View file

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View file

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 660 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#58866B"><path d="M22.65 34h3V22h-3ZM24 18.3q.7 0 1.175-.45.475-.45.475-1.15t-.475-1.2Q24.7 15 24 15q-.7 0-1.175.5-.475.5-.475 1.2t.475 1.15q.475.45 1.175.45ZM24 44q-4.1 0-7.75-1.575-3.65-1.575-6.375-4.3-2.725-2.725-4.3-6.375Q4 28.1 4 23.95q0-4.1 1.575-7.75 1.575-3.65 4.3-6.35 2.725-2.7 6.375-4.275Q19.9 4 24.05 4q4.1 0 7.75 1.575 3.65 1.575 6.35 4.275 2.7 2.7 4.275 6.35Q44 19.85 44 24q0 4.1-1.575 7.75-1.575 3.65-4.275 6.375t-6.35 4.3Q28.15 44 24 44Zm.05-3q7.05 0 12-4.975T41 23.95q0-7.05-4.95-12T24 7q-7.05 0-12.025 4.95Q7 16.9 7 24q0 7.05 4.975 12.025Q16.95 41 24.05 41ZM24 24Z"/></svg>

After

Width:  |  Height:  |  Size: 660 B

View file

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 893 B

View file

@ -19,7 +19,6 @@
--border-radius-m: 8px; --border-radius-m: 8px;
--border-radius-l: 12px; --border-radius-l: 12px;
--color-first: #4162B5; --color-first: #4162B5;
--color-second: #ED675F; --color-second: #ED675F;

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import style from '../style/index.module.scss'; import style from '../style/map.module.scss';
import { getRandom } from '../helpers/level'; import { getRandom } from '../helpers/level';
interface IBlockProps { interface IBlockProps {

View file

@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
import { getRandomLevel } from '../helpers/level'; import { getRandomLevel } from '../helpers/level';
import Blocks from './Blocks'; import Blocks from './Blocks';
import style from '../style/index.module.scss'; import style from '../style/map.module.scss';
function getCitySize(percent: number): [number, number] { function getCitySize(percent: number): [number, number] {
if (percent > 70) return [20, 20]; if (percent > 70) return [20, 20];

View file

@ -1,27 +1,78 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import IHashMap from 'ts/interfaces/HashMap';
import UiKitButton from 'ts/components/UiKit/components/Button'; import UiKitButton from 'ts/components/UiKit/components/Button';
import Description from 'ts/components/Description';
import ShowSymbol from 'ts/components/ShowSymbol';
import { shuffle } from 'ts/helpers/random';
import CityMap from './components/CityMap'; import CityMap from './components/CityMap';
import style from './style/index.module.scss'; import style from './style/wrapper.module.scss';
interface ICityBuilderProps { interface IValue {
title: string;
value: number;
} }
function CityBuilder({}: ICityBuilderProps): React.ReactElement | null { function getTotal(valuesByKey: IHashMap<number>): number {
const [percent, setPercent] = useState<number>(5); return Object.values(valuesByKey || {})
.reduce((sum: number, value: number) => sum + value, 0);
}
function getRandomList(valuesByKey: IHashMap<number>): IValue[] {
const list = Object.entries(valuesByKey || {})
.map(([title, value]: any) => ({ title, value }));
return shuffle(list);
}
interface ICityBuilderProps {
valuesByTitle: IHashMap<number>;
}
function CityBuilder({
valuesByTitle,
}: ICityBuilderProps): React.ReactElement | null {
const [list, setList] = useState<IValue[]>([]);
const [selectedIndex, setSelectedIndex] = useState<number>(0);
const [total, setTotal] = useState<number>(100);
const lastIndex = list.length - 1;
useEffect(() => {
setTotal(getTotal(valuesByTitle));
setList(getRandomList(valuesByTitle));
}, [valuesByTitle]);
if (!list.length) return null;
const selected = list[selectedIndex];
const percent = Math.ceil(((selected.value || 0) * 100) / total);
return ( return (
<> <>
<ShowSymbol
text={selected.title}
length={20}
/>
<Description
text={`Сейчас в проекте есть ${selected.value || 0} файлов созданных этим пользователем. Это примерно ${percent}% от всех файлов в проекте.`}
/>
<div className={style.city_builder_control}>
<UiKitButton <UiKitButton
className={style.races_button} disabled={!selectedIndex}
className={style.city_builder_control_prev}
onClick={() => { onClick={() => {
setPercent(Math.random() * 100); setSelectedIndex(selectedIndex - 1);
}} }}
> />
rand <UiKitButton
</UiKitButton> disabled={selectedIndex === lastIndex}
className={style.city_builder_control_next}
onClick={() => {
setSelectedIndex(selectedIndex + 1);
}}
/>
<CityMap percent={percent} /> <CityMap percent={percent} />
</div>
</> </>
); );
} }

View file

@ -0,0 +1,35 @@
@import 'src/styles/variables';
.city_builder_control {
position: relative;
margin: 0 0 var(--space-xxl);
user-select: none;
background-color: var(--color-13);
&_prev,
&_next {
position: absolute;
top: 0;
bottom: 0;
display: block;
width: 30%;
height: 100%;
cursor: pointer;
border-radius: 0;
border: none;
color: transparent;
background-color: transparent;
}
&_prev {
left: 0;
right: 30%;
}
&_next {
left: 70%;
right: 100%;
}
}

View file

@ -17,6 +17,19 @@
margin-left: var(--space-l); margin-left: var(--space-l);
cursor: pointer; cursor: pointer;
} }
&_full_screen {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
padding: var(--space-xxl);
margin: 0;
border-radius: 0;
}
} }
@media print { @media print {

View file

@ -5,8 +5,9 @@ import { useTranslation } from 'react-i18next';
import ISort from 'ts/interfaces/Sort'; import ISort from 'ts/interfaces/Sort';
import Table from 'ts/components/Table'; import Table from 'ts/components/Table';
import Cards from 'ts/components/Cards'; import Cards from 'ts/components/Cards';
import { downloadExcel } from 'ts/helpers/File';
import viewSettings from 'ts/store/ViewSettings'; import viewSettings from 'ts/store/ViewSettings';
import globalScroll from 'ts/helpers/globalScroll';
import { downloadExcel } from 'ts/helpers/File';
import isMobile from 'ts/helpers/isMobile'; import isMobile from 'ts/helpers/isMobile';
import style from './index.module.scss'; import style from './index.module.scss';
@ -40,6 +41,7 @@ function DataView({
const urlParams = useParams<any>(); const urlParams = useParams<any>();
const defaultType = viewSettings.getItem(urlParams, isMobile ? 'cards' : 'table'); const defaultType = viewSettings.getItem(urlParams, isMobile ? 'cards' : 'table');
const [localType, setType] = useState<string>(type || defaultType); const [localType, setType] = useState<string>(type || defaultType);
const [fullSize, setFullSize] = useState<boolean>(false);
if (!rows || !rows.length) return null; if (!rows || !rows.length) return null;
@ -48,11 +50,13 @@ function DataView({
cards: './assets/icons/Table.svg', cards: './assets/icons/Table.svg',
}[localType]; }[localType];
const title = { const titleForType = {
table: 'Отобразить карточками', table: 'Отобразить карточками',
cards: 'Отобразить таблицой', cards: 'Отобразить таблицой',
}[localType]; }[localType];
const fullSizeClass = fullSize ? style.data_view_full_screen : '';
return ( return (
<> <>
<div style={{ position: 'relative' }}> <div style={{ position: 'relative' }}>
@ -68,9 +72,24 @@ function DataView({
}} }}
/> />
)} )}
{false && !isMobile && (
<img
title={'Развернуть'}
src="./assets/icons/OpenFullscreen.svg"
className={style.data_view_icon}
onClick={() => {
if (fullSize) {
globalScroll.off();
} else {
globalScroll.on();
}
setFullSize(!fullSize);
}}
/>
)}
{!isMobile && ( {!isMobile && (
<img <img
title={title} title={titleForType}
src={icon} src={icon}
className={style.data_view_icon} className={style.data_view_icon}
onClick={() => { onClick={() => {
@ -84,7 +103,10 @@ function DataView({
</div> </div>
{localType === 'table' && ( {localType === 'table' && (
<PageWrapper template="table"> <PageWrapper
template="table"
className={fullSizeClass}
>
<Table <Table
rows={rows} rows={rows}
sort={sort} sort={sort}

View file

@ -6,14 +6,15 @@ import style from './index.module.scss';
interface IExternalLinkProps { interface IExternalLinkProps {
link: string, link: string,
text: string, text: string,
className?: string,
} }
function ExternalLink({ link, text }: IExternalLinkProps) { function ExternalLink({ link, text, className }: IExternalLinkProps) {
return ( return (
<Link <Link
to={link} to={link}
target="_blank" target="_blank"
className={style.external_link} className={`${style.external_link} ${className || ''}`}
> >
{text} {text}
</Link> </Link>

View file

@ -3,6 +3,7 @@ import React from 'react';
import ICommit from 'ts/interfaces/Commit'; import ICommit from 'ts/interfaces/Commit';
import ExternalLink from 'ts/components/ExternalLink'; import ExternalLink from 'ts/components/ExternalLink';
import userSettings from 'ts/store/UserSettings'; import userSettings from 'ts/store/UserSettings';
import { getDate } from 'ts/helpers/formatter';
import dataGrip from 'ts/helpers/DataGrip'; import dataGrip from 'ts/helpers/DataGrip';
import style from '../styles/index.module.scss'; import style from '../styles/index.module.scss';
@ -23,19 +24,24 @@ function GetItem({ commit, mode }: IGetItemProps) {
<div className={style.get_list}> <div className={style.get_list}>
<div className={style.get_list_title}> <div className={style.get_list_title}>
<ExternalLink <ExternalLink
link={`${userSettings?.settings?.linksPrefix?.task || '/'}${commit.task}`}
text={commit.task} text={commit.task}
link={`${userSettings?.settings?.linksPrefix?.task || '/'}${commit.task}`}
className={style.get_list_task}
/> />
{prId && mode !== 'print' && ( {prId && mode !== 'print' && (
<ExternalLink <ExternalLink
text="pull request"
link={`${userSettings?.settings?.linksPrefix?.pr || '/'}${prId}`} link={`${userSettings?.settings?.linksPrefix?.pr || '/'}${prId}`}
text="PR" className={style.get_list_pr}
/> />
)} )}
</div> </div>
<div className={`${style.get_list_icon} ${className}`}> <div className={`${style.get_list_icon} ${className}`}>
{commit.taskNumber} {commit.taskNumber}
</div> </div>
<div className={style.get_list_date}>
{getDate(commit.date)}
</div>
</div> </div>
); );
} }

View file

@ -1,25 +1,37 @@
@import 'src/styles/variables'; @import 'src/styles/variables';
.get_list_container {
margin: 12px 0 24px 0;
}
.get_list { .get_list {
display: inline-block; display: inline-block;
padding: 0; min-width: 140px;
margin: 0 var(--space-sm) var(--space-sm) 0; padding: var(--space-m) var(--space-m) var(--space-s);
margin: 0 0 var(--space-sm) 0;
box-sizing: border-box; box-sizing: border-box;
vertical-align: top; vertical-align: top;
&:last-child { border: 1px solid var(--color-border);
margin: 0 var(--space-sm) 0 0; border-radius: var(--border-radius-s);
background-color: #F5F7F9;
&_container {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
padding: var(--space-m) var(--space-m) 0;
margin: var(--space-m) 0 var(--space-xxl) 0;
border: 1px solid var(--color-border);
border-radius: var(--border-radius-s);
background-color: white;
} }
&_title { &_title {
position: relative; position: relative;
font-size: var(--font-s); font-size: var(--font-s);
display: block; display: block;
min-height: 87px;
margin: 0 0 var(--space-s) 0; margin: 0 0 var(--space-s) 0;
padding: var(--space-xxl) var(--space-s); padding: var(--space-xxl) var(--space-s);
@ -66,6 +78,7 @@
border-radius: 32px; border-radius: 32px;
letter-spacing: 2px; letter-spacing: 2px;
border: 2px dotted white;
color: var(--color-black); color: var(--color-black);
background-color: var(--color-border); background-color: var(--color-border);
} }
@ -73,5 +86,26 @@
&_big_number { &_big_number {
letter-spacing: normal; letter-spacing: normal;
} }
&_task {
display: block;
margin: 0 auto;
}
&_pr {
display: block;
margin: var(--space-m) auto 0;
color: var(--color-grey);
}
&_date {
font-size: var(--font-s);
margin: var(--space-m) auto 0;
padding: var(--space-s) 0 0 0;
text-align: center;
color: var(--color-grey);
border-top: 1px solid var(--color-border);
}
} }

View file

@ -2,6 +2,7 @@ import React, { ReactNode, useEffect } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import isMobile from 'ts/helpers/isMobile'; import isMobile from 'ts/helpers/isMobile';
import globalScroll from 'ts/helpers/globalScroll';
import Header from './components/Header'; import Header from './components/Header';
import Body from './components/Body'; import Body from './components/Body';
@ -21,13 +22,7 @@ function Modal({
onClose, onClose,
children, children,
}: IModalProps) { }: IModalProps) {
useEffect(() => { useEffect(globalScroll.useOnOff, []);
const overflowY = document.body.style.overflowY;
document.body.style.overflowY = 'hidden';
return () => {
document.body.style.overflowY = overflowY;
};
}, []);
const childrenWithProps = React.Children.map(children, (child) => (React.isValidElement(child) const childrenWithProps = React.Children.map(children, (child) => (React.isValidElement(child)
? React.cloneElement( ? React.cloneElement(

View file

@ -4,14 +4,16 @@ import style from './index.module.scss';
interface IPageWrapperProps { interface IPageWrapperProps {
children: ReactNode | string | null; children: ReactNode | string | null;
className?: string;
template?: 'box' | 'table'; template?: 'box' | 'table';
} }
function PageWrapper({ function PageWrapper({
children, children,
className,
template, template,
}: IPageWrapperProps) { }: IPageWrapperProps) {
const className = template const localClassName = template
? `${style.main_wrapper} ${style.main_wrapper_white}` ? `${style.main_wrapper} ${style.main_wrapper_white}`
: `${style.main_wrapper}`; : `${style.main_wrapper}`;
@ -21,7 +23,7 @@ function PageWrapper({
return ( return (
<div <div
className={className} className={`${localClassName} ${className || ''}`}
style={css} style={css}
> >
{children} {children}

View file

@ -1,77 +0,0 @@
import React, { useEffect, useState } from 'react';
import { shuffle } from './index';
import Info from './Info';
import style from './index.module.scss';
const DURATION = {
MIN: 5,
BASE: 10,
};
const animations = [
'ease',
'ease-in',
'ease-out',
'ease-in-out',
'linear',
'cubic-bezier(0.1, 0.7, 1, 0.1)',
];
function getRandom(max: number) {
return Math.floor(Math.random() * (max - 0 + 1)) + 0;
}
interface ITrackProps {
title: string;
speed: number;
type?: string;
canStart?: boolean;
}
function Track({
title,
speed,
type,
canStart,
}: ITrackProps): React.ReactElement | null {
const modeIndex = getRandom(animations.length - 1);
const [mode] = useState<string>(animations[modeIndex]);
useEffect(() => {
shuffle(animations);
}, []);
if (!title) return null;
const duration = DURATION.MIN + (DURATION.BASE * (1 - speed)) * 3;
const classForMove = canStart ? style.races_track_animation : '';
return (
<div className={`${style.races_track} ${type || ''}`}>
{canStart && (
<Info
title={title}
duration={duration}
/>
)}
<div
className={`${style.races_track_car} ${type || ''} ${classForMove || ''}`}
style={{
animationTimingFunction: mode,
animationDuration: `${duration}s`,
}}
>
<div className={`${style.races_track_car_title} ${type || ''}`}>
{title}
</div>
</div>
</div>
);
}
Track.defaultProps = {
type: '',
canStart: false,
};
export default Track;

View file

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { shuffle, getRandom } from 'ts/helpers/random';
import style from '../styles/car.module.scss';
const animations = [
'ease',
'ease-in',
'ease-out',
'ease-in-out',
'linear',
'cubic-bezier(0.1, 0.7, 1, 0.1)',
];
interface ICarProps {
title: string;
duration: number;
type?: string;
canStart?: boolean;
}
function Car({
title,
duration,
type,
canStart,
}: ICarProps): React.ReactElement | null {
const modeIndex = getRandom(animations.length - 1);
const [mode] = useState<string>(animations[modeIndex]);
useEffect(() => {
shuffle(animations);
}, []);
const classForMove = canStart ? style.races_track_car_animation : '';
return (
<div
className={`${style.races_track_car} ${type || ''} ${classForMove || ''}`}
style={{
animationTimingFunction: mode,
animationDuration: `${duration}s`,
}}
>
<div className={`${style.races_track_car_title} ${type || ''}`}>
{title}
</div>
<img
className={style.races_track_car_cover}
src="./assets/games/car.png"
/>
</div>
);
}
Car.defaultProps = {
type: '',
canStart: false,
};
export default Car;

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import style from './index.module.scss'; import style from '../styles/info.module.scss';
interface IInfoProps { interface IInfoProps {
title: string; title: string;
@ -11,6 +11,7 @@ function Info({
title, title,
duration, duration,
}: IInfoProps): React.ReactElement | null { }: IInfoProps): React.ReactElement | null {
console.log(title);
return ( return (
<div <div
className={style.races_track_info} className={style.races_track_info}
@ -18,7 +19,7 @@ function Info({
animationDelay: `${duration + 1}s`, animationDelay: `${duration + 1}s`,
}} }}
> >
{title} 4
</div> </div>
); );
} }

View file

@ -0,0 +1,52 @@
import React from 'react';
import Info from './Info';
import Car from './Car';
import style from '../styles/index.module.scss';
const DURATION = {
MIN: 10,
BASE: 20,
};
interface ITrackProps {
title: string;
speed: number;
type?: string;
canStart?: boolean;
}
function Track({
title,
speed,
type,
canStart,
}: ITrackProps): React.ReactElement | null {
if (!title) return null;
const duration = DURATION.MIN + (DURATION.BASE * (1 - speed)) * 3;
return (
<div className={`${style.races_track} ${type || ''}`}>
{canStart && (
<Info
title={title}
duration={duration}
/>
)}
<Car
title={title}
duration={duration}
type={type}
canStart={canStart}
/>
</div>
);
}
Track.defaultProps = {
type: '',
canStart: false,
};
export default Track;

View file

@ -1,106 +0,0 @@
@import 'src/styles/variables';
.races {
position: relative;
margin: 0 auto var(--space-xxl);
border: var(--space-xs) solid var(--color-border);
border-left: none;
border-right: none;
&_track {
position: relative;
height: 70px;
padding: var(--space-xxs);
margin: 0 auto;
text-align: right;
border-bottom: 1px solid var(--color-border);
background-color: var(--color-grey);
&_car {
position: absolute;
top: 0;
left: 0;
width: 10%;
height: 100%;
background-image: url('../../../assets/games/car.png');
background-position: center center;
background-repeat: no-repeat;
background-size: auto 70%;
&_title {
font-size: 12px;
display: inline-block;
width: 100%;
margin: 0;
padding: var(--space-xss);
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
border: 1px solid var(--color-grey);
border-radius: var(--border-radius-s);
color: var(--color-black);
background-color: var(--color-border);
}
}
&_info {
font-size: 12px;
display: inline-block;
width: 10%;
height: 100%;
margin: 0 12%;
padding: var(--space-m);
text-align: left;
border-radius: var(--border-radius-l);
border: 1px solid var(--color-grey);
color: var(--color-black);
background-color: var(--color-border);
animation-name: races_track_info;
animation-iteration-count: 1;
animation-duration: 1s;
animation-direction: alternate;
animation-fill-mode: both;
}
&_animation {
animation-name: races_track_car;
animation-iteration-count: 1;
animation-direction: alternate;
animation-fill-mode: both;
}
}
&_button {
position: absolute;
top: var(--space-l);
left: calc(50% - 100px);
z-index: 1;
}
}
@keyframes races_track_car {
from {
left: 0;
}
to {
left: 90%;
}
}
@keyframes races_track_info {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View file

@ -2,15 +2,11 @@ import React, { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import UiKitButton from 'ts/components/UiKit/components/Button'; import UiKitButton from 'ts/components/UiKit/components/Button';
import { shuffle } from 'ts/helpers/random';
import Track from './Track'; import Track from './components/Track';
import style from './index.module.scss';
export function shuffle(items: any[]) { import style from './styles/index.module.scss';
// @ts-ignore
for (let j, x, i = items.length; i; j = parseInt(Math.random() * i), x = items[--i], items[i] = items[j], items[j] = x) {}
return items;
}
interface IRacesProps { interface IRacesProps {
tracks: { tracks: {
@ -25,10 +21,11 @@ function Races({
}: IRacesProps): React.ReactElement | null { }: IRacesProps): React.ReactElement | null {
const { t } = useTranslation(); const { t } = useTranslation();
const [showAnimation, setShowAnimation] = useState<boolean>(false); const [showAnimation, setShowAnimation] = useState<boolean>(false);
const [shuffleTracks] = useState<any>([...shuffle(tracks)]);
if (!tracks.length) return null; if (!tracks.length) return null;
const lines = shuffle(tracks).map((track: any) => { const lines = shuffleTracks.map((track: any) => {
return ( return (
<Track <Track
key={track.title} key={track.title}

View file

@ -0,0 +1,69 @@
@import 'src/styles/variables';
.races_track_car {
position: absolute;
top: 0;
left: 0;
width: 10%;
height: 100%;
text-align: center;
&_title {
font-size: 12px;
display: inline-block;
width: auto;
max-width: 100%;
margin: var(--space-xs) auto 0 auto;
padding: var(--space-xxs) var(--space-xs);
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid var(--color-grey);
border-radius: var(--border-radius-s);
color: var(--color-black);
background-color: white;
&:before {
content: ' ';
position: absolute;
top: 22px;
left: 47%;
display: block;
padding: 4px;
transform: rotate(45deg);
background-color: white;
}
}
&_cover {
font-size: 12px;
display: block;
height: 50%;
margin: 0 auto;
}
&_animation {
animation-name: races_track_car;
animation-iteration-count: 1;
animation-direction: alternate;
animation-fill-mode: both;
}
}
@keyframes races_track_car {
from {
left: 0;
}
to {
left: 90%;
}
}

View file

@ -0,0 +1,33 @@
@import 'src/styles/variables';
.races {
position: relative;
margin: 0 auto var(--space-xxl);
border: var(--space-xxl) solid var(--color-13);
border-left: none;
border-right: none;
user-select: none;
&_track {
position: relative;
height: 80px;
padding: var(--space-xxs);
margin: 0 auto;
text-align: right;
border-bottom: var(--space-xxs) dashed var(--color-border);
background-color: var(--color-grey);
&:first-child {
border-top: var(--space-xxs) dashed var(--color-border);
}
}
&_button {
position: absolute;
top: var(--space-l);
left: calc(50% - 100px);
z-index: 1;
}
}

View file

@ -0,0 +1,36 @@
@import 'src/styles/variables';
.races_track_info {
font-size: 28px;
font-weight: bold;
display: inline-block;
width: 60px;
height: 60px;
margin: 5px 12%;
padding: var(--space-s) 0;
text-align: center;
border-radius: 60px;
line-height: 40px;
box-sizing: border-box;
border: var(--space-xxs) solid var(--color-border);
color: var(--color-black);
background-color: white;
animation-name: races_track_info;
animation-iteration-count: 1;
animation-duration: 1s;
animation-direction: alternate;
animation-fill-mode: both;
}
@keyframes races_track_info {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View file

@ -20,6 +20,16 @@ function getClassName(recommendation?: any) {
}[type || RECOMMENDATION_TYPES.INFO] ?? style.recommendations_card_fact; }[type || RECOMMENDATION_TYPES.INFO] ?? style.recommendations_card_fact;
} }
function getImageUrl(recommendation?: any) {
const type = recommendation?.type;
return {
[RECOMMENDATION_TYPES.INFO]: './assets/recommendations/info.svg',
[RECOMMENDATION_TYPES.FACT]: './assets/recommendations/fact.svg',
[RECOMMENDATION_TYPES.WARNING]: './assets/recommendations/warning.svg',
[RECOMMENDATION_TYPES.ALERT]: './assets/recommendations/alert.svg',
}[type || RECOMMENDATION_TYPES.INFO] ?? './assets/recommendations/info.svg';
}
interface IRecommendationsProps { interface IRecommendationsProps {
recommendation: any; recommendation: any;
onClick: Function; onClick: Function;
@ -45,7 +55,10 @@ function Card({
onClick={isMobile ? onClick : undefined} onClick={isMobile ? onClick : undefined}
> >
<h5 className={style.recommendations_card_title}> <h5 className={style.recommendations_card_title}>
<span className={style.recommendations_card_icon}></span> <img
className={style.recommendations_card_icon}
src={getImageUrl(recommendation)}
/>
{localization.get(title, titleArgs)} {localization.get(title, titleArgs)}
</h5> </h5>
<Description <Description

View file

@ -46,14 +46,13 @@
position: absolute; position: absolute;
top: var(--space-s); top: var(--space-s);
right: var(--space-s); right: var(--space-s);
z-index: 0;
display: inline-block; display: inline-block;
width: 18px; width: 24px;
height: 18px; height: 24px;
background-repeat: no-repeat; opacity: 0.5;
background-position: center center;
background-size: 100% auto;
} }
&_button { &_button {
@ -64,28 +63,24 @@
&_info { &_info {
--color-temp-border: #97C2A9; --color-temp-border: #97C2A9;
--color-temp-icon: url('/assets/recommendations/info.svg');
--color-temp-bg: #E3F8EC; --color-temp-bg: #E3F8EC;
--color-temp-title: #58866B; --color-temp-title: #58866B;
} }
&_fact { &_fact {
--color-temp-border: var(--color-11); --color-temp-border: var(--color-11);
--color-temp-icon: url('/assets/recommendations/info.svg');
--color-temp-bg: #EFF7FF; --color-temp-bg: #EFF7FF;
--color-temp-title: var(--color-first); --color-temp-title: var(--color-first);
} }
&_warning { &_warning {
--color-temp-border: var(--color-21); --color-temp-border: var(--color-21);
--color-temp-icon: url('/assets/recommendations/warning.svg');
--color-temp-bg: #FFF5F2; --color-temp-bg: #FFF5F2;
--color-temp-title: #E8B06D; --color-temp-title: #E8B06D;
} }
&_error { &_error {
--color-temp-border: var(--color-12); --color-temp-border: var(--color-12);
--color-temp-icon: url('/assets/recommendations/alert.svg');
--color-temp-bg: #FFEFEE; --color-temp-bg: #FFEFEE;
--color-temp-title: #DD8B87; --color-temp-title: #DD8B87;
} }

View file

@ -1,77 +0,0 @@
import React from 'react';
import Description from 'ts/components/Description';
import localization from 'ts/helpers/Localization';
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
import style from '../styles/card.module.scss';
function getClassName(recommendation?: any) {
const type = recommendation?.type;
return {
[RECOMMENDATION_TYPES.INFO]: style.recommendations_card_info,
[RECOMMENDATION_TYPES.FACT]: style.recommendations_card_fact,
[RECOMMENDATION_TYPES.WARNING]: style.recommendations_card_warning,
[RECOMMENDATION_TYPES.ALERT]: style.recommendations_card_error,
}[type || RECOMMENDATION_TYPES.INFO] ?? style.recommendations_card_fact;
}
function getDescriptionText(recommendation?: any) {
const descriptionArgs = recommendation?.arguments?.description;
const { description } = recommendation;
const list = Array.isArray(description)
? description
: [description];
return list.map((textId: string) => (
localization.get(textId, descriptionArgs)
)).join('\n');
}
interface IRecommendationsProps {
recommendation: any;
}
function Card({
recommendation,
}: IRecommendationsProps) {
if (!recommendation) return null;
const { title } = recommendation;
let formattedTitle = title || '';
if (Array.isArray(title)) {
formattedTitle = title.length > 1
? `${title[0]} +${title.length - 1}`
: title[0];
}
const className = getClassName(recommendation);
const titleArgs = recommendation?.arguments?.title;
const parts = getDescriptionText(recommendation).split('\n');
const previewText = parts.shift();
const mainText = parts.join('\n');
return (
<div className={`${style.recommendations_card} ${className}`}>
<div className={style.recommendations_card_wrapper}>
<h5 className={style.recommendations_card_title}>
<span className={style.recommendations_card_icon}></span>
{localization.get(formattedTitle, titleArgs)}
</h5>
<Description
style={{ color: '#12131B' }}
text={previewText || ''}
/>
<div className={style.recommendations_card_shortcut}>
<Description
style={{ color: '#12131B' }}
text={mainText || ''}
/>
</div>
</div>
</div>
);
}
export default Card;

View file

@ -1,60 +0,0 @@
import React, { useLayoutEffect, useRef, useState } from 'react';
import Card from './components/Card';
import style from './styles/index.module.scss';
interface IRecommendationsProps {
recommendations: any[];
}
function Recommendations({
recommendations,
}: IRecommendationsProps) {
const [maxCardsOnDisplay, setMaxCardsOnDisplay] = useState<number>(5);
const [isOpen, setOpen] = useState<boolean>(false);
const ref = useRef() as React.MutableRefObject<HTMLDivElement>;
useLayoutEffect(() => {
const width = ref?.current?.offsetWidth;
const placeForCard = (width - 30) / (220 + 24);
setMaxCardsOnDisplay(placeForCard);
}, []);
const className = isOpen
? style.recommendations_full
: style.recommendations_short;
const children = (recommendations || [])
.filter(item => item)
.map((recommendation) => (
<Card
key={recommendation[1]}
recommendation={recommendation}
/>
));
const visibleChildren = children.slice(0, isOpen ? Infinity : maxCardsOnDisplay);
if (!children.length) return null;
return (
<div
ref={ref}
className={className}
>
{isOpen ? children : visibleChildren}
{!isOpen && children.length > maxCardsOnDisplay && (
<div
className={style.more}
onClick={() => {
setOpen(true);
}}
>
»
</div>
)}
</div>
);
}
export default Recommendations;

View file

@ -1,166 +0,0 @@
@import 'src/styles/variables';
.recommendations {
&_short,
&_full {
position: relative;
display: block;
max-height: 108px;
margin: 0 0 16px 0;
}
&_full {
max-height: none;
}
&_more,
&_card {
display: inline-block;
min-height: 100px;
max-height: 100px;
text-align: left;
vertical-align: top;
box-sizing: border-box;
white-space: normal;
border-radius: var(--border-radius-m);
background-color: white;
}
&_more {
position: absolute;
top: 0;
right: 0;
width: 30px;
margin: 0 0 8px 0;
text-align: center;
line-height: 100px;
cursor: pointer;
border: 1px solid var(--color-border);
color: #AAAAAA;
}
&_card {
position: relative;
width: 220px;
margin: 0 12px 16px 0;
border-left: none;
&_wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
display: block;
min-height: 100px;
max-height: 100px;
padding: 16px;
box-sizing: border-box;
overflow: hidden;
border-radius: var(--border-radius-m);
border: 1px solid var(--color-border);
border-left: 8px solid var(--color-border);
background-color: white;
}
&_icon {
position: absolute;
top: 16px;
left: 16px;
display: inline-block;
width: 18px;
height: 18px;
background-repeat: no-repeat;
background-position: center center;
background-size: 100% auto;
}
&_info {
--color-temp-border: #97C2A9;
--color-temp-icon: url('/assets/recommendations/info.svg');
--color-temp-bg: #E3F8EC;
--color-temp-title: #58866B;
}
&_fact {
--color-temp-border: var(--color-11);
--color-temp-icon: url('/assets/recommendations/info.svg');
--color-temp-bg: #EFF7FF;
--color-temp-title: var(--color-first);
}
&_warning {
--color-temp-border: var(--color-21);
--color-temp-icon: url('/assets/recommendations/warning.svg');
--color-temp-bg: #FFF5F2;
--color-temp-title: #E8B06D;
}
&_error {
--color-temp-border: var(--color-12);
--color-temp-icon: url('/assets/recommendations/alert.svg');
--color-temp-bg: #FFEFEE;
--color-temp-title: #DD8B87;
}
&_title {
font-weight: bold;
font-size: var(--font-xs);
display: block;
padding: 2px 0 0 24px;
margin: 0 auto 4px auto;
text-align: left;
text-decoration: none;
vertical-align: bottom;
color: var(--color-temp-title);
}
&_wrapper {
background-color: var(--color-temp-bg);
border-left-color: var(--color-temp-border);
}
}
}
.recommendations_card:hover > .recommendations_card_wrapper {
z-index: 2;
width: 170%;
max-height: 450px;
box-shadow: 2px 2px 3px #999999;
overflow-y: scroll;
}
.recommendations_card_wrapper::-webkit-scrollbar {
width: 8px;
background-color: transparent;
}
.recommendations_card_wrapper::-webkit-scrollbar-thumb {
background: #AAAAAA;
}
.recommendations_title {
color: var(--color-temp-border);
}
.recommendations_card_icon {
background-image: var(--color-temp-icon);
}
.recommendations_card_shortcut {
display: none;
padding: 6px 0 0 0;
margin: 6px 0 0 0;
border-top: 1px solid var(--color-temp-border);
}
.recommendations_card:hover .recommendations_card_shortcut {
display: block;
}

View file

@ -1,27 +0,0 @@
@import 'src/styles/variables';
.recommendations_short,
.recommendations_full {
position: relative;
display: block;
margin: 0 0 12px 0;
}
.more {
display: inline-block;
width: 30px;
margin: 0 0 8px 0;
text-align: center;
vertical-align: top;
box-sizing: border-box;
white-space: normal;
cursor: pointer;
border-radius: var(--border-radius-m);
line-height: 100px;
border: 1px solid var(--color-border);
color: var(--color-black);
background-color: white;
}

View file

@ -1,27 +0,0 @@
import React from 'react';
import Title from 'ts/components/Title';
import localization from 'ts/helpers/Localization';
import Recommendations from './index';
interface IRecommendationsWrapperProps {
recommendations: any[];
}
function RecommendationsWrapper({
recommendations,
}: IRecommendationsWrapperProps) {
if (!recommendations.length) return null;
const title = localization.get('recommendations.title');
return (
<>
<Title title={title}/>
<Recommendations recommendations={recommendations} />
</>
);
}
export default RecommendationsWrapper;

View file

@ -0,0 +1,31 @@
import React, { ReactNode } from 'react';
import style from '../styles/index.module.scss';
interface IButtonProps {
children: ReactNode;
onClick: Function;
mode?: string;
}
function Button({
children,
onClick,
mode,
}: IButtonProps): React.ReactElement | null {
const classNameMode = {
'table-row': style.show_symbol_s,
}[mode || ''] || '';
return (
<div
className={`${style.show_symbol} ${style.show_symbol_hide} ${classNameMode}`}
onClick={() => onClick()}
>
{children}
</div>
);
}
export default Button;

View file

@ -0,0 +1,40 @@
import React, { ReactNode, useEffect, useState } from 'react';
import style from '../styles/index.module.scss';
interface IOneSymbolProps {
show: boolean;
children: ReactNode;
mode?: string;
}
function OneSymbol({
show,
children,
mode,
}: IOneSymbolProps): React.ReactElement | null {
const [localShow, setShow] = useState<boolean>(false);
useEffect(() => {
setShow(show);
}, [show]);
const className = localShow ? style.show_symbol_hide : '';
const classNameBg = localShow ? style.show_symbol_bg_hide : '';
const classNameMode = {
'table-row': style.show_symbol_s,
}[mode || ''] || '';
return (
<div className={`${style.show_symbol} ${className} ${classNameMode}`}>
{children}
<div
className={`${style.show_symbol_bg} ${classNameBg}`}
onClick={() => setShow(true)}
/>
</div>
);
}
export default OneSymbol;

View file

@ -0,0 +1,71 @@
import React, { useEffect, useState } from 'react';
import OneSymbol from './components/OneSymbol';
import Button from './components/Button';
import style from './styles/index.module.scss';
function getSymbolList(text: string, length?: number) {
const list = (text || '').split('');
const lastIndex = length
? (length - 1)
: (list.length - 1);
if ((list.length - 1) > lastIndex) {
list[lastIndex] = '…';
}
return list;
}
interface IShowSymbolProps {
text: string;
length?: number;
mode?: string;
}
function ShowSymbol({
text,
length,
mode,
}: IShowSymbolProps): React.ReactElement | null {
const [showAll, setShowAll] = useState<boolean>(false);
useEffect(() => {
setShowAll(false);
}, [text]);
if (!text && !length) return null;
const list = getSymbolList(text, length);
const fakeList = length ? (new Array(length)).fill(1) : null;
const line = (fakeList || list)
.map((symbol: string, index: number) => (
<OneSymbol
key={`${text}|${symbol}|${index}`}
mode={mode}
show={showAll}
>
{list[index] || ''}
</OneSymbol>
));
return (
<div
className={`${style.show_symbol_wrapper}`}
style={{
paddingTop: mode === 'table-row' ? '8px' : 0,
}}
>
<Button
mode={mode}
onClick={() => setShowAll(true)}
>
»
</Button>
{line}
</div>
);
}
export default ShowSymbol;

View file

@ -0,0 +1,91 @@
@import 'src/styles/variables';
.show_symbol_wrapper {
white-space: nowrap;
}
.show_symbol {
--temp-font: var(--font-s);
--temp-width: 30px;
--temp-height: 40px;
user-select: none;
&_s {
--temp-font: var(--font-xxs);
--temp-width: 20px;
--temp-height: 30px;
}
font-size: var(--temp-font);
position: relative;
display: inline-block;
width: var(--temp-width);
height: var(--temp-height);
padding: 0;
margin: 0 var(--space-xxs) 0 0;
vertical-align: top;
text-transform: capitalize;
text-decoration: none;
text-align: center;
white-space: nowrap;
line-height: var(--temp-height);
transform: rotateY(180deg);
border: 1px solid var(--color-border);
color: var(--color-black);
background-color: white;
&_hide {
animation-name: show_symbol;
animation-duration: 1s;
}
&_bg {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
cursor: pointer;
background-color: var(--color-black);
&_hide {
// pointer-events: none;
animation-name: show_symbol_bg;
animation-duration: 0.4s;
}
}
}
.show_symbol_hide,
.show_symbol_bg_hide {
animation-iteration-count: 1;
animation-direction: alternate;
animation-fill-mode: both;
}
@keyframes show_symbol {
from {
transform: rotateY(180deg);
}
to {
transform: rotateY(0);
}
}
@keyframes show_symbol_bg {
from {
opacity: 1;
}
99% {
opacity: 1;
}
to {
opacity: 0;
}
}

View file

@ -1,6 +1,7 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import Logo from 'ts/pages/PageWrapper/components/sidebar/Logo'; import Logo from 'ts/pages/PageWrapper/components/sidebar/Logo';
import globalScroll from 'ts/helpers/globalScroll';
import style from './index.module.scss'; import style from './index.module.scss';
import progress from './progress.module.scss'; import progress from './progress.module.scss';
@ -8,11 +9,7 @@ import progress from './progress.module.scss';
function SplashScreen(): React.ReactElement | null { function SplashScreen(): React.ReactElement | null {
useEffect(() => { useEffect(() => {
const overflow = document.body.style.overflow; globalScroll.off(5400);
document.body.style.overflow = 'hidden';
setTimeout(() => {
document.body.style.overflow = overflow;
}, 5400);
}, []); }, []);
return ( return (

View file

@ -1,25 +0,0 @@
import React, { useState } from 'react';
import style from '../styles/index.module.scss';
interface ITitleProps {
title: string,
}
function Title({ title }: ITitleProps): React.ReactElement | null {
const [show, setShow] = useState<boolean>(false);
return (
<div className={`${style.tv100and1_cell_title}`}>
{title}
<button
className={`${style.tv100and1_button} ${show ? style.animation : ''}`}
onClick={() => {
setShow(true);
}}
/>
</div>
);
}
export default Title;

View file

@ -1,51 +0,0 @@
import React from 'react';
import LineChart from 'ts/components/LineChart';
import getOptions from 'ts/components/LineChart/helpers/getOptions';
import Title from './components/Title';
import style from './styles/index.module.scss';
interface ITv100And1Props {
rows: {
title: string,
value: number,
}[];
}
function Tv100And1({
rows = [],
}: ITv100And1Props): React.ReactElement | null {
if (!rows || !rows.length) return null;
const chartOptions = getOptions({ max: rows[0].value, suffix: 'сиволов' });
const formattedRows = rows.map((row: any) => (
<div
key={row.title}
className={`${style.tv100and1_row}`}
>
<Title title={row.title} />
<div className={`${style.tv100and1_cell_value}`}>
{row.value}
</div>
<div className={`${style.tv100and1_cell_chart}`}>
<LineChart
options={chartOptions}
value={row.value}
/>
</div>
</div>
));
return (
<div className={`${style.tv100and1}`}>
{formattedRows}
</div>
);
}
Tv100And1.defaultProps = {
rows: [],
};
export default Tv100And1;

View file

@ -1,90 +0,0 @@
@import 'src/styles/variables';
.tv100and1 {
&_row {
display: block;
white-space: nowrap;
}
&_cell_title,
&_cell_value,
&_cell_chart {
position: relative;
font-size: var(--font-xs);
display: inline-block;
padding: var(--space-m) 0;
line-height: var(--table-cell-height);
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
text-align: left;
}
&_cell_title {
width: 250px;
}
&_cell_value {
width: 50px;
text-align: right;
}
&_cell_chart {
width: calc(100% - 300px);
padding: 0;
}
&_button {
position: absolute;
left: 0;
right: 0;
bottom: 2px;
display: block;
height: calc(100% - 4px);
transform: rotate3d(1, 0, 0, 0);
box-sizing: border-box;
border: none;
cursor: pointer;
background-color: var(--color-grey);
background-image: url('../../../../assets/games/tv100and1.png');
background-repeat: repeat-x;
background-size: auto 100%;
&.animation {
animation-name: tv_100_and_1;
animation-iteration-count: 1;
animation-duration: 1s;
animation-direction: alternate;
animation-timing-function: ease-in;
animation-fill-mode: both;
}
}
}
@keyframes tv_100_and_1 {
from {
transform: rotate3d(1, 0, 0, 0);
}
10% {
transform: rotate3d(1, 0, 0, 90deg);
}
25% {
transform: rotate3d(1, 0, 0, 0);
}
55% {
transform: rotate3d(1, 0, 0, 90deg);
}
80% {
transform: rotate3d(1, 0, 0, 0);
}
to {
transform: rotate3d(1, 0, 0, 90deg);
}
}

View file

@ -0,0 +1,49 @@
import IHashMap from 'ts/interfaces/HashMap';
import { IDirtyFile } from 'ts/interfaces/FileInfo';
export default class FileGripByAuthor {
addedFilesByAuthor: IHashMap<number> = {};
addedWithoutRemoveFilesByAuthor: IHashMap<number> = {};
removedFilesByAuthor: IHashMap<number> = {};
totalAddedFiles: number = 0;
clear() {
this.addedFilesByAuthor = {};
this.addedWithoutRemoveFilesByAuthor = {};
this.removedFilesByAuthor = {};
this.totalAddedFiles = 0;
}
addFile(file: IDirtyFile) {
const create = file?.firstCommit?.author || '';
const remove = file?.lastCommit?.author || '';
if (!(create || remove) || file?.name?.[0] === '.') return;
this.#addNewAuthor(create);
this.#addNewAuthor(remove);
this.addedWithoutRemoveFilesByAuthor[create] += 1;
if (file.action !== 'D') {
this.addedFilesByAuthor[create] += 1;
} else {
this.removedFilesByAuthor[remove] += 1;
}
}
#addNewAuthor(author: string) {
const value = this.addedFilesByAuthor[author];
if (value || value === 0) return;
this.addedFilesByAuthor[author] = 0;
this.addedWithoutRemoveFilesByAuthor[author] = 0;
this.removedFilesByAuthor[author] = 0;
}
updateTotalInfo() {
this.totalAddedFiles = Object.values(this.addedFilesByAuthor)
.reduce((sum: number, value: number) => sum + value, 0);
}
}

View file

@ -5,6 +5,7 @@ import FileBuilder from './components/FileBuilder';
import FileGripByExtension from './components/extension'; import FileGripByExtension from './components/extension';
import FileGripByType from './components/type'; import FileGripByType from './components/type';
import FileGripByFolder from './components/folder'; import FileGripByFolder from './components/folder';
import FileGripByAuthor from './components/author';
class FileGrip { class FileGrip {
files: any = new FileBuilder(); files: any = new FileBuilder();
@ -17,12 +18,15 @@ class FileGrip {
removedTree: any = new FileGripByFolder(); removedTree: any = new FileGripByFolder();
author: any = new FileGripByAuthor();
clear() { clear() {
this.files.clear(); this.files.clear();
this.extension.clear(); this.extension.clear();
this.type.clear(); this.type.clear();
this.tree.clear(); this.tree.clear();
this.removedTree.clear(); this.removedTree.clear();
this.author.clear();
} }
addCommit(commit: ICommit | ISystemCommit) { addCommit(commit: ICommit | ISystemCommit) {
@ -37,6 +41,7 @@ class FileGrip {
this.files.updateTotalInfo((file: IDirtyFile) => { this.files.updateTotalInfo((file: IDirtyFile) => {
this.extension.addFile(file); this.extension.addFile(file);
this.type.addFile(file); this.type.addFile(file);
this.author.addFile(file);
if (file.action !== 'D') { if (file.action !== 'D') {
this.tree.addFile(file); this.tree.addFile(file);
} else { } else {
@ -46,6 +51,7 @@ class FileGrip {
this.extension.updateTotalInfo(); this.extension.updateTotalInfo();
this.type.updateTotalInfo(); this.type.updateTotalInfo();
this.author.updateTotalInfo();
this.tree.updateTotalInfo(); this.tree.updateTotalInfo();
this.removedTree.updateTotalInfo(); this.removedTree.updateTotalInfo();
} }

View file

@ -49,6 +49,10 @@ export default {
haveNotEmail: ACHIEVEMENT_TYPE.NORMAL, // Почтальон Печкин. Не заполнил поле e-mail haveNotEmail: ACHIEVEMENT_TYPE.NORMAL, // Почтальон Печкин. Не заполнил поле e-mail
hasCommitFrom0to7: ACHIEVEMENT_TYPE.BAD, // Ночной дозор hasCommitFrom0to7: ACHIEVEMENT_TYPE.BAD, // Ночной дозор
longWaitPR: ACHIEVEMENT_TYPE.BAD, // Обещать не значит жениться, ожидание PR больше месяца longWaitPR: ACHIEVEMENT_TYPE.BAD, // Обещать не значит жениться, ожидание PR больше месяца
lastCommit: ACHIEVEMENT_TYPE.NORMAL, // Я закончил. последний коммит на проекте
longTask: ACHIEVEMENT_TYPE.BAD, // Вроде изян. работал над задачей больше трех месяцев
noCommitOnDay: ACHIEVEMENT_TYPE.NORMAL, // Технический перерыв
firstCommit: ACHIEVEMENT_TYPE.NORMAL, // Кто первый, того и тапки. первый коммит на проекте
// Типаж Козерога, по месяцу первого коммита // Типаж Козерога, по месяцу первого коммита
horoscope1: ACHIEVEMENT_TYPE.NORMAL, // козерог horoscope1: ACHIEVEMENT_TYPE.NORMAL, // козерог
@ -66,15 +70,11 @@ export default {
// нет картинки // нет картинки
longestMessage: ACHIEVEMENT_TYPE.NORMAL, // А разговоров то было... longestMessage: ACHIEVEMENT_TYPE.NORMAL, // А разговоров то было...
noCommitOnDay: ACHIEVEMENT_TYPE.NORMAL, // Технический перерыв
commitsAfter1800: ACHIEVEMENT_TYPE.GOOD, // Делу время commitsAfter1800: ACHIEVEMENT_TYPE.GOOD, // Делу время
more3YearsInProject: ACHIEVEMENT_TYPE.GOOD, // Старожил. больше 3х лет на проекте more3YearsInProject: ACHIEVEMENT_TYPE.GOOD, // Старожил. больше 3х лет на проекте
firstCommit: ACHIEVEMENT_TYPE.NORMAL, // Кто первый, того и тапки. первый коммит на проекте
lastCommit: ACHIEVEMENT_TYPE.NORMAL, // Я закончил. последний коммит на проекте
moreLintHint: ACHIEVEMENT_TYPE.GOOD, // Грамар-наци. Больше всех внес в .eslintrc .stylelintrc.json moreLintHint: ACHIEVEMENT_TYPE.GOOD, // Грамар-наци. Больше всех внес в .eslintrc .stylelintrc.json
moreAddedFolders: ACHIEVEMENT_TYPE.NORMAL, // Директор, создал больше всех дирректорий moreAddedFolders: ACHIEVEMENT_TYPE.NORMAL, // Директор, создал больше всех дирректорий
workOnWeekends: ACHIEVEMENT_TYPE.BAD, // Работа не walk. хоть раз работал на выходных workOnWeekends: ACHIEVEMENT_TYPE.BAD, // Работа не walk. хоть раз работал на выходных
longTask: ACHIEVEMENT_TYPE.BAD, // Вроде изян. работал над задачей больше трех месяцев
fileRush: ACHIEVEMENT_TYPE.NORMAL, // Зерг Раш. Создал больше всех файлов в проекте fileRush: ACHIEVEMENT_TYPE.NORMAL, // Зерг Раш. Создал больше всех файлов в проекте
// нет кода // нет кода

View file

@ -0,0 +1,24 @@
let overflow = document.body.style.overflow;
function on() {
document.body.style.overflow = overflow;
}
function off(delay?: number) {
overflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
if (delay) setTimeout(on, delay);
}
function useOnOff() {
off();
return () => {
on();
};
}
export default {
on,
off,
useOnOff,
};

9
src/ts/helpers/random.ts Normal file
View file

@ -0,0 +1,9 @@
export function getRandom(max: number): number {
return Math.floor(Math.random() * (max - 0 + 1)) + 0;
}
export function shuffle(items: any[]): any[] {
// @ts-ignore
for (let j, x, i = items.length; i; j = parseInt(Math.random() * i), x = items[--i], items[i] = items[j], items[j] = x) {}
return items;
}

View file

@ -47,7 +47,7 @@ export const TEAM = [
id: 'day', id: 'day',
link: '/team/day', link: '/team/day',
title: 'sidebar.team.day', title: 'sidebar.team.day',
icon: './assets/menu/team_week.svg', icon: './assets/menu/team_day.svg',
}, },
{ {
id: 'week', id: 'week',
@ -59,13 +59,13 @@ export const TEAM = [
id: 'month', id: 'month',
link: '/team/month', link: '/team/month',
title: 'sidebar.team.month', title: 'sidebar.team.month',
icon: './assets/menu/team_date_1.svg', icon: './assets/menu/team_month.svg',
}, },
{ {
id: 'hours', id: 'hours',
link: '/team/hours', link: '/team/hours',
title: 'sidebar.team.hours', title: 'sidebar.team.hours',
icon: './assets/menu/team_date_2.svg', icon: './assets/menu/team_hours.svg',
}, },
{}, {},
{ {
@ -78,25 +78,25 @@ export const TEAM = [
id: 'removedFiles', id: 'removedFiles',
link: '/team/removedFiles', link: '/team/removedFiles',
title: 'sidebar.team.removedFiles', title: 'sidebar.team.removedFiles',
icon: './assets/menu/team_files.svg', icon: './assets/menu/team_files_remove.svg',
}, },
{ {
id: 'extension', id: 'extension',
link: '/team/extension', link: '/team/extension',
title: 'sidebar.team.extension', title: 'sidebar.team.extension',
icon: './assets/menu/team_files.svg', icon: './assets/menu/team_files_ext.svg',
}, },
{ {
id: 'tasks', id: 'tasks',
link: '/team/tasks', link: '/team/tasks',
title: 'sidebar.team.tasks', title: 'sidebar.team.tasks',
icon: './assets/menu/team_date_1.svg', icon: './assets/menu/team_tasks.svg',
}, },
{ {
id: 'release', id: 'release',
link: '/team/release', link: '/team/release',
title: 'sidebar.team.release', title: 'sidebar.team.release',
icon: './assets/menu/team_date_1.svg', icon: './assets/menu/team_release.svg',
}, },
{}, {},
{ {
@ -143,7 +143,7 @@ export const PERSON = [
id: 'day', id: 'day',
link: '/person/day/', link: '/person/day/',
title: 'sidebar.person.day', title: 'sidebar.person.day',
icon: './assets/menu/team_week.svg', icon: './assets/menu/team_day.svg',
}, },
{ {
id: 'week', id: 'week',
@ -155,20 +155,20 @@ export const PERSON = [
id: 'month', id: 'month',
link: '/person/month/', link: '/person/month/',
title: 'sidebar.person.month', title: 'sidebar.person.month',
icon: './assets/menu/team_date_1.svg', icon: './assets/menu/team_month.svg',
}, },
{ {
id: 'hours', id: 'hours',
link: '/person/hours/', link: '/person/hours/',
title: 'sidebar.person.hours', title: 'sidebar.person.hours',
icon: './assets/menu/team_date_2.svg', icon: './assets/menu/team_hours.svg',
}, },
{}, {},
{ {
id: 'tasks', id: 'tasks',
link: '/person/tasks/', link: '/person/tasks/',
title: 'sidebar.person.tasks', title: 'sidebar.person.tasks',
icon: './assets/menu/team_date_1.svg', icon: './assets/menu/team_tasks.svg',
}, },
{}, {},
{ {

View file

@ -3,20 +3,19 @@ import { observer } from 'mobx-react-lite';
import dataGripStore from 'ts/store/DataGrip'; import dataGripStore from 'ts/store/DataGrip';
import PageWrapper from 'ts/components/Page/wrapper';
import Title from 'ts/components/Title'; import Title from 'ts/components/Title';
import Races from 'ts/components/Races'; import Races from 'ts/components/Races';
import CityBuilder from 'ts/components/CityBuilder'; import CityBuilder from 'ts/components/CityBuilder';
import Tv100And1 from 'ts/components/Tv100And1';
import DataView from 'ts/components/DataView'; import DataView from 'ts/components/DataView';
import ShowSymbol from 'ts/components/ShowSymbol';
import Column from 'ts/components/Table/components/Column'; import Column from 'ts/components/Table/components/Column';
import LineChart from 'ts/components/LineChart'; import LineChart from 'ts/components/LineChart';
import getOptions from 'ts/components/LineChart/helpers/getOptions'; import getOptions from 'ts/components/LineChart/helpers/getOptions';
import { ColumnTypesEnum } from 'ts/components/Table/interfaces/Column'; import { ColumnTypesEnum } from 'ts/components/Table/interfaces/Column';
const Top = observer((): React.ReactElement => { const TeamBuilding = observer((): React.ReactElement => {
const filesByAuthor = dataGripStore.fileGrip.author?.addedFilesByAuthor;
const tracksAuth = dataGripStore.dataGrip.author.statistic const tracksAuth = dataGripStore.dataGrip.author.statistic
.filter((item: any) => !item.isStaff); .filter((item: any) => !item.isStaff);
@ -36,26 +35,26 @@ const Top = observer((): React.ReactElement => {
<> <>
<Title title="Скорость закрытия задач"/> <Title title="Скорость закрытия задач"/>
<Races tracks={tracks} /> <Races tracks={tracks} />
<Title title="Объем созданных файлов"/>
<CityBuilder />
{'Небоскребы вверх ввиде графика'}
<Title title="Максимальная длинна подписи коммита"/> <Title title="Максимальная длинна подписи коммита"/>
<Tv100And1 rows={maxMessageLength} />
<PageWrapper template="table">
<DataView rows={maxMessageLength}> <DataView rows={maxMessageLength}>
<Column <Column
isFixed isFixed
template={ColumnTypesEnum.STRING}
title="Сотрудник" title="Сотрудник"
properties="title" properties="title"
width={260} template={(text: string) => (
<ShowSymbol
text={text}
length={14}
mode="table-row"
/>
)}
width={360}
/> />
<Column <Column
template={ColumnTypesEnum.SHORT_NUMBER} template={ColumnTypesEnum.SHORT_NUMBER}
properties="value" properties="value"
width={40} width={50}
/> />
<Column <Column
title="Количество символов" title="Количество символов"
@ -68,10 +67,45 @@ const Top = observer((): React.ReactElement => {
)} )}
/> />
</DataView> </DataView>
</PageWrapper>
<Title title="Количество созданных файлов, если бы это был город"/>
<CityBuilder valuesByTitle={filesByAuthor} />
<Title title="Количество созданных папок"/>
<DataView rows={maxMessageLength}>
<Column
isFixed
title="Сотрудник"
properties="title"
template={(text: string) => (
<ShowSymbol
text={text}
length={14}
mode="table-row"
/>
)}
width={360}
/>
<Column
template={ColumnTypesEnum.SHORT_NUMBER}
properties="value"
width={50}
/>
<Column
title="Количество символов"
properties="value"
template={(messageLength: number) => (
<LineChart
options={chartMessageLength}
value={messageLength}
/>
)}
/>
</DataView>
{'Небоскребы вверх ввиде графика'}
</> </>
); );
}); });
export default Top; export default TeamBuilding;

View file

@ -18,7 +18,7 @@ import Type from './components/Type';
import Week from './components/Week'; import Week from './components/Week';
import Month from './components/Month'; import Month from './components/Month';
import Tasks from './components/Tasks'; import Tasks from './components/Tasks';
import Top from './components/Top'; import TeamBuilding from './components/Top';
import Pr from './components/PR'; import Pr from './components/PR';
import Print from './components/Print'; import Print from './components/Print';
import Release from './components/Release'; import Release from './components/Release';
@ -41,7 +41,7 @@ function getViewById(page?: string) {
if (page === 'commits') return <Commits/>; if (page === 'commits') return <Commits/>;
if (page === 'changes') return <Changes/>; if (page === 'changes') return <Changes/>;
if (page === 'words') return <PopularWords mode={mode}/>; if (page === 'words') return <PopularWords mode={mode}/>;
if (page === 'top') return <Top/>; if (page === 'building') return <TeamBuilding/>;
if (page === 'print') return <Print/>; if (page === 'print') return <Print/>;
if (page === 'tasks') return <Tasks/>; if (page === 'tasks') return <Tasks/>;
return <Total/>; return <Total/>;

View file

@ -27,7 +27,7 @@ export default `
§ sidebar.team.commits: All commits § sidebar.team.commits: All commits
§ sidebar.team.changes: Alle Änderungen § sidebar.team.changes: Alle Änderungen
§ sidebar.team.words: Beliebte Wörter § sidebar.team.words: Beliebte Wörter
§ sidebar.team.top: Quiz § sidebar.team.building: Quiz
§ sidebar.team.settings: Die Einstellungen § sidebar.team.settings: Die Einstellungen
§ sidebar.person.total: Allgemeine Informationen § sidebar.person.total: Allgemeine Informationen
§ sidebar.person.money: Arbeitskosten § sidebar.person.money: Arbeitskosten

View file

@ -27,7 +27,7 @@ export default `
§ sidebar.team.commits: All commits § sidebar.team.commits: All commits
§ sidebar.team.changes: All changes § sidebar.team.changes: All changes
§ sidebar.team.words: Popular words § sidebar.team.words: Popular words
§ sidebar.team.top: Quiz § sidebar.team.building: Quiz
§ sidebar.team.settings: Settings § sidebar.team.settings: Settings
§ sidebar.person.total: Common info § sidebar.person.total: Common info
§ sidebar.person.money: Work cost § sidebar.person.money: Work cost

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