КИЇВ. УМОВНА ЗИМА. ТВОЯ ЗМІНА.
Блекаутдиспетчер Світла не вистачить на всіх. Але за кожним вікном — хтось є.
Одна зміна на пульті міських електромереж. Тримай баланс. Памʼятай обіцянки. Відповідай мамі.
Прийняти зміну ↗ Продовжити
12 ХВИЛИН ОДНА ЗМІНА ТВОЇ РІШЕННЯ
«Не роби мені краще за всіх. Я термос набрала».
Мама · особиста лінія
ПЕРЕД ПЕРШИМ ДЗВІНКОМ
У якому вікні живеш ти? Свій дім, мама і друг опиняться в різних чергах. Кнопки ті самі. Рішення — вже особисте.
Твій масив Темп розмов На старті мережа перевантажена. У тебе 8 секунд, щоб вимкнути кілька черг і втримати ліміт. Черги, навантаження й персонажі вигадані. Це гра про вибір, а не справжній графік відключень.
Почати керування містом ↗ Назад МІСЬКІ ЕЛЕКТРОМЕРЕЖІ
Ти тримаєш Київ. Як грати Ⅱ Пауза
ЧАС У МІСТІ 06:00 Ранкова зміна
БАЛАНС МЕРЕЖІ Потрібна твоя увага
Зменш навантаження до позначки Увімкнено — світиться
СТАН МІСТА Прокидається Десять черг. Один ліміт.
РЕЙТИНГ ДИСПЕТЧЕРА 76 / 100
ДОВІРА МІСТА 65%
РИЗИК ЗВІЛЬНЕННЯ 0%
БЕЗ СВІТЛА 0 мешканців
Зніми напругу з однієї черги, щоб утримати навантаження в межах ліміту.
МІСТО У ТВОЇХ РУКАХ
Київ. Тримай світло. НАЖИВО
Обраний район КЛАВІШІ 1–0 · ПЕРЕМИКАННЯ
Міські служби Метро · вода · тепло
План на вечір 18:00 — 21:00 Обіцяй лише те вікно, яке готовий захищати.
Обіцяти світло
Захищений мінімум ЗАВЖДИ ПІД НАПРУГОЮ Базове аварійне живлення захищене. Метро, насоси та тепло керуються на панелі міських служб. Нижче — місцеві допоміжні резерви.
Переграти цю зміну ↗ До вибору зміни
ДИСПЕТЧЕРСЬКА
Час на ковток чаю
Повернутись до пульта ↗
Для гри потрібен JavaScript. Увімкніть його в браузері.
globalThis.BD={data:{"city-map":{"source":{"title":"Kyiv map with raions","author":"Winecko","date":"2022-08-09","url":"https://commons.wikimedia.org/wiki/File:Kyiv_map_with_raions.svg","license":"CC BY-SA 4.0","licenseUrl":"https://creativecommons.org/licenses/by-sa/4.0/","changes":"Extracted district polygons and river paths; rounded coordinates; new interactive relief and styling."},"districts":[{"id":"rusanivka","name":"Дніпровський","polygon":[[489.7,290.41],[476.36,292.87],[403.66,319.65],[374.27,275.32],[366.32,267.5],[349.13,254.09],[348.29,252.23],[345.53,239.5],[350.83,229.11],[360.61,216.51],[353.07,199.12],[356.54,196.61],[386.12,196.58],[422.56,195.37],[426.66,210.42],[421.45,218.93],[427.59,233.45],[439.51,239.66],[446.68,259.96],[445.25,266.48],[451.9,268.68],[457.54,266.45],[462.45,268.53],[465.27,276.69],[472.57,270.26],[476.23,272.81],[479.49,258.81],[471.51,255.74],[471.48,242.61],[561.0,203.47],[567.61,205.61],[567.45,218.21],[564.38,227.46],[568.6,233.39],[562.16,241.09],[523.66,276.53]],"label":[451,261],"urban":[440,275]},{"id":"pozniaky","name":"Дарницький","polygon":[[420.96,412.71],[429.48,427.9],[433.34,429.39],[423.51,432.81],[420.43,435.62],[423.51,441.68],[423.51,448.0],[417.01,437.9],[401.73,419.03],[396.9,399.28],[396.73,393.13],[398.75,378.82],[404.54,365.3],[409.02,340.02],[414.55,339.75],[419.38,340.54],[417.45,337.21],[410.78,335.8],[403.74,319.62],[476.38,292.86],[489.68,290.42],[523.66,276.53],[562.21,241.05],[569.5,239.58],[569.59,251.96],[571.61,255.12],[560.11,258.72],[573.1,269.7],[578.81,274.88],[579.42,276.72],[594.7,283.57],[593.64,291.56],[609.45,299.19],[615.33,307.62],[620.77,318.42],[613.4,326.76],[623.32,338.17],[634.73,340.46],[642.63,348.53],[637.8,352.48],[630.52,368.46],[615.5,366.35],[607.25,359.59],[606.46,357.31],[590.57,361.7],[589.43,371.89],[593.73,376.36],[590.48,382.42],[582.14,382.42],[587.68,388.3],[587.41,394.36],[588.73,399.36],[570.99,396.64],[558.53,400.77],[540.62,391.81],[540.53,389.79],[541.15,389.18],[532.63,379.26],[525.52,386.46],[524.38,391.02],[524.38,392.78],[523.15,392.69],[523.24,394.62],[526.66,398.31],[526.48,403.67],[524.29,403.67],[523.24,402.35],[522.62,402.35],[519.64,409.37],[525.61,420.26],[525.52,421.93],[524.55,423.07],[524.64,424.47],[507.52,435.53],[506.29,434.22],[506.38,432.64],[491.37,424.38],[487.42,425.7],[484.7,424.3],[484.7,419.91],[485.66,417.62],[484.34,413.67],[478.02,416.04],[456.16,418.5],[456.43,409.9],[445.1,409.46],[438.52,412.53]],"label":[517,369],"urban":[479,366]},{"id":"troieshchyna","name":"Деснянський","polygon":[[472.57,270.26],[465.28,276.69],[462.45,268.53],[457.54,266.44],[451.9,268.69],[445.24,266.48],[446.68,259.96],[439.5,239.66],[427.58,233.45],[421.44,218.92],[426.66,210.42],[422.57,195.37],[385.97,196.59],[356.54,196.61],[353.15,199.08],[349.89,191.47],[349.63,165.4],[353.89,153.07],[355.38,150.12],[357.2,147.91],[359.43,150.58],[372.44,151.51],[376.53,160.39],[383.49,160.39],[381.53,146.48],[369.27,131.49],[375.38,124.32],[473.56,134.56],[475.7,127.58],[481.35,117.71],[482.59,109.45],[487.99,105.48],[497.65,103.52],[517.95,91.39],[519.72,103.65],[535.48,101.38],[532.38,68.64],[543.62,54.54],[540.23,46.44],[551.59,46.47],[575.21,58.45],[590.67,58.45],[594.64,71.46],[605.38,70.47],[608.49,66.31],[619.75,81.39],[641.61,89.37],[637.51,91.6],[637.57,100.42],[640.58,101.51],[646.48,135.34],[642.23,138.44],[632.17,140.18],[620.37,146.36],[607.65,147.78],[586.6,160.6],[589.55,163.37],[586.39,168.64],[580.3,161.44],[574.41,161.54],[573.54,162.75],[573.57,165.38],[580.43,166.59],[582.63,177.61],[567.73,184.5],[570.62,188.66],[565.44,188.54],[557.46,194.53],[559.6,202.07],[561.02,203.46],[471.48,242.61],[471.52,255.74],[479.49,258.81],[476.24,272.82]],"label":[492,142],"urban":[475,169]},{"id":"teremky","name":"Голосіївський","polygon":[[436.53,625.72],[382.28,629.57],[386.37,588.72],[377.18,572.46],[356.45,572.34],[353.22,568.36],[356.58,556.44],[345.15,545.27],[349.5,537.32],[349.5,521.56],[330.87,520.07],[339.32,506.04],[334.97,499.83],[338.57,476.86],[319.7,472.27],[311.63,464.07],[301.7,469.91],[292.26,460.47],[297.6,456.75],[300.95,452.28],[291.39,446.19],[290.4,449.92],[278.23,452.77],[278.11,446.32],[283.57,441.23],[279.72,441.23],[277.24,424.71],[280.84,422.11],[281.46,415.4],[277.49,415.4],[273.39,407.7],[262.59,404.48],[256.88,416.52],[243.84,412.55],[240.37,407.33],[242.72,394.42],[236.27,388.34],[248.79,372.47],[252.51,365.52],[257.19,364.19],[260.57,367.66],[261.66,366.2],[262.69,362.35],[267.61,360.29],[267.75,356.4],[280.71,356.34],[283.46,349.58],[277.3,349.47],[281.78,345.25],[290.25,349.48],[296.3,342.82],[300.91,331.17],[303.63,328.76],[316.4,328.45],[308.43,316.2],[311.7,308.52],[317.59,308.37],[325.58,316.39],[319.87,298.18],[305.8,282.73],[311.97,278.18],[326.77,282.57],[327.5,307.45],[336.73,326.23],[333.87,333.3],[371.62,342.74],[382.51,328.61],[393.23,324.6],[393.57,367.11],[387.74,404.85],[409.71,435.02],[434.67,480.71],[447.58,505.79],[450.56,525.9],[449.49,542.02],[415.52,539.48],[415.52,546.77],[420.56,554.01],[422.58,566.56],[430.62,568.54],[431.71,579.56],[436.54,588.82]],"label":[322,444],"urban":[300,398]},{"id":"solomianskyi","name":"Солом’янський","polygon":[[290.24,349.48],[281.77,345.25],[277.3,349.48],[283.45,349.6],[280.72,356.34],[267.74,356.4],[267.62,360.28],[262.68,362.36],[261.66,366.21],[260.57,367.66],[257.19,364.19],[252.5,365.52],[248.78,372.48],[234.23,355.38],[231.33,355.29],[228.35,349.24],[222.64,343.27],[231.77,333.08],[240.55,321.32],[231.59,322.55],[206.4,274.44],[209.29,267.85],[224.31,253.54],[225.86,246.52],[274.26,262.5],[277.68,270.49],[287.69,267.5],[305.93,282.86],[319.87,298.18],[325.57,316.38],[317.59,308.37],[311.7,308.52],[308.43,316.2],[316.4,328.45],[303.63,328.76],[300.9,331.17],[296.3,342.83]],"label":[263,322],"urban":[270,316]},{"id":"pechersk","name":"Печерський","polygon":[[382.51,328.6],[371.62,342.74],[333.87,333.3],[336.72,326.23],[327.51,307.45],[326.76,282.6],[333.39,276.24],[333.56,270.0],[339.66,261.44],[339.66,256.79],[347.43,255.56],[366.31,270.22],[376.89,284.14],[386.41,310.12],[393.09,324.65]],"label":[361,303],"urban":[357,312]},{"id":"borshchahivka","name":"Святошинський","polygon":[[240.55,321.32],[231.78,333.07],[222.59,343.32],[201.01,332.16],[175.31,304.59],[166.49,285.29],[165.44,268.96],[158.3,265.42],[157.55,262.07],[154.57,265.55],[132.85,269.64],[116.46,269.52],[87.59,260.33],[87.65,268.77],[79.27,284.98],[80.83,287.09],[74.37,293.79],[66.73,286.4],[59.78,285.54],[57.3,292.49],[47.49,299.69],[40.35,286.53],[46.68,279.39],[46.43,274.67],[48.79,273.31],[50.41,273.31],[49.48,264.3],[43.39,254.19],[64.44,225.44],[63.38,220.73],[56.18,215.45],[58.66,209.8],[57.24,206.08],[60.4,196.14],[67.35,198.69],[75.42,188.57],[73.5,186.27],[78.65,179.44],[78.47,170.26],[69.28,159.64],[85.11,142.76],[91.69,142.57],[101.68,133.32],[100.69,131.33],[100.5,127.86],[104.41,123.64],[113.35,123.57],[116.33,107.74],[114.47,99.74],[174.19,155.92],[175.56,181.8],[206.53,202.85],[205.48,247.85],[225.86,246.56],[224.31,253.55],[209.3,267.85],[206.4,274.44],[231.6,322.55]],"label":[132,254],"urban":[171,260]},{"id":"lukianivka","name":"Шевченківський","polygon":[[326.79,282.57],[311.97,278.18],[305.79,282.75],[287.69,267.51],[277.68,270.49],[274.25,262.5],[238.53,250.69],[225.93,246.55],[205.47,247.85],[206.53,202.93],[221.63,217.31],[238.5,219.48],[246.69,205.45],[263.8,204.27],[269.01,212.35],[276.19,209.66],[277.58,213.43],[275.47,216.47],[279.14,218.62],[285.71,214.33],[287.72,217.65],[296.51,218.79],[296.54,227.45],[303.4,227.58],[305.55,237.71],[319.45,238.57],[321.65,251.54],[329.6,248.49],[337.68,250.52],[342.68,256.31],[339.67,256.8],[339.67,261.44],[333.56,270.01],[333.39,276.24]],"label":[281,262],"urban":[283,253]},{"id":"podil","name":"Подільський","polygon":[[238.5,219.48],[221.62,217.31],[206.37,202.73],[175.56,181.8],[174.19,155.95],[210.27,142.52],[265.61,138.71],[262.43,148.44],[263.57,181.5],[285.59,201.55],[294.7,203.41],[308.35,220.04],[313.58,211.87],[337.21,212.47],[345.27,210.59],[349.44,211.64],[354.28,211.35],[355.71,216.63],[340.93,237.67],[346.1,255.69],[342.69,256.33],[337.67,250.52],[329.6,248.51],[321.66,251.55],[319.45,238.57],[305.55,237.7],[303.41,227.59],[296.55,227.46],[296.51,218.8],[287.73,217.65],[285.71,214.33],[279.13,218.62],[275.47,216.47],[277.58,213.43],[276.18,209.68],[269.01,212.35],[263.8,204.28],[246.7,205.46]],"label":[263,200],"urban":[275,212]},{"id":"obolon","name":"Оболонський","polygon":[[210.28,142.51],[174.22,155.94],[114.67,99.92],[108.33,92.66],[111.55,89.37],[114.56,93.47],[124.28,89.34],[138.68,104.67],[140.48,98.12],[144.58,94.3],[145.45,87.6],[155.66,87.48],[145.63,83.81],[139.33,77.54],[141.38,75.43],[122.29,63.48],[159.2,59.45],[186.48,61.5],[185.4,49.55],[185.49,44.33],[187.51,41.51],[267.49,44.52],[280.59,48.55],[280.59,60.35],[290.71,62.37],[290.56,68.39],[300.49,68.48],[301.7,75.59],[315.01,75.53],[319.74,101.14],[352.48,131.46],[354.09,143.25],[347.14,162.81],[348.75,178.64],[347.57,194.72],[354.19,211.26],[352.73,211.45],[349.42,211.63],[345.28,210.59],[337.21,212.48],[313.59,211.86],[308.35,220.03],[294.72,203.41],[285.59,201.55],[263.57,181.49],[262.43,148.43],[265.59,138.71]],"label":[250,118],"urban":[270,145]}],"water":["M471.18,583.07 c -0.01,0.0 -0.08,0.04 -0.09,0.05 -0.01,0.01 -0.0,0.02 -0.0,0.03 -0.0,0.01 0.0,0.06 0.01,0.07 0.0,0.0 0.01,0.01 0.02,0.01 0.03,0.02 0.06,0.03 0.09,0.03 0.02,0.0 0.02,-0.01 0.04,-0.01 0.01,-0.0 0.01,-0.0 0.02,-0.0 0.0,-0.0 0.0,0.0 0.0,0.0 0.0,-0.0 -0.01,0.0 -0.01,0.0 -0.02,-0.01 0.01,-0.0 -0.01,-0.01 -0.01,-0.01 -0.02,-0.01 -0.03,-0.01 -0.0,-0.0 0.0,-0.0 0.0,-0.0 -0.0,-0.0 -0.01,-0.01 -0.01,-0.01 -0.0,-0.01 0.0,-0.05 0.0,-0.05 -0.01,-0.01 -0.02,0.01 -0.03,0.0 -0.01,-0.01 -0.0,-0.06 0.0,-0.07 z","M303.25,-11.38 l 5.5,13.5 2.62,4.5 4.5,13.38 6.62,7.62 v 11.0 l 4.25,2.62 -9.0,9.88 -9.75,21.25 5.0,2.12 -4.75,9.38 9.0,23.88 28.75,19.0 4.5,5.12 2.25,10.5 L 342.0,160.0 l 3.0,-8.38 1.0,-15.12 -7.88,3.25 0.5,22.62 h 4.0 l -4.25,4.12 -0.88,13.25 0.75,1.62 4.38,-2.75 2.5,-6.5 2.12,4.38 -3.0,9.12 2.62,5.75 -5.12,5.75 5.75,5.75 0.25,3.12 4.0,2.38 2.88,8.5 -12.75,15.75 -1.88,-3.5 -3.88,-6.12 2.62,-7.38 -5.5,5.62 -2.25,0.12 1.25,-5.12 -6.0,2.12 -1.62,-1.12 -3.25,-3.0 -7.5,-2.12 1.25,5.62 7.38,-0.38 -0.12,4.88 6.38,0.75 8.0,8.12 4.38,20.62 15.62,11.88 11.75,11.75 7.0,8.88 4.75,15.12 5.25,10.75 -3.5,1.38 -0.38,5.0 5.75,3.5 4.38,6.75 0.38,18.25 -2.12,12.12 0.62,13.25 -2.5,13.62 -4.75,8.62 -0.62,3.12 0.75,9.75 -4.62,-2.88 -2.88,2.62 5.5,5.0 -1.12,5.5 8.25,9.25 6.88,0.5 12.5,9.0 1.5,9.88 3.12,1.62 6.88,8.75 10.75,20.5 1.0,6.0 -2.12,0.25 -0.5,-4.25 -2.0,-5.38 -2.75,-0.38 -0.62,3.0 -3.88,-2.25 1.12,-3.5 -1.62,1.12 -0.38,-3.25 -3.62,1.12 -0.12,5.12 2.5,5.25 7.5,7.75 4.88,2.12 15.0,15.88 -0.88,1.25 -6.25,0.25 -2.38,-2.25 -1.88,1.88 -3.75,0.88 c 0.0,0.0 7.0,3.25 6.5,3.25 -0.5,0.0 -7.75,0.88 -7.75,0.88 l -5.75,-11.75 -7.12,-4.25 0.88,-9.62 -2.75,9.5 -10.62,-9.5 -0.12,-9.0 -1.75,10.88 15.5,12.25 6.62,8.5 -2.38,0.88 7.25,4.38 12.25,2.62 7.38,5.88 1.12,10.0 -4.0,7.0 c 0.0,0.0 5.5,3.5 4.88,4.12 C 449.0,542.5 445.5,545.0 445.5,545.0 l 0.25,8.62 c 0.0,0.0 1.62,1.25 1.25,1.75 -0.38,0.5 -1.62,0.5 -1.62,0.5 l -1.5,-1.38 -4.25,4.75 5.62,0.5 9.38,4.88 3.5,0.12 11.75,8.38 -3.25,3.88 3.62,6.62 c 0.0,0.0 41.25,1.88 44.12,1.38 0.75,0.62 19.38,0.12 19.38,0.12 l -0.62,-8.5 -7.88,-6.62 -0.88,-4.62 5.62,0.12 -7.12,-9.5 2.25,-4.38 -3.75,-2.62 -2.88,3.0 -6.62,3.25 -7.5,-5.75 -6.25,-9.25 -3.88,-0.12 -1.38,-10.75 -7.25,-0.62 -2.0,7.0 -2.38,-0.75 -0.88,-5.88 -2.0,-1.12 -1.0,-20.75 -2.25,-1.62 0.5,-7.75 -1.0,-6.12 -4.38,4.38 1.25,-10.25 0.25,-1.88 -4.0,-4.75 -1.0,4.38 -4.75,0.5 -0.75,2.5 -2.5,0.88 1.25,2.25 -0.12,4.0 -1.12,0.12 4.38,15.62 2.88,1.88 3.75,-2.38 4.88,10.88 -11.75,-4.5 -15.25,-29.88 -8.38,-9.0 -6.0,-21.88 -8.62,-12.88 -0.5,5.5 5.88,7.75 5.12,18.25 9.75,13.0 8.25,18.5 -13.38,-21.75 -7.0,-12.12 -6.12,-18.0 L 416.5,437.5 401.75,418.88 397.0,398.75 396.75,389.0 399.12,377.12 405.0,364.62 408.75,340.0 h 5.88 l 5.0,0.88 -2.25,-3.88 -7.0,-1.25 -7.0,-16.5 L 404.0,286.88 399.0,283.0 400.62,273.62 396.0,256.25 l -9.75,-18.62 -4.38,2.88 1.5,3.62 L 380.62,244.0 368.5,228.25 368.25,212.0 l 5.0,-3.5 1.25,0.12 8.75,-10.88 0.12,-22.5 -4.0,-12.88 -1.38,1.5 0.62,5.12 c 0.0,0.0 -9.88,5.0 -9.25,5.25 0.62,0.25 10.38,-0.88 10.38,-0.88 l 0.38,3.38 c 0.0,0.0 -9.0,4.0 -8.38,4.0 0.62,0.0 3.88,0.0 3.88,0.0 l -0.88,4.12 3.0,4.25 3.38,0.38 -1.12,4.88 -7.12,9.38 -1.75,-7.0 -3.88,-12.75 -6.88,9.62 10.25,12.25 -3.12,4.12 -1.88,-3.75 -1.25,14.5 3.88,16.25 8.5,10.75 5.12,23.25 4.0,-0.12 -4.25,-23.38 3.75,-2.0 1.75,4.38 6.88,7.88 1.12,11.0 2.62,4.62 -0.25,12.75 3.12,2.38 0.88,5.75 -1.75,2.38 1.12,4.88 -12.75,-10.38 -23.38,-40.25 -4.12,1.25 13.75,18.75 -0.25,4.25 -24.12,-21.0 -4.62,-15.12 5.75,-10.5 9.5,-11.62 L 349.5,191.0 l 0.25,-28.12 11.0,-20.25 -5.38,-12.88 -6.38,-7.62 -2.0,-9.38 4.88,-5.5 2.12,2.12 10.25,-2.0 4.75,2.88 5.88,3.38 11.38,0.88 3.62,-1.88 1.5,-6.62 -8.62,-5.0 -4.88,-6.5 6.38,-5.75 10.0,3.88 6.25,-0.62 12.88,-12.5 0.38,-9.12 -17.38,-10.12 -1.5,-5.25 8.0,-3.5 14.12,-9.0 10.38,4.12 4.5,5.38 6.0,0.12 9.25,-6.0 13.38,-5.0 7.38,-5.38 -0.12,-9.62 4.38,-3.75 -5.88,2.0 -8.12,-0.75 -4.25,-7.0 2.62,-3.38 h 24.88 l 8.88,7.5 -1.75,-6.5 14.75,8.25 27.12,-3.5 10.0,-4.38 -3.12,-3.12 -8.25,2.62 4.75,-8.0 -6.0,-5.0 -5.12,0.12 6.62,6.75 -3.5,5.38 -2.75,-2.12 -2.0,5.38 -8.0,-0.88 -0.88,3.25 -8.38,-0.12 -4.5,-6.25 h 2.25 L 498.25,7.0 l -3.38,-0.25 1.0,6.0 -4.75,-3.0 -26.5,-1.5 0.62,-1.5 h -9.12 l -8.75,5.88 1.5,7.25 14.12,10.25 0.38,3.88 -7.88,5.5 -12.88,4.12 -7.75,4.62 -5.0,-3.75 -1.5,-4.0 -6.12,-3.25 -13.88,4.25 -17.5,11.88 0.62,6.12 17.88,9.25 0.25,4.25 -3.5,2.75 -1.62,7.38 -7.0,5.5 -4.38,1.0 -6.12,-3.25 -8.0,-1.25 -4.88,5.0 2.38,8.75 7.12,6.5 2.0,6.0 -3.75,0.25 -7.5,-2.5 -6.25,-5.0 -9.12,-1.5 -5.88,-9.5 -4.25,-8.38 -0.5,-5.25 -5.12,-9.75 -1.0,-11.88 4.88,6.88 -2.0,-7.0 2.0,-3.12 -1.5,-4.38 L 337.38,50.0 335.5,55.5 331.38,52.0 335.5,43.5 347.38,45.88 353.0,40.25 356.38,29.5 c 0.0,0.0 -0.88,-12.62 -0.88,-14.25 0.0,-1.62 -3.12,-13.38 -3.12,-13.38 L 354.5,-10.5 355.25,-18.0 Z","M427.31,468.43 l 0.55,1.03 c 0.3,0.57 1.09,2.05 1.74,3.3 l 1.19,2.26 0.52,3.18 c 0.29,1.75 0.53,3.26 0.55,3.36 0.02,0.15 -0.24,0.22 -1.17,0.33 -0.65,0.08 -1.39,0.15 -1.63,0.16 l -0.45,0.01 -0.27,-2.34 c -0.27,-2.33 -0.27,-2.36 -1.16,-4.72 -0.49,-1.31 -0.95,-2.44 -1.04,-2.52 -0.08,-0.08 -0.53,-0.18 -0.99,-0.23 -0.96,-0.1 -0.81,-0.32 -1.23,1.75 -0.14,0.68 -0.27,1.27 -0.3,1.29 -0.04,0.04 -4.04,-2.21 -4.79,-2.7 -0.12,-0.08 -0.07,-0.36 0.22,-1.21 0.21,-0.61 0.38,-1.13 0.38,-1.15 0.0,-0.02 -0.21,0.1 -0.47,0.27 -0.56,0.38 -0.58,0.35 -0.71,-1.09 l -0.09,-0.97 h -1.35 -1.34 l -0.08,1.41 c -0.17,2.87 -0.22,2.61 1.14,5.43 l 1.22,2.53 3.66,3.8 3.66,3.8 2.44,1.05 2.44,1.05 6.84,7.24 c 3.76,3.98 7.23,7.66 7.7,8.16 l 0.86,0.92 -0.6,0.87 c -0.33,0.48 -0.63,0.89 -0.68,0.92 -0.04,0.03 -1.59,0.12 -3.42,0.2 l -3.34,0.15 -1.09,-1.01 -1.09,-1.01 -0.81,0.8 c -0.78,0.77 -0.85,0.81 -1.84,1.02 -0.57,0.12 -1.03,0.25 -1.03,0.29 0.0,0.04 1.1,0.62 2.44,1.29 1.87,0.93 2.47,1.3 2.59,1.54 0.22,0.49 0.0,0.72 -0.79,0.82 -4.21,0.5 -7.75,0.89 -7.78,0.85 -0.02,-0.03 -1.35,-2.72 -2.95,-5.99 l -2.9,-5.94 -3.58,-2.13 -3.58,-2.13 0.0,-0.56 c 0.0,-0.31 0.04,-1.15 0.09,-1.87 l 0.09,-1.31 -0.61,2.03 c -0.33,1.12 -0.64,2.06 -0.68,2.11 -0.04,0.04 -2.64,-2.22 -5.77,-5.02 l -5.7,-5.09 -0.02,-1.32 -0.02,-1.32 -0.33,2.0 -0.33,2.0 1.27,1.0 c 0.7,0.55 4.14,3.27 7.65,6.04 l 6.38,5.04 3.47,4.45 c 1.91,2.45 3.48,4.53 3.48,4.63 0.01,0.11 -0.32,0.3 -0.89,0.5 -0.77,0.27 -0.87,0.34 -0.69,0.46 0.12,0.08 1.54,0.93 3.15,1.9 l 2.94,1.75 6.06,1.29 6.06,1.29 3.84,3.05 c 2.11,1.68 3.84,3.09 3.84,3.14 -0.0,0.05 0.26,2.4 0.57,5.22 l 0.58,5.14 -1.82,3.17 c -1.0,1.75 -1.85,3.26 -1.88,3.36 -0.05,0.13 0.12,0.31 0.52,0.56 1.12,0.7 2.97,2.15 3.5,2.73 0.41,0.45 0.53,0.68 0.53,1.01 0.0,0.49 -0.22,0.7 -2.67,2.51 l -1.48,1.09 0.07,1.96 c 0.04,1.08 0.11,2.91 0.15,4.06 0.06,1.66 0.11,2.12 0.26,2.17 0.1,0.04 0.37,0.32 0.61,0.63 0.9,1.18 0.43,2.03 -1.23,2.23 -0.69,0.08 -0.7,0.08 -1.34,-0.49 l -0.65,-0.57 -1.53,1.71 c -0.84,0.94 -1.53,1.72 -1.52,1.73 0.01,0.01 1.05,0.11 2.31,0.23 l 2.3,0.21 4.64,2.42 4.64,2.42 1.81,0.09 1.81,0.09 6.06,4.31 c 3.33,2.37 6.11,4.35 6.17,4.4 0.06,0.05 -0.66,1.01 -1.6,2.12 l -1.7,2.03 0.3,0.52 c 0.16,0.29 0.9,1.62 1.64,2.97 l 1.34,2.46 1.15,0.07 c 5.42,0.35 31.5,1.29 38.71,1.4 2.37,0.04 5.58,0.11 7.12,0.15 3.07,0.09 10.39,0.06 13.58,-0.06 l 2.02,-0.07 -0.05,-0.52 c -0.03,-0.29 -0.16,-2.0 -0.29,-3.82 -0.13,-1.81 -0.28,-3.34 -0.34,-3.39 -0.06,-0.05 -1.82,-1.53 -3.92,-3.29 l -3.82,-3.2 -0.47,-2.54 c -0.26,-1.4 -0.5,-2.64 -0.54,-2.78 -0.06,-0.23 0.01,-0.24 2.51,-0.16 1.42,0.05 2.58,0.06 2.58,0.04 0.0,-0.02 -1.49,-2.03 -3.31,-4.45 l -3.31,-4.4 1.09,-2.11 c 1.07,-2.06 1.08,-2.11 0.84,-2.3 -0.14,-0.11 -0.8,-0.57 -1.48,-1.04 l -1.23,-0.85 -1.25,1.34 -1.25,1.34 -3.56,1.74 -3.56,1.74 -3.92,-3.0 -3.92,-3.0 -3.04,-4.5 c -1.67,-2.48 -3.08,-4.52 -3.13,-4.55 -0.05,-0.03 -0.98,-0.09 -2.07,-0.13 l -1.99,-0.08 -0.67,-5.32 c -0.37,-2.93 -0.69,-5.35 -0.72,-5.38 -0.06,-0.07 -6.2,-0.61 -6.27,-0.55 -0.03,0.02 -0.5,1.6 -1.04,3.51 -0.55,1.91 -1.01,3.49 -1.04,3.51 -0.02,0.02 -0.77,-0.19 -1.65,-0.47 l -1.62,-0.51 -0.43,-2.96 -0.43,-2.96 -0.91,-0.52 c -0.5,-0.29 -0.96,-0.57 -1.02,-0.63 -0.06,-0.06 -0.31,-4.3 -0.55,-9.42 -0.24,-5.12 -0.48,-9.78 -0.52,-10.35 l -0.08,-1.04 -1.11,-0.82 c -0.63,-0.46 -1.11,-0.91 -1.11,-1.03 0.0,-0.11 0.11,-1.9 0.25,-3.96 l 0.25,-3.75 -0.4,-2.53 -0.4,-2.54 -2.35,2.35 c -1.76,1.76 -2.35,2.28 -2.35,2.08 0.0,-0.33 1.47,-12.5 1.56,-12.87 0.05,-0.2 -0.3,-0.7 -1.43,-2.04 -0.82,-0.98 -1.53,-1.78 -1.59,-1.8 -0.05,-0.01 -0.27,0.75 -0.48,1.69 -0.21,0.94 -0.41,1.74 -0.44,1.77 -0.03,0.03 -1.07,0.15 -2.3,0.27 -1.24,0.12 -2.31,0.28 -2.39,0.36 -0.08,0.08 -0.26,0.59 -0.42,1.14 -0.33,1.14 -0.4,1.26 -0.83,1.37 -0.17,0.04 -0.62,0.19 -0.99,0.33 l -0.67,0.25 0.5,0.88 0.5,0.88 -0.09,2.35 -0.09,2.36 -0.46,0.04 -0.46,0.04 2.07,7.39 2.07,7.39 0.82,0.51 c 0.45,0.28 0.99,0.62 1.2,0.76 l 0.38,0.25 1.98,-1.25 c 1.09,-0.69 1.99,-1.24 2.01,-1.22 0.1,0.1 5.64,12.54 5.6,12.58 -0.06,0.07 -12.96,-4.88 -13.12,-5.04 -0.08,-0.08 -3.56,-6.84 -7.73,-15.02 l -7.59,-14.88 -4.21,-4.54 -4.21,-4.54 -1.13,-4.14 -1.13,-4.14 -1.02,-0.04 c -0.77,-0.03 -1.02,0.0 -1.02,0.12 0.0,0.09 0.28,1.12 0.61,2.29 l 0.61,2.12 4.87,6.5 4.88,6.5 4.13,9.28 4.13,9.28 -0.43,0.26 c -0.24,0.14 -0.47,0.25 -0.52,0.25 -0.19,-0.01 -13.82,-22.39 -17.06,-28.0 -2.89,-5.01 -3.5,-6.15 -3.87,-7.25 l -0.43,-1.31 -2.02,-0.04 z","M 303.0,-10.78 355.0,-17.12","M474.86,609.53 c 0.0,-0.01 -0.69,-2.52 -1.53,-5.58 l -1.53,-5.57 -0.52,-7.09 c -0.28,-3.9 -0.52,-7.1 -0.52,-7.11 0.0,-0.01 0.2,-0.01 0.45,-0.0 1.21,0.06 6.54,0.29 9.52,0.41 12.08,0.5 20.5,0.8 27.17,0.96 1.24,0.03 4.88,0.04 6.22,0.02 0.15,-0.0 0.42,0.02 0.59,0.05 0.82,0.14 2.07,0.18 5.68,0.2 l 3.09,0.02 v 11.85 11.85 h -24.31 c -13.37,0.0 -24.31,-0.01 -24.31,-0.01 z","M495.33,641.94 c -3.31,-1.37 -6.14,-2.62 -6.29,-2.78 -0.15,-0.16 -2.5,-3.66 -5.21,-7.78 l -4.93,-7.49 -1.95,-7.1 -1.95,-7.1 24.27,-0.04 24.27,-0.04 v -11.82 -11.82 l 3.58,-0.12 c 1.97,-0.07 4.05,-0.1 4.63,-0.06 l 1.05,0.06 3.31,5.21 c 3.05,4.8 3.5,5.61 5.62,10.21 l 2.31,5.0 v 17.76 c 0.0,12.47 -0.06,17.76 -0.19,17.76 -0.1,0.0 -9.46,0.6 -20.8,1.33 -11.34,0.73 -20.86,1.32 -21.16,1.32 -0.3,-0.0 -3.25,-1.13 -6.56,-2.49 z","M427.12,467.97 c -0.13,-0.22 -1.78,-3.34 -3.66,-6.94 l -3.41,-6.54 -3.11,-3.98 c -4.03,-5.15 -3.86,-4.97 -5.48,-5.81 -0.98,-0.51 -1.42,-0.84 -1.48,-1.12 -0.05,-0.22 -0.39,-2.43 -0.76,-4.91 l -0.67,-4.51 -6.42,-4.62 -6.42,-4.62 -3.38,-0.22 -3.38,-0.22 -3.55,-3.99 c -1.95,-2.19 -3.75,-4.2 -3.98,-4.46 l -0.43,-0.47 0.56,-2.67 c 0.31,-1.47 0.54,-2.74 0.5,-2.83 -0.03,-0.09 -1.17,-1.17 -2.53,-2.41 -1.36,-1.23 -2.5,-2.3 -2.52,-2.37 -0.05,-0.14 1.79,-1.77 1.99,-1.77 0.06,0.0 1.23,0.69 2.58,1.53 1.36,0.84 2.49,1.5 2.52,1.46 0.03,-0.04 -0.13,-2.41 -0.36,-5.28 -0.57,-7.13 -0.65,-6.76 2.55,-12.61 l 2.4,-4.39 1.26,-6.86 1.26,-6.86 -0.31,-6.6 -0.31,-6.6 1.08,-6.18 1.08,-6.18 -0.1,-5.05 c -0.06,-2.78 -0.15,-6.14 -0.2,-7.48 l -0.1,-2.43 7.48,0.0 7.48,0.0 1.32,3.16 1.32,3.16 2.75,0.48 c 4.7,0.83 4.24,0.65 5.01,1.97 0.37,0.64 0.65,1.19 0.61,1.23 -0.04,0.04 -0.74,-0.05 -1.56,-0.19 -0.98,-0.17 -2.68,-0.26 -4.98,-0.26 -3.47,-0.0 -3.49,0.0 -3.58,0.4 -0.05,0.22 -0.92,5.85 -1.93,12.51 l -1.84,12.11 -2.91,6.19 -2.91,6.19 -1.19,5.92 -1.19,5.92 0.11,5.05 0.11,5.05 2.39,10.13 c 1.31,5.57 2.46,10.22 2.54,10.33 0.08,0.11 3.45,4.37 7.48,9.48 7.05,8.92 7.52,9.57 12.29,16.81 l 4.96,7.53 2.53,7.4 c 1.39,4.07 2.56,7.5 2.61,7.63 0.06,0.17 -0.38,0.22 -1.88,0.22 -1.84,0.0 -1.97,-0.02 -2.2,-0.4 z","M434.37,468.24 c -0.04,-0.07 -0.92,-3.15 -1.96,-6.83 l -1.88,-6.7 -2.91,-3.84 -2.91,-3.84 0.17,-1.64 c 0.09,-0.9 0.2,-1.67 0.23,-1.7 0.03,-0.03 1.75,2.49 3.82,5.59 l 3.77,5.65 1.71,6.24 c 0.94,3.43 1.77,6.45 1.84,6.72 0.12,0.49 0.12,0.49 -0.84,0.49 -0.53,0.0 -1.0,-0.06 -1.04,-0.13 z","M392.36,328.17 v -1.61 l -2.22,-3.41 c -1.22,-1.88 -2.33,-3.51 -2.48,-3.63 -0.14,-0.12 -1.39,-0.91 -2.78,-1.75 l -2.52,-1.53 0.06,-2.02 c 0.03,-1.11 0.13,-2.11 0.22,-2.21 0.09,-0.1 0.95,-0.49 1.93,-0.86 0.97,-0.37 1.74,-0.72 1.71,-0.78 -0.04,-0.06 -1.3,-2.66 -2.81,-5.77 l -2.74,-5.66 -2.23,-7.16 c -1.23,-3.94 -2.31,-7.35 -2.41,-7.58 -0.1,-0.23 -1.76,-2.42 -3.69,-4.86 -3.24,-4.09 -3.99,-4.92 -9.58,-10.47 l -6.07,-6.03 -7.51,-5.69 c -4.13,-3.13 -7.54,-5.75 -7.56,-5.83 -0.03,-0.07 -1.02,-4.71 -2.21,-10.31 l -2.16,-10.17 -4.13,-4.18 -4.13,-4.18 -2.76,-0.34 c -1.52,-0.19 -2.86,-0.34 -2.99,-0.34 -0.17,-0.0 -0.22,-0.62 -0.22,-2.49 v -2.49 l -3.05,0.14 c -1.68,0.08 -3.36,0.14 -3.74,0.15 l -0.69,0.01 -0.43,-1.92 c -0.24,-1.05 -0.38,-1.96 -0.32,-2.02 0.06,-0.06 1.48,0.28 3.15,0.75 l 3.05,0.86 1.68,1.53 c 2.22,2.02 3.23,2.72 3.75,2.61 0.22,-0.05 1.42,-0.45 2.66,-0.89 1.24,-0.44 2.25,-0.78 2.25,-0.75 0.0,0.03 -0.24,1.05 -0.53,2.28 -0.29,1.22 -0.53,2.27 -0.53,2.34 0.0,0.07 0.72,0.09 1.6,0.04 l 1.6,-0.08 1.76,-1.75 c 0.97,-0.96 1.76,-1.67 1.76,-1.56 0.0,0.11 -0.35,1.18 -0.79,2.37 l -0.79,2.18 2.18,3.46 c 1.2,1.9 2.6,4.27 3.13,5.27 0.52,1.0 1.0,1.79 1.07,1.77 0.15,-0.06 13.26,-16.25 13.35,-16.5 0.08,-0.21 -2.72,-8.69 -2.99,-9.03 -0.09,-0.11 -0.98,-0.69 -1.98,-1.29 -2.0,-1.19 -2.04,-1.24 -2.04,-3.19 -0.0,-0.79 -0.02,-0.81 -2.82,-3.61 l -2.81,-2.81 2.46,-2.75 c 1.35,-1.51 2.46,-2.84 2.46,-2.97 0.0,-0.12 -0.56,-1.45 -1.24,-2.95 -0.68,-1.5 -1.24,-2.84 -1.24,-2.97 0.0,-0.13 0.65,-2.2 1.45,-4.6 l 1.45,-4.36 -0.46,-1.08 -0.46,-1.08 h 1.08 1.08 l -0.11,8.35 -0.11,8.35 5.49,12.77 c 3.02,7.03 5.45,12.88 5.4,13.0 -0.05,0.12 -2.13,2.71 -4.61,5.75 l -4.52,5.52 -2.92,5.33 c -1.61,2.93 -2.92,5.41 -2.92,5.52 0.0,0.1 1.05,3.64 2.34,7.85 l 2.34,7.66 12.43,10.82 c 6.84,5.95 12.51,10.85 12.6,10.88 0.09,0.03 0.17,-0.25 0.18,-0.62 0.01,-0.37 0.08,-1.63 0.15,-2.78 l 0.14,-2.11 -6.69,-9.12 -6.69,-9.12 1.43,-0.42 c 0.92,-0.27 1.47,-0.36 1.54,-0.24 0.06,0.1 5.28,9.08 11.59,19.96 l 11.48,19.78 6.99,5.69 c 3.85,3.13 7.02,5.62 7.05,5.53 0.03,-0.09 -0.23,-1.37 -0.57,-2.85 -0.35,-1.48 -0.63,-2.81 -0.63,-2.95 0.0,-0.14 0.37,-0.77 0.82,-1.4 l 0.82,-1.15 -0.48,-3.13 c -0.26,-1.72 -0.5,-3.14 -0.52,-3.16 -0.02,-0.02 -0.7,-0.54 -1.51,-1.15 l -1.47,-1.11 0.02,-3.62 c 0.01,-1.99 0.07,-4.82 0.13,-6.29 l 0.11,-2.66 -1.36,-2.37 -1.36,-2.37 -0.56,-5.52 -0.56,-5.52 -3.48,-4.0 -3.48,-4.0 -0.94,-2.38 c -0.52,-1.31 -1.03,-2.35 -1.13,-2.33 -0.58,0.14 -4.49,2.37 -4.49,2.57 0.0,0.13 0.91,5.26 2.03,11.4 1.12,6.14 2.03,11.27 2.03,11.4 0.0,0.16 -0.38,0.22 -1.38,0.22 h -1.38 l -2.53,-11.47 -2.53,-11.47 -4.25,-5.36 -4.25,-5.36 -1.92,-8.02 -1.92,-8.02 0.53,-6.02 c 0.29,-3.31 0.55,-6.05 0.58,-6.08 0.03,-0.03 0.32,0.5 0.65,1.18 0.33,0.68 0.66,1.22 0.72,1.19 0.16,-0.06 3.87,-4.92 3.87,-5.07 0.0,-0.06 -2.23,-2.77 -4.96,-6.03 -2.73,-3.25 -5.0,-6.01 -5.05,-6.13 -0.05,-0.12 1.23,-2.06 2.84,-4.31 1.61,-2.26 2.93,-4.06 2.93,-4.01 0.0,0.05 0.76,2.59 1.69,5.64 0.93,3.05 2.12,7.29 2.65,9.43 0.53,2.14 1.03,4.04 1.11,4.23 0.12,0.28 0.84,-0.58 4.07,-4.84 l 3.93,-5.17 0.61,-2.59 c 0.33,-1.42 0.61,-2.72 0.61,-2.88 0.0,-0.23 -0.28,-0.31 -1.46,-0.41 -0.8,-0.07 -1.64,-0.17 -1.86,-0.22 -0.32,-0.08 -1.97,-2.17 -2.92,-3.7 -0.07,-0.12 0.07,-1.14 0.31,-2.26 0.24,-1.12 0.44,-2.12 0.44,-2.22 0.0,-0.09 -0.49,-0.2 -1.08,-0.22 l -1.08,-0.05 3.31,-1.49 3.31,-1.49 -0.12,-1.38 -0.12,-1.38 h 0.99 c 0.91,0.0 1.0,0.04 1.18,0.49 0.13,0.34 0.15,3.78 0.07,11.61 l -0.13,11.12 -4.18,5.19 c -4.13,5.12 -4.18,5.19 -4.84,5.19 -0.55,0.0 -1.09,0.3 -3.29,1.85 l -2.63,1.85 0.08,6.42 c 0.04,3.53 0.13,7.35 0.19,8.49 l 0.12,2.07 6.1,7.93 6.1,7.93 1.91,0.13 c 1.05,0.07 1.95,0.09 1.99,0.05 0.06,-0.06 -0.62,-1.83 -1.45,-3.77 -0.08,-0.18 3.23,-2.5 3.36,-2.35 0.03,0.04 2.16,4.08 4.72,8.99 l 4.66,8.92 2.28,8.5 2.28,8.5 -0.74,4.51 c -0.41,2.48 -0.78,4.68 -0.83,4.89 -0.07,0.32 0.31,0.69 2.45,2.34 l 2.53,1.96 -0.31,16.11 -0.31,16.11 1.85,4.36 c 1.01,2.4 2.01,4.74 2.21,5.2 l 0.36,0.84 h -7.42 -7.42 z","M338.28,180.02 c -0.13,-0.38 -0.06,-2.28 0.24,-6.87 l 0.43,-6.35 2.53,-2.48 2.53,-2.48 -2.4,-0.01 -2.4,-0.01 -0.12,-4.99 c -0.06,-2.75 -0.17,-7.62 -0.23,-10.84 l -0.12,-5.85 3.25,-1.35 c 1.79,-0.74 3.28,-1.32 3.31,-1.29 0.03,0.03 -0.16,3.19 -0.41,7.01 l -0.47,6.96 -1.49,4.15 c -1.37,3.83 -1.46,4.17 -1.18,4.38 0.17,0.12 0.43,0.22 0.58,0.22 0.26,-0.01 10.48,-16.52 10.86,-17.54 0.11,-0.3 -0.15,-1.85 -0.95,-5.62 -0.61,-2.86 -1.17,-5.32 -1.25,-5.47 -0.08,-0.15 -1.12,-1.39 -2.32,-2.76 l -2.18,-2.49 -14.38,-9.53 -14.38,-9.53 -4.41,-11.71 -4.41,-11.71 2.41,-4.7 c 1.33,-2.58 2.38,-4.79 2.33,-4.9 -0.04,-0.11 -1.12,-0.64 -2.4,-1.18 -1.28,-0.53 -2.32,-1.05 -2.31,-1.15 0.0,-0.1 2.1,-4.74 4.66,-10.32 l 4.66,-10.14 4.66,-5.12 c 2.56,-2.82 4.65,-5.17 4.64,-5.23 -0.01,-0.06 -1.03,-0.73 -2.25,-1.5 l -2.23,-1.39 v -2.64 -2.64 h 15.8 15.8 l -0.78,2.43 c -0.43,1.34 -0.9,2.88 -1.06,3.42 -0.26,0.91 -0.49,1.2 -2.99,3.7 l -2.71,2.71 -5.95,-1.19 c -3.27,-0.65 -5.98,-1.16 -6.02,-1.12 -0.04,0.04 -1.07,2.12 -2.29,4.64 -1.81,3.73 -2.18,4.61 -1.99,4.8 0.98,0.97 4.85,4.09 4.93,3.99 0.06,-0.07 0.53,-1.38 1.03,-2.91 l 0.92,-2.78 2.06,0.02 c 1.13,0.01 2.81,0.07 3.72,0.13 l 1.66,0.11 0.59,1.68 c 0.32,0.92 0.59,1.77 0.6,1.87 0.0,0.11 -0.43,0.86 -0.96,1.68 l -0.96,1.49 0.51,1.76 c 0.28,0.97 0.49,1.78 0.46,1.81 -0.03,0.03 -0.87,-1.1 -1.87,-2.52 -1.0,-1.41 -1.88,-2.61 -1.95,-2.65 -0.08,-0.05 -0.1,0.21 -0.06,0.58 0.04,0.36 0.31,3.51 0.6,6.99 l 0.52,6.33 2.56,4.89 2.56,4.89 0.26,2.58 0.26,2.58 2.12,4.23 c 1.34,2.67 3.2,5.98 5.07,9.0 1.62,2.63 3.01,4.84 3.09,4.91 0.07,0.08 2.04,0.45 4.36,0.83 2.32,0.38 4.43,0.76 4.68,0.85 0.25,0.09 1.8,1.23 3.45,2.54 l 2.99,2.39 3.85,1.28 3.85,1.28 2.29,-0.13 c 1.26,-0.07 2.29,-0.17 2.29,-0.23 0.0,-0.06 -0.5,-1.61 -1.1,-3.45 l -1.1,-3.35 -3.55,-3.25 -3.55,-3.25 -1.09,-4.01 c -0.6,-2.21 -1.09,-4.09 -1.09,-4.19 0.0,-0.1 0.99,-1.17 2.2,-2.37 l 2.2,-2.19 3.77,0.58 3.77,0.58 3.12,1.66 3.12,1.66 2.33,-0.54 c 1.28,-0.3 2.43,-0.6 2.55,-0.67 0.12,-0.07 1.77,-1.36 3.67,-2.85 l 3.46,-2.72 0.75,-3.47 c 0.41,-1.91 0.85,-3.63 0.97,-3.82 0.12,-0.2 0.95,-0.91 1.84,-1.59 l 1.61,-1.23 -0.11,-2.17 c -0.06,-1.23 -0.05,-2.16 0.04,-2.16 0.3,0.01 2.98,1.69 2.98,1.86 -0.0,0.09 -0.07,1.99 -0.15,4.22 l -0.14,4.05 -3.74,3.63 c -2.06,2.0 -4.89,4.76 -6.3,6.14 l -2.56,2.51 -2.92,0.29 -2.92,0.29 -4.85,-1.89 c -2.67,-1.04 -4.99,-1.92 -5.15,-1.97 -0.2,-0.06 -1.4,0.91 -3.76,3.04 -1.9,1.72 -3.46,3.17 -3.46,3.23 0.0,0.05 1.17,1.66 2.6,3.56 l 2.6,3.46 4.12,2.38 c 2.83,1.64 4.12,2.48 4.12,2.68 0.0,0.29 -1.21,5.66 -1.29,5.73 -0.02,0.02 -0.76,0.39 -1.63,0.83 l -1.6,0.8 -5.51,-0.43 -5.51,-0.43 -3.22,-1.86 c -1.77,-1.02 -4.14,-2.43 -5.27,-3.12 -1.32,-0.81 -2.21,-1.25 -2.49,-1.22 -0.24,0.02 -2.57,0.46 -5.16,0.97 l -4.72,0.93 -1.11,-1.12 c -0.61,-0.61 -1.16,-1.12 -1.23,-1.12 -0.07,0.0 -1.33,1.36 -2.81,3.02 l -2.69,3.02 1.01,4.8 c 0.56,2.64 1.11,4.97 1.24,5.17 0.13,0.2 1.58,1.98 3.24,3.95 l 3.01,3.59 2.58,6.16 c 1.42,3.39 2.58,6.24 2.58,6.34 0.0,0.1 -2.43,4.65 -5.4,10.11 l -5.4,9.93 -0.11,5.81 -0.11,5.81 h -1.08 -1.08 l -0.85,-1.7 c -0.47,-0.94 -0.91,-1.63 -0.99,-1.55 -0.08,0.09 -0.72,1.67 -1.42,3.52 -0.7,1.85 -1.33,3.45 -1.4,3.57 -0.06,0.12 -0.93,0.73 -1.92,1.35 l -1.8,1.14 z","M381.4,174.21 l -0.97,-0.09 -0.05,-0.66 c -0.07,-0.8 0.2,-0.78 -4.03,-0.31 -3.47,0.39 -4.83,0.44 -4.57,0.2 0.09,-0.09 1.8,-1.02 3.79,-2.06 1.99,-1.05 3.64,-1.91 3.66,-1.92 0.02,-0.01 -0.11,-1.17 -0.28,-2.58 -0.21,-1.67 -0.26,-2.67 -0.15,-2.88 0.09,-0.18 0.23,-0.26 0.3,-0.18 0.14,0.15 3.4,10.55 3.32,10.57 -0.02,0.01 -0.48,-0.03 -1.01,-0.08 z","M395.61,60.97 l -3.55,-1.85 -0.28,-2.69 c -0.16,-1.48 -0.23,-2.74 -0.16,-2.8 0.07,-0.06 3.9,-2.68 8.52,-5.82 l 8.4,-5.71 6.83,-2.1 6.83,-2.1 2.71,1.44 c 1.49,0.79 2.8,1.54 2.91,1.65 0.11,0.11 0.5,1.03 0.87,2.04 l 0.68,1.83 2.68,2.01 c 1.47,1.11 2.74,2.01 2.82,2.01 0.07,0.0 1.94,-1.07 4.14,-2.37 l 4.0,-2.37 6.41,-2.06 6.41,-2.06 4.09,-2.85 4.09,-2.85 -0.11,-1.25 c -0.06,-0.69 -0.16,-1.71 -0.22,-2.27 l -0.11,-1.02 -6.12,-4.43 c -3.37,-2.44 -6.55,-4.76 -7.08,-5.17 l -0.96,-0.73 -0.68,-3.26 c -0.37,-1.79 -0.62,-3.3 -0.54,-3.36 0.07,-0.05 1.94,-1.31 4.15,-2.8 l 4.02,-2.7 h 3.98 c 2.19,0.0 3.98,0.03 3.98,0.07 0.0,0.04 -0.12,0.35 -0.26,0.69 l -0.26,0.63 0.93,0.1 c 0.51,0.05 6.06,0.38 12.33,0.72 6.27,0.34 11.98,0.67 12.68,0.73 1.25,0.11 1.35,0.15 4.05,1.86 1.52,0.96 2.79,1.73 2.82,1.69 0.03,-0.03 -0.18,-1.48 -0.47,-3.21 -0.29,-1.73 -0.51,-3.17 -0.48,-3.19 0.03,-0.02 0.55,-0.0 1.15,0.04 l 1.1,0.08 1.24,2.17 c 0.68,1.19 1.24,2.22 1.24,2.28 0.0,0.06 -0.48,0.11 -1.08,0.11 -0.59,0.0 -1.05,0.07 -1.02,0.15 0.03,0.08 1.21,1.75 2.62,3.71 l 2.56,3.56 4.58,-0.04 4.58,-0.04 0.4,-1.47 c 0.22,-0.81 0.43,-1.5 0.46,-1.53 0.03,-0.03 1.8,0.14 3.93,0.38 2.13,0.24 3.93,0.37 3.99,0.29 0.07,-0.08 0.51,-1.18 0.97,-2.44 0.47,-1.26 0.87,-2.33 0.9,-2.36 0.03,-0.04 0.56,0.34 1.18,0.83 0.62,0.49 1.21,0.92 1.32,0.95 0.17,0.05 3.8,-5.31 4.06,-5.98 0.06,-0.15 -1.02,-1.39 -2.79,-3.2 l -2.89,-2.96 0.7,-0.12 c 0.39,-0.07 1.14,-0.13 1.67,-0.13 l 0.97,-0.01 2.65,2.21 c 1.46,1.22 2.67,2.27 2.7,2.34 0.03,0.07 -1.11,2.08 -2.51,4.45 -1.41,2.37 -2.54,4.34 -2.51,4.37 0.03,0.03 2.13,-0.61 4.67,-1.42 l 4.62,-1.47 1.11,1.12 c 0.61,0.61 1.07,1.14 1.03,1.18 -0.04,0.03 -2.11,0.94 -4.59,2.02 l -4.51,1.96 -13.37,1.73 -13.37,1.73 -7.81,-4.37 c -4.3,-2.4 -7.85,-4.33 -7.89,-4.29 -0.04,0.04 0.25,1.29 0.65,2.76 0.4,1.48 0.7,2.72 0.65,2.76 -0.04,0.04 -1.73,-1.32 -3.75,-3.02 l -3.67,-3.1 h -12.69 -12.69 l -1.53,1.96 -1.53,1.96 2.25,3.74 c 1.24,2.06 2.28,3.77 2.31,3.81 0.03,0.04 1.98,0.25 4.34,0.46 l 4.28,0.39 1.24,-0.42 c 0.68,-0.23 1.3,-0.4 1.37,-0.37 0.07,0.03 -0.31,0.4 -0.85,0.84 l -0.98,0.8 0.12,4.78 0.12,4.78 -3.57,2.61 -3.57,2.61 -6.66,2.48 -6.66,2.48 -4.61,2.98 -4.61,2.98 h -1.95 c -3.62,0.0 -3.29,0.16 -5.8,-2.81 l -2.18,-2.59 -5.4,-2.16 -5.4,-2.16 -7.12,4.54 c -7.51,4.79 -6.84,4.43 -14.84,7.96 l -0.82,0.36 0.53,1.83 c 0.29,1.01 0.68,2.36 0.87,3.0 l 0.34,1.18 1.77,1.01 c 1.64,0.94 1.97,1.17 1.63,1.14 -0.07,-0.01 -1.73,-0.85 -3.68,-1.86 z","M323.06,30.07 v -2.73 l -3.33,-3.83 -3.33,-3.83 -2.26,-6.69 c -2.11,-6.26 -2.34,-6.84 -3.57,-8.94 -0.97,-1.66 -1.95,-3.81 -3.76,-8.27 -1.35,-3.31 -2.43,-6.05 -2.4,-6.08 0.05,-0.06 50.0,-6.18 50.06,-6.14 0.17,0.1 -0.86,7.71 -1.68,12.46 l -1.02,5.9 0.94,3.64 c 1.45,5.64 2.13,8.96 2.25,10.89 0.06,0.97 0.26,4.31 0.46,7.42 l 0.36,5.66 -0.52,1.59 -0.52,1.59 -15.84,0.05 -15.84,0.05 z","M402.37,64.55 c -1.78,-0.92 -3.23,-1.68 -3.23,-1.68 0.0,-0.0 0.04,0.01 0.08,0.02 0.17,0.06 0.31,0.0 0.28,-0.12 -0.01,-0.06 -0.1,-0.14 -0.25,-0.24 -0.06,-0.04 -0.11,-0.08 -0.11,-0.08 0.0,-0.0 6.45,3.75 6.47,3.77 0.01,0.01 0.01,0.01 0.0,0.01 -0.01,-0.0 -1.47,-0.75 -3.25,-1.68 z","M409.92,69.53 c -0.03,-0.45 -0.05,-0.82 -0.05,-0.82 0.0,-0.0 0.19,0.11 0.43,0.24 0.23,0.14 0.42,0.25 0.42,0.25 -0.0,0.0 -0.04,-0.02 -0.09,-0.05 -0.26,-0.14 -0.44,-0.21 -0.5,-0.2 -0.02,0.0 -0.06,0.02 -0.07,0.03 -0.03,0.04 -0.05,0.11 -0.07,0.25 -0.02,0.17 -0.02,0.31 -0.02,0.71 -0.0,0.22 -0.0,0.4 -0.0,0.4 -0.0,0.0 -0.02,-0.37 -0.05,-0.82 z","M413.18,72.05 c -0.0,-0.02 0.01,-0.29 0.02,-0.6 l 0.02,-0.58 -0.01,-0.03 c -0.03,-0.07 -0.17,-0.18 -0.46,-0.39 -0.23,-0.16 -0.62,-0.42 -0.95,-0.62 -0.09,-0.05 -0.16,-0.1 -0.16,-0.1 0.0,-0.0 1.59,0.92 1.6,0.93 0.01,0.01 0.0,0.13 -0.02,0.68 -0.02,0.37 -0.03,0.69 -0.03,0.71 -0.0,0.03 -0.0,0.03 -0.0,0.01 z","M406.23,77.65 c -0.0,-0.03 0.35,-1.61 0.36,-1.62 0.01,-0.0 0.8,-0.63 1.77,-1.39 1.61,-1.26 1.76,-1.38 1.76,-1.35 0.0,0.03 -0.07,0.08 -0.74,0.59 -0.41,0.31 -0.87,0.67 -1.03,0.79 -0.83,0.64 -1.53,1.26 -1.66,1.46 -0.06,0.09 -0.2,0.54 -0.38,1.24 -0.04,0.16 -0.08,0.28 -0.08,0.28 z","M410.44,81.61 c 0.03,-0.03 2.44,-2.37 2.44,-2.37 0.0,0.0 -0.0,0.01 -0.0,0.02 l -0.0,0.02 -1.2,1.17 -1.2,1.17 -0.02,0.0 c -0.01,0.0 -0.02,-0.0 -0.02,-0.0 z","M401.06,86.47 c 0.0,-0.0 0.88,-0.69 1.95,-1.53 1.07,-0.84 1.95,-1.53 1.95,-1.53 0.0,-0.0 0.06,-0.27 0.13,-0.59 0.07,-0.32 0.13,-0.59 0.13,-0.58 0.0,0.0 -0.25,1.19 -0.25,1.19 -0.0,0.0 -2.86,2.25 -3.27,2.58 -0.66,0.52 -0.59,0.47 -0.61,0.47 -0.01,0.0 -0.02,-0.0 -0.02,-0.0 z","M405.19,86.72 c 0.0,-0.0 1.42,-1.39 3.25,-3.16 2.1,-2.04 2.0,-1.94 2.02,-1.94 0.02,0.0 0.02,0.0 -0.03,0.05 -0.03,0.03 -1.21,1.18 -2.63,2.55 -1.64,1.59 -2.58,2.5 -2.59,2.5 -0.01,0.0 -0.01,-0.0 -0.01,-0.0 z","M430.88,468.42 c -0.02,-0.01 -0.0,-0.01 0.04,-0.02 0.15,-0.02 0.28,-0.07 0.33,-0.12 0.01,-0.01 0.03,-0.04 0.03,-0.06 l 0.01,-0.04 0.04,0.12 0.04,0.12 -0.24,-0.0 c -0.13,-0.0 -0.25,-0.01 -0.26,-0.01 z","M415.4,468.24 c 0.0,-0.08 0.03,-0.12 0.14,-0.15 1.18,-0.37 2.48,-0.76 2.49,-0.75 0.01,0.01 0.04,0.19 0.06,0.39 0.02,0.2 0.05,0.43 0.06,0.49 l 0.02,0.12 h -1.39 -1.39 z","M375.08,91.71 c -0.21,-0.78 -0.39,-1.43 -0.39,-1.43 -0.0,-0.01 0.09,-0.1 0.26,-0.28 0.15,-0.15 0.27,-0.27 0.27,-0.27 0.0,0.0 -0.03,0.04 -0.07,0.08 -0.15,0.17 -0.3,0.35 -0.34,0.41 -0.05,0.07 -0.05,0.1 -0.03,0.21 0.06,0.29 0.28,1.16 0.59,2.32 0.05,0.2 0.1,0.37 0.09,0.37 -0.0,0.0 -0.18,-0.63 -0.39,-1.42 z","M415.45,473.17 l -0.19,-0.41 0.01,-0.25 0.01,-0.25 0.03,0.18 c 0.06,0.35 0.14,0.63 0.31,1.01 0.03,0.07 0.05,0.12 0.05,0.12 -0.0,0.0 -0.09,-0.18 -0.2,-0.41 z","M427.13,468.2 c -0.09,-0.16 -0.1,-0.21 -0.04,-0.12 0.08,0.12 0.18,0.21 0.3,0.26 l 0.05,0.02 -0.11,0.0 -0.11,0.0 z","M436.25,468.42 c -0.01,-0.0 0.01,-0.02 0.03,-0.03 0.1,-0.05 0.14,-0.15 0.12,-0.3 -0.01,-0.04 -0.01,-0.08 -0.01,-0.08 0.0,-0.0 0.03,0.08 0.06,0.19 0.03,0.11 0.06,0.2 0.06,0.21 0.0,0.01 -0.02,0.01 -0.12,0.01 -0.07,-0.0 -0.13,-0.0 -0.14,-0.01 z","M434.21,468.14 c -0.11,-0.4 -0.2,-0.73 -0.2,-0.73 0.0,-0.0 0.01,0.03 0.02,0.06 0.06,0.23 0.23,0.77 0.25,0.8 0.03,0.05 0.07,0.08 0.18,0.11 0.11,0.03 0.11,0.03 0.04,0.05 -0.13,0.04 -0.16,0.1 -0.13,0.26 0.03,0.14 0.04,0.17 0.03,0.17 -0.0,-0.0 -0.1,-0.33 -0.21,-0.72 z","M435.08,471.22 c -0.27,-0.95 -0.49,-1.73 -0.64,-2.33 -0.02,-0.09 -0.02,-0.09 -0.02,-0.05 0.0,0.02 -0.0,0.02 -0.01,0.01 -0.02,-0.03 -0.4,-1.42 -0.4,-1.44 0.0,-0.01 0.01,-0.01 0.02,0.01 0.0,0.01 0.01,0.01 0.01,0.01 -0.0,-0.0 -0.02,-0.07 -0.04,-0.16 -0.02,-0.08 -0.07,-0.26 -0.11,-0.39 -0.04,-0.13 -0.07,-0.24 -0.07,-0.24 -0.0,-0.01 0.05,-0.01 1.1,-0.01 h 1.1 l 0.01,0.02 c 0.01,0.03 0.14,0.5 0.22,0.8 0.08,0.31 0.12,0.43 0.14,0.53 0.01,0.05 0.01,0.06 0.02,0.05 0.0,-0.01 0.0,-0.02 0.0,-0.02 0.01,-0.0 0.02,0.06 0.06,0.18 0.01,0.05 0.03,0.13 0.05,0.16 0.01,0.05 0.02,0.07 0.02,0.07 -0.0,0.0 -0.02,0.01 -0.05,0.01 -0.06,0.0 -0.05,0.01 0.02,0.01 l 0.05,0.0 0.02,0.08 c 0.01,0.04 0.03,0.1 0.03,0.12 0.01,0.02 0.18,0.64 0.38,1.38 0.2,0.74 0.37,1.34 0.37,1.35 0.0,0.01 -0.05,0.01 -1.1,0.01 h -1.1 l -0.04,-0.15 z m -0.66,-2.43 c -0.0,-0.0 -0.0,-0.0 -0.0,0.0 -0.0,0.0 0.0,0.01 0.0,0.01 0.0,-0.0 0.0,-0.01 0.0,-0.01 z m 0.02,-0.31 c 0.01,-0.01 0.01,-0.01 -0.0,-0.0 -0.0,0.0 -0.01,0.01 -0.01,0.01 0.0,0.0 0.0,0.0 0.01,-0.01 z m 1.94,-0.04 c -0.01,-0.0 -0.02,-0.0 -0.02,-0.0 -0.01,0.0 -0.0,0.0 0.01,0.0 0.01,0.0 0.02,-0.0 0.01,-0.0 z m -0.12,-0.0 c -0.01,-0.0 -0.01,-0.0 -0.01,-0.01 0.0,-0.0 0.01,-0.01 0.01,-0.02 0.01,-0.01 0.01,-0.01 -0.03,0.01 -0.02,0.01 -0.04,0.01 -0.05,0.01 -0.01,0.0 0.04,0.01 0.06,0.01 0.01,0.0 0.02,-0.0 0.01,-0.0 z m -1.65,-0.01 0.04,-0.01 -0.04,-0.01 c -0.02,-0.0 -0.05,-0.01 -0.05,-0.01 -0.01,-0.0 -0.01,-0.0 0.0,0.0 0.02,0.01 0.02,0.02 0.0,0.02 -0.01,0.01 -0.01,0.01 -0.0,0.0 0.01,-0.0 0.03,-0.01 0.05,-0.01 z m -0.52,-0.83 c -0.0,-0.0 -0.0,-0.0 -0.0,0.0 -0.0,0.0 0.0,0.01 0.0,0.01 0.0,-0.0 0.0,-0.01 0.0,-0.01 z","M435.12,471.36 c -0.01,-0.03 -0.13,-0.46 -0.18,-0.65 -0.18,-0.63 -0.31,-1.13 -0.42,-1.55 -0.03,-0.1 -0.06,-0.21 -0.07,-0.25 -0.01,-0.04 -0.02,-0.07 -0.02,-0.06 -0.0,0.01 -0.01,0.01 -0.01,0.01 -0.0,-0.01 -0.01,-0.02 -0.05,-0.17 -0.07,-0.25 -0.27,-0.97 -0.34,-1.22 -0.02,-0.07 -0.02,-0.08 -0.0,-0.07 0.0,0.0 0.0,-0.0 -0.0,-0.01 -0.06,-0.22 -0.22,-0.75 -0.22,-0.75 0.0,-0.0 0.5,-0.0 1.1,-0.0 l 1.1,0.0 0.04,0.15 c 0.19,0.71 0.25,0.94 0.29,1.09 0.02,0.08 0.04,0.15 0.04,0.15 0.0,0.0 0.0,-0.0 0.0,-0.01 0.0,-0.02 0.01,-0.01 0.02,0.01 0.01,0.03 0.04,0.13 0.08,0.28 0.02,0.08 0.03,0.11 0.03,0.12 -0.0,0.0 -0.02,0.01 -0.03,0.01 -0.04,0.0 -0.02,0.01 0.02,0.01 l 0.03,0.0 0.01,0.04 c 0.06,0.2 0.79,2.88 0.79,2.88 -0.0,0.0 -0.49,0.0 -1.1,0.0 -1.04,0.0 -1.1,-0.0 -1.1,-0.01 z m 1.12,-2.94 c 0.0,-0.0 0.0,-0.01 0.01,-0.01 0.0,-0.0 0.0,-0.01 -0.0,-0.0 -0.0,0.0 -0.02,0.01 -0.03,0.01 -0.02,0.01 -0.03,0.01 -0.03,0.01 0.0,0.0 0.01,0.0 0.03,0.0 0.03,0.0 0.03,-0.0 0.03,-0.01 z m -1.64,-0.01 c 0.02,-0.0 0.03,-0.01 0.03,-0.01 -0.0,-0.0 -0.06,-0.01 -0.07,-0.01 -0.0,0.0 0.0,0.0 0.0,0.01 0.0,0.0 0.0,0.01 0.0,0.01 -0.0,0.01 -0.0,0.01 0.03,0.0 z","M434.6,469.48 c -0.01,-0.01 -0.08,-0.31 -0.13,-0.48 -0.04,-0.15 -0.04,-0.15 -0.04,-0.14 -0.0,0.0 -0.01,0.0 -0.01,-0.0 -0.02,-0.04 -0.4,-1.41 -0.4,-1.44 0.0,-0.01 0.0,-0.01 0.01,-0.01 0.0,0.0 0.01,-0.0 0.0,-0.01 -0.0,-0.01 -0.05,-0.18 -0.12,-0.42 -0.06,-0.2 -0.08,-0.28 -0.1,-0.37 -0.01,-0.02 -0.08,-0.29 -0.17,-0.6 -0.09,-0.31 -0.2,-0.72 -0.26,-0.9 -0.05,-0.18 -0.1,-0.34 -0.1,-0.34 -0.0,-0.01 0.05,-0.01 1.11,-0.01 h 1.12 l 0.01,0.02 c 0.0,0.01 0.08,0.31 0.18,0.66 0.17,0.61 0.26,0.97 0.38,1.39 0.12,0.45 0.25,0.94 0.29,1.09 0.02,0.09 0.02,0.09 0.03,0.09 0.01,-0.02 0.02,0.0 0.04,0.08 0.02,0.07 0.08,0.29 0.09,0.31 0.0,0.01 -0.01,0.02 -0.03,0.02 -0.01,0.0 -0.01,0.0 -0.01,0.0 0.0,0.0 0.01,0.0 0.03,0.0 0.02,0.0 0.02,0.0 0.02,0.01 0.0,0.0 0.06,0.23 0.14,0.51 0.08,0.28 0.14,0.51 0.14,0.52 l 0.01,0.02 h -1.1 -1.1 z m 1.65,-1.06 c 0.0,-0.01 0.0,-0.01 0.0,-0.01 -0.0,-0.0 -0.05,0.01 -0.05,0.02 -0.0,0.0 0.01,0.0 0.02,0.0 0.02,0.0 0.02,-0.0 0.03,-0.01 z m -1.64,-0.01 c 0.02,-0.0 0.02,-0.01 -0.02,-0.01 l -0.02,-0.0 0.0,0.01 c 0.0,0.01 0.0,0.01 0.01,0.01 0.0,-0.0 0.02,-0.0 0.03,-0.01 z","M434.6,469.49 c -0.0,-0.0 -0.06,-0.23 -0.11,-0.42 -0.05,-0.2 -0.05,-0.21 -0.06,-0.21 -0.0,0.0 -0.01,-0.0 -0.01,-0.01 -0.01,-0.02 -0.29,-1.01 -0.37,-1.3 -0.03,-0.12 -0.04,-0.15 -0.03,-0.15 0.0,0.0 0.0,-0.0 0.0,-0.01 -0.0,-0.01 -0.05,-0.17 -0.11,-0.37 -0.1,-0.34 -0.64,-2.23 -0.64,-2.25 l -0.0,-0.01 1.12,0.0 1.12,0.0 0.08,0.28 c 0.04,0.15 0.12,0.45 0.18,0.66 0.06,0.21 0.14,0.5 0.18,0.64 0.24,0.89 0.37,1.36 0.42,1.55 0.03,0.1 0.03,0.11 0.04,0.11 0.0,-0.0 0.01,0.0 0.01,0.01 0.01,0.02 0.08,0.28 0.11,0.37 0.01,0.03 0.01,0.04 -0.02,0.04 -0.01,0.0 -0.01,0.0 0.01,0.0 0.01,0.0 0.02,0.0 0.02,0.01 0.0,0.0 0.01,0.03 0.02,0.06 0.08,0.31 0.27,0.98 0.27,0.99 0.0,0.0 -0.22,0.01 -1.1,0.01 -0.61,0.0 -1.11,-0.0 -1.11,-0.0 z m 1.64,-1.07 c 0.01,-0.01 0.0,-0.01 -0.02,-0.0 -0.01,0.0 -0.02,0.01 -0.02,0.01 0.0,0.01 0.03,0.0 0.04,-0.01 z m -1.64,-0.01 0.02,-0.0 -0.01,-0.0 c -0.04,-0.01 -0.04,-0.01 -0.04,0.0 0.0,0.01 0.01,0.01 0.03,0.01 z","M428.27,478.61 c -0.12,-0.93 -0.23,-1.41 -0.52,-2.24 -0.07,-0.19 -0.01,-0.05 0.18,0.46 l 0.2,0.54 0.08,0.67 c 0.04,0.37 0.08,0.67 0.08,0.68 -0.0,0.0 -0.01,-0.04 -0.02,-0.11 z","M426.95,474.19 c -0.0,-0.0 -0.02,-0.06 -0.05,-0.12 -0.27,-0.69 -0.52,-1.29 -0.63,-1.51 -0.04,-0.08 -0.06,-0.11 -0.08,-0.13 -0.06,-0.05 -0.23,-0.11 -0.48,-0.16 -0.04,-0.01 -0.07,-0.02 -0.07,-0.02 0.0,-0.0 0.14,0.02 0.31,0.04 l 0.31,0.04 0.35,0.93 c 0.19,0.51 0.35,0.93 0.34,0.93 -0.0,0.0 -0.0,0.0 -0.0,-0.0 z","M424.17,472.53 c -0.0,-0.01 0.1,-0.47 0.1,-0.47 0.0,-0.0 0.12,0.01 0.27,0.03 0.14,0.02 0.26,0.04 0.25,0.04 -0.01,0.0 -0.02,-0.0 -0.04,-0.0 -0.05,-0.01 -0.17,-0.01 -0.21,-0.0 -0.09,0.01 -0.15,0.04 -0.2,0.09 -0.06,0.06 -0.1,0.14 -0.15,0.27 -0.01,0.03 -0.02,0.05 -0.02,0.04 z","M401.75,484.77 c -0.0,-0.01 0.13,-0.82 0.29,-1.8 l 0.29,-1.8 0.0,0.26 c 0.0,0.14 0.01,0.33 0.01,0.41 l 0.0,0.16 -0.06,-0.0 -0.06,-0.0 -0.23,1.39 c -0.13,0.77 -0.23,1.39 -0.23,1.38 z","M414.29,492.96 c -0.0,-0.01 0.97,-3.37 0.97,-3.36 0.0,0.01 -0.06,0.64 -0.13,1.4 -0.07,0.76 -0.13,1.38 -0.13,1.37 -0.0,-0.03 0.02,-0.29 0.07,-1.11 0.02,-0.34 0.04,-0.62 0.04,-0.63 -0.0,-0.01 -0.11,-0.03 -0.12,-0.02 -0.0,0.0 -0.16,0.51 -0.34,1.14 -0.35,1.17 -0.37,1.23 -0.37,1.21 z","M471.17,583.04 c 0.11,0.01 0.07,0.12 0.11,0.17 0.01,0.01 0.01,0.01 0.02,0.01 0.0,0.0 0.01,0.01 0.01,0.01","M471.1,583.16 c 0.04,0.0 0.08,0.0 0.12,0.01 0.01,0.0 0.02,0.01 0.03,0.01 0.01,0.0 0.03,-0.0 0.04,0.0 0.02,0.0 0.08,0.02 0.11,0.01 0.0,-0.0 0.0,-0.0 0.0,-0.0 -0.0,-0.01 -0.0,-0.01 -0.0,-0.02 -0.01,-0.02 -0.0,-0.01 -0.02,-0.03 -0.01,-0.01 -0.01,-0.03 -0.01,-0.03 -0.0,-0.0 -0.01,0.0 -0.01,0.0 -0.0,-0.0 0.0,-0.01 0.0,-0.01 -0.0,-0.0 -0.01,0.0 -0.02,0.0 -0.01,-0.0 -0.03,-0.0 -0.04,-0.0 -0.0,0.0 0.0,0.0 0.0,0.0 -0.0,0.0 -0.01,0.0 -0.01,0.0 -0.01,0.0 -0.03,-0.0 -0.04,-0.0 -0.0,-0.0 -0.0,-0.0 -0.0,-0.0 -0.01,-0.0 -0.01,0.0 -0.02,0.0 -0.01,0.0 -0.02,0.0 -0.03,0.0 -0.03,0.0 -0.03,0.01 -0.05,0.02 -0.01,0.01 -0.03,0.01 -0.04,0.02 -0.0,0.0 -0.01,-0.0 -0.01,0.0 -0.0,0.0 0.0,0.01 0.0,0.01 -0.0,0.0 -0.0,0.01 -0.01,0.01 -0.0,0.0 0.01,-0.01 0.01,-0.01 0.01,0.0 0.01,0.01 0.01,0.02 z","M470.93,583.98 c -0.01,-0.0 -0.09,-0.01 -0.09,-0.0 -0.0,0.0 -0.0,0.01 -0.0,0.01 -0.0,0.0 -0.01,-0.0 -0.01,0.0 -0.0,0.0 0.0,0.01 0.0,0.01 -0.0,0.0 -0.0,0.01 -0.0,0.01 -0.0,0.0 0.0,0.01 0.0,0.01 -0.0,0.0 -0.0,-0.0 -0.0,0.0 -0.0,0.0 -0.0,0.05 -0.0,0.05 -0.0,0.0 -0.01,0.0 -0.02,0.0 -0.0,0.0 0.0,0.01 0.0,0.01 -0.0,0.01 -0.01,0.02 -0.02,0.04 -0.0,0.01 0.01,0.03 0.01,0.04 0.01,0.02 -0.0,-0.01 -0.0,0.02 0.0,0.01 0.01,0.01 0.01,0.02 0.0,0.01 -0.0,0.03 0.0,0.04 0.0,0.02 0.04,0.0 0.05,0.02 0.02,0.02 -0.01,0.01 0.01,0.02 0.02,0.0 0.07,0.0 0.09,-0.0 0.0,-0.0 0.01,-0.0 0.01,-0.0 0.01,-0.0 0.02,-0.01 0.03,-0.01 0.01,-0.0 0.02,-0.0 0.04,-0.0 0.01,-0.0 0.01,-0.01 0.02,-0.01 0.0,-0.0 0.0,0.0 0.0,0.0 0.0,-0.01 -0.0,-0.01 0.0,-0.02 0.0,-0.01 0.01,-0.01 0.01,-0.02 -0.0,-0.01 -0.01,-0.02 -0.0,-0.03 0.0,-0.03 0.01,0.01 0.0,-0.04 -0.0,-0.0 -0.01,-0.04 -0.02,-0.05 -0.0,-0.0 -0.02,-0.0 -0.03,-0.01 -0.01,-0.01 -0.0,-0.04 -0.01,-0.05 -0.0,-0.0 -0.0,0.0 -0.0,0.0 -0.0,-0.0 0.0,-0.0 0.0,-0.0 -0.0,-0.0 -0.0,0.0 -0.0,0.0 -0.0,-0.0 0.0,-0.0 0.0,-0.0 -0.0,-0.01 -0.01,-0.0 -0.01,-0.0 -0.01,-0.0 -0.01,-0.01 -0.01,-0.0 -0.0,0.0 -0.01,0.01 -0.01,0.0 -0.0,-0.0 -0.0,-0.01 -0.0,-0.01 -0.0,-0.0 -0.0,0.0 -0.0,0.0 -0.01,-0.01 -0.01,-0.01 -0.02,-0.02 z","M481.87,584.78 c -0.04,0.0 -0.09,-0.01 -0.13,0.0 -0.12,0.03 -0.24,0.08 -0.35,0.13 -0.01,0.01 -0.01,0.02 -0.02,0.02 -0.04,0.01 -0.09,-0.01 -0.13,0.0 -0.13,0.09 0.0,0.02 -0.13,0.04 -0.04,-0.02 -0.04,0.04 -0.07,0.04 -0.13,0.04 -0.11,0.02 -0.22,0.02 -0.1,0.01 -0.21,0.02 -0.31,0.02 -0.13,0.01 -0.27,-0.01 -0.4,0.0 -0.37,0.03 0.11,0.01 -0.4,0.07 -0.25,0.03 -0.5,-0.01 -0.75,-0.02 -0.21,-0.01 -0.43,-0.02 -0.64,-0.02 -0.35,-0.01 -0.71,0.02 -1.06,0.0 -0.45,-0.03 -0.18,-0.06 -0.66,-0.15 -0.21,-0.04 -0.35,-0.01 -0.55,-0.02 -0.07,-0.01 -0.15,-0.04 -0.22,-0.04 -0.07,-0.01 -0.13,0.01 -0.2,0.0 -0.27,-0.04 -0.53,-0.08 -0.8,-0.11 -0.06,-0.01 -0.12,0.01 -0.18,0.0 -0.05,-0.01 -0.1,-0.01 -0.15,-0.02 -0.01,-0.0 -0.01,-0.02 -0.02,-0.02 -0.25,-0.02 -0.52,0.0 -0.77,0.02 -0.1,0.01 -0.21,-0.01 -0.31,0.0 -0.03,0.0 -0.06,0.02 -0.09,0.02 -0.19,0.01 -0.38,-0.01 -0.57,0.0 -0.19,0.01 -0.04,0.06 -0.31,0.02 -0.03,-0.01 -0.06,-0.03 -0.09,-0.04 -0.05,0.0 -0.1,0.0 -0.15,0.0 -0.19,0.0 -0.04,0.02 -0.2,-0.04 -0.04,-0.05 -0.09,-0.01 -0.13,-0.02 -0.19,-0.05 -0.24,-0.09 -0.38,-0.13 -0.05,-0.02 -0.09,-0.04 -0.13,-0.07 -0.01,-0.0 -0.02,0.01 -0.02,0.0 -0.01,-0.02 -0.01,-0.05 -0.02,-0.07 -0.01,-0.01 -0.03,0.01 -0.04,0.0 -0.02,-0.01 -0.03,-0.03 -0.04,-0.04 -0.01,-0.01 -0.03,0.01 -0.04,0.0 -0.01,-0.01 -0.02,-0.06 -0.02,-0.07 -0.03,-0.01 -0.06,-0.01 -0.09,-0.02 -0.02,-0.01 -0.0,-0.05 -0.02,-0.07 -0.02,-0.01 -0.05,-0.01 -0.07,-0.02 -0.06,-0.0 -0.01,-0.05 -0.02,-0.07 -0.01,-0.01 -0.03,0.01 -0.04,0.0 -0.01,-0.01 0.01,-0.03 0.0,-0.04 -0.01,-0.01 -0.04,-0.01 -0.04,-0.02 -0.01,-0.04 -0.01,-0.07 -0.02,-0.11 -0.01,0.0 -0.02,0.01 -0.02,0.0 -0.02,-0.02 0.01,-0.05 0.0,-0.07 -0.0,-0.01 -0.02,-0.01 -0.02,-0.02 -0.01,-0.01 0.01,-0.06 0.0,-0.07 -0.01,-0.01 -0.02,0.01 -0.02,0.0 -0.01,-0.03 -0.02,-0.06 0.0,-0.09 0.02,-0.03 0.07,-0.05 0.09,-0.09 0.0,-0.01 -0.01,-0.02 0.0,-0.02 0.01,-0.01 0.02,0.01 0.02,0.0 0.02,-0.02 -0.02,-0.11 0.0,-0.13 0.01,-0.01 0.02,0.01 0.02,0.0 0.01,-0.01 -0.01,-0.02 0.0,-0.02 0.05,-0.05 0.13,-0.08 0.18,-0.13 0.01,-0.01 -0.0,-0.02 0.0,-0.02 0.01,-0.02 0.18,-0.15 0.2,-0.15 0.01,-0.01 0.03,0.01 0.04,0.0 0.03,-0.02 0.1,-0.14 0.15,-0.15 0.13,-0.04 0.25,0.0 0.38,-0.02 0.11,-0.02 0.11,-0.04 0.2,-0.07 0.09,-0.02 0.18,-0.04 0.27,-0.07 0.02,-0.01 0.03,-0.02 0.04,-0.02 0.36,-0.03 0.08,-0.0 0.29,0.02 0.12,0.01 0.14,-0.01 0.27,-0.02 0.06,-0.0 0.12,0.0 0.18,0.0 0.22,-0.01 0.43,-0.09 0.64,-0.11 0.12,-0.01 0.24,0.0 0.35,0.0 0.25,0.0 0.5,0.0 0.75,0.0 0.29,0.0 0.59,-0.02 0.88,0.0 0.13,0.01 0.26,0.04 0.4,0.04 0.29,0.01 0.59,-0.02 0.88,0.0 0.11,0.01 0.22,0.07 0.33,0.07 0.21,0.0 0.41,-0.04 0.62,-0.02 0.22,0.02 0.44,0.08 0.66,0.09 0.3,0.01 0.61,-0.02 0.91,0.0 0.13,0.01 0.21,0.04 0.33,0.07 0.11,0.02 0.29,0.03 0.4,0.07 0.03,0.01 0.05,0.05 0.09,0.07 0.03,0.01 0.22,0.04 0.24,0.04 0.01,0.0 -0.01,0.02 0.0,0.02 0.01,0.01 0.36,-0.01 0.42,0.0 0.08,0.01 0.15,0.06 0.22,0.07 0.12,0.02 0.56,-0.03 0.64,0.0 0.38,0.23 -0.1,-0.03 0.2,0.07 0.02,0.01 0.03,0.03 0.04,0.04 0.02,0.01 0.05,0.01 0.07,0.02 0.01,0.01 -0.01,0.02 0.0,0.02 0.03,0.01 0.07,-0.02 0.09,0.0 0.01,0.01 -0.0,0.03 0.0,0.04 0.01,0.05 0.05,0.09 0.07,0.13 0.01,0.04 0.01,0.09 0.02,0.13 0.01,0.02 0.04,0.02 0.04,0.04 0.01,0.02 0.0,0.04 0.0,0.07 0.01,0.02 0.01,0.05 0.02,0.07 0.0,0.01 0.04,0.03 0.02,0.04 -0.05,0.05 0.01,-0.12 -0.04,0.04 -0.02,0.05 -0.02,0.13 -0.04,0.18 -0.01,0.01 -0.02,0.01 -0.02,0.02 -0.0,0.01 0.01,0.02 0.0,0.02 -0.02,0.01 -0.06,0.0 -0.07,0.02 -0.02,0.06 -0.0,0.14 -0.02,0.2 -0.01,0.04 -0.05,0.06 -0.07,0.09 -0.01,0.02 -0.01,0.07 -0.02,0.09 -0.01,0.02 -0.06,0.04 -0.07,0.04 -0.02,0.03 -0.01,0.08 -0.02,0.11 -0.01,0.03 -0.04,0.11 -0.04,0.02 0.0,-0.07 -0.01,0.06 -0.02,0.07 -0.04,0.01 -0.07,0.0 -0.11,0.0 z","M498.09,583.36 c -0.69,-0.15 -1.38,-0.31 -2.08,-0.44 -1.11,-0.2 -1.59,0.75 -1.97,1.59 -0.05,0.12 -0.06,0.25 -0.04,0.38 0.03,0.35 0.08,0.7 0.18,1.04 0.04,0.15 0.11,0.31 0.22,0.42 0.21,0.21 0.55,0.35 0.82,0.49 0.05,0.03 0.1,0.06 0.15,0.09 0.11,0.08 0.21,0.18 0.33,0.24 0.05,0.02 0.1,0.01 0.15,0.02 1.83,0.54 0.69,0.41 1.66,0.35 0.24,-0.01 0.67,0.03 0.86,-0.02 0.13,-0.04 0.23,-0.16 0.35,-0.22 0.29,-0.16 0.34,-0.08 0.55,-0.35 0.16,-0.21 0.11,-0.37 0.15,-0.62 0.03,-0.16 0.1,-0.31 0.11,-0.46 0.0,-0.07 -0.07,-0.11 -0.09,-0.18 -0.02,-0.07 -0.03,-0.43 -0.09,-0.55 -0.04,-0.09 -0.1,-0.17 -0.15,-0.24 -0.06,-0.08 -0.19,-0.1 -0.24,-0.2 -0.01,-0.01 0.02,-0.03 0.02,-0.04 0.01,-0.04 -0.02,-0.15 -0.02,-0.15 -0.02,-0.08 -0.05,-0.16 -0.09,-0.24 -0.02,-0.04 -0.05,-0.07 -0.07,-0.11 -0.01,-0.02 0.0,-0.04 0.0,-0.07 -0.01,-0.04 -0.01,-0.08 -0.02,-0.11 -0.01,-0.03 -0.05,-0.06 -0.07,-0.09 -0.01,-0.02 -0.01,-0.05 -0.02,-0.07 -0.02,-0.02 -0.1,-0.05 -0.11,-0.09 -0.01,-0.04 0.01,-0.08 0.0,-0.11 -0.01,-0.01 -0.03,0.0 -0.04,0.0 -0.03,0.0 -0.04,0.0 -0.07,-0.02 -0.01,-0.01 -0.01,-0.03 -0.02,-0.04 -0.01,-0.01 -0.03,-0.01 -0.04,-0.02 -0.01,-0.01 0.01,-0.02 0.0,-0.02 -0.02,-0.02 -0.04,0.0 -0.07,0.0 -0.02,-0.01 -0.04,-0.01 -0.07,-0.02 0.0,-0.01 0.01,-0.02 0.0,-0.02 -0.03,-0.01 -0.09,0.02 -0.11,0.0 -0.03,-0.02 -0.06,-0.06 -0.09,-0.09 z","M499.17,587.27 c -0.35,0.05 -0.69,0.1 -1.04,0.15 -0.32,0.07 -0.63,0.15 -0.95,0.2 -0.17,0.03 -0.35,0.0 -0.53,0.02 -0.4,0.04 -0.79,0.11 -1.19,0.15 -0.09,0.01 -0.18,-0.01 -0.27,0.0 -0.3,0.02 -0.59,0.06 -0.88,0.09 -0.48,0.04 -0.95,0.09 -1.44,0.09 -0.39,0.0 -0.78,0.0 -1.17,0.0 -0.37,0.0 -0.74,0.01 -1.1,-0.02 -0.57,-0.06 -0.56,-0.07 -1.15,-0.15 -0.12,-0.02 -0.25,-0.02 -0.38,-0.04 -0.29,-0.05 -0.02,-0.04 -0.2,-0.04 -0.03,0.0 -0.11,-0.01 -0.09,0.0 0.07,0.03 0.16,0.02 0.22,0.07 0.04,0.03 -0.09,0.0 -0.13,0.0 -0.09,-0.01 -0.18,-0.01 -0.27,-0.02 -0.06,-0.01 -0.12,-0.0 -0.18,-0.02 -0.01,-0.01 0.01,-0.04 0.0,-0.04 -0.15,-0.04 -0.32,0.0 -0.46,-0.07 -0.03,-0.01 -0.04,-0.05 -0.07,-0.07 -0.07,-0.03 -0.15,-0.04 -0.22,-0.07 -0.13,-0.08 -0.24,-0.18 -0.38,-0.24 -0.16,-0.14 -0.38,-0.07 -0.55,-0.15 -0.14,-0.06 -0.26,-0.16 -0.4,-0.22 -0.13,-0.06 -0.35,-0.03 -0.49,-0.07 -0.1,-0.03 -0.19,-0.07 -0.29,-0.11 -0.18,-0.02 -0.36,-0.03 -0.53,-0.07 -0.06,-0.01 -0.63,-0.18 -0.77,-0.2 -0.08,-0.01 -0.16,0.01 -0.24,0.0 -0.04,-0.01 -0.07,-0.03 -0.11,-0.04 -0.06,-0.02 -0.12,-0.03 -0.18,-0.07 -0.13,-0.08 -0.21,-0.17 -0.33,-0.27 -0.08,-0.06 -0.25,-0.23 -0.38,-0.24 -0.02,-0.0 -0.03,0.05 -0.04,0.04 -0.06,-0.06 -0.12,-0.12 -0.18,-0.18 0.0,-0.01 0.01,-0.03 0.0,-0.04 -0.07,-0.07 -0.15,-0.12 -0.22,-0.18 -0.03,-0.03 -0.06,-0.06 -0.09,-0.09 -0.01,-0.01 0.01,-0.02 0.0,-0.02 -0.12,-0.09 -0.24,-0.17 -0.38,-0.24 -0.05,-0.02 -0.12,0.01 -0.15,-0.02 -0.01,-0.01 -0.03,-0.07 -0.04,-0.09 -0.03,-0.03 -0.07,-0.04 -0.09,-0.07 -0.01,-0.01 0.01,-0.03 0.0,-0.04 -0.02,-0.07 -0.11,-0.07 -0.13,-0.15 -0.01,-0.06 0.04,-0.15 0.02,-0.2 -0.01,-0.02 -0.05,0.07 -0.07,0.04 -0.02,-0.03 0.02,-0.07 0.02,-0.11 0.01,-0.09 0.01,-0.18 0.02,-0.27 0.05,-0.26 0.33,-0.81 0.51,-0.99 0.04,-0.05 0.11,-0.07 0.15,-0.11 0.05,-0.05 0.08,-0.13 0.13,-0.18 0.03,-0.03 0.08,-0.02 0.11,-0.04 0.07,-0.04 0.13,-0.1 0.2,-0.13 0.06,-0.03 0.13,-0.03 0.2,-0.04 0.1,-0.02 0.2,-0.03 0.29,-0.07 0.17,-0.08 0.31,-0.22 0.49,-0.29 0.39,-0.15 1.67,-0.21 1.79,-0.22 0.35,-0.03 0.71,-0.05 1.06,-0.07 0.91,-0.03 1.83,0.02 2.74,0.07 0.3,0.02 0.6,0.02 0.91,0.04 0.34,0.03 0.68,0.07 1.02,0.11 0.03,0.0 0.06,0.02 0.09,0.02 0.46,0.02 0.95,-0.06 1.39,0.07 0.18,0.05 0.34,0.17 0.51,0.24 0.37,0.26 0.83,0.28 1.24,0.44 0.77,0.31 0.46,0.31 1.1,0.71 0.15,0.1 0.33,0.15 0.49,0.24 0.03,0.02 -0.06,0.0 -0.09,0.0 0.1,0.04 0.2,0.06 0.29,0.11 0.26,0.14 0.21,0.23 0.44,0.44 0.07,0.06 0.16,0.1 0.24,0.15 0.27,0.19 0.49,0.43 0.8,0.57 0.11,0.05 0.25,0.07 0.35,0.13 0.06,0.04 0.32,0.47 0.38,0.57 0.02,0.03 -0.03,0.11 -0.02,0.13 0.03,0.05 0.19,0.11 0.22,0.13 0.03,0.03 0.02,0.08 0.04,0.11 0.02,0.04 0.04,0.07 0.07,0.11 0.01,0.03 0.01,0.06 0.02,0.09 0.02,0.03 0.05,0.06 0.07,0.09 0.04,0.07 0.01,0.11 0.02,0.18 0.03,0.11 0.08,0.15 0.09,0.27 0.0,0.02 -0.03,0.23 0.0,0.27 0.01,0.01 0.03,0.01 0.04,0.02 0.01,0.01 -0.01,0.03 0.0,0.04 0.02,0.02 0.01,-0.05 0.02,-0.07 0.02,-0.03 0.04,-0.06 0.07,-0.09 z","M500.06,588.14 c 0.82,0.22 0.38,0.12 1.94,0.24 0.49,0.04 0.99,0.06 1.48,0.09 0.63,0.09 1.26,0.2 1.9,0.27 0.48,0.05 0.96,0.02 1.44,0.07 0.74,0.07 1.47,0.2 2.21,0.27 0.28,0.02 0.75,0.02 1.06,-0.11 0.07,-0.03 0.12,-0.1 0.2,-0.11 0.2,-0.03 0.4,-0.02 0.6,-0.02 0.5,-0.01 1.0,0.01 1.5,0.0 1.76,-0.05 0.26,-0.02 1.81,-0.11 0.18,-0.01 0.37,0.03 0.55,0.0 0.05,-0.01 0.09,-0.03 0.13,-0.04 0.12,-0.03 0.24,-0.06 0.35,-0.09 0.18,-0.04 0.36,-0.06 0.53,-0.11 0.04,-0.01 0.07,-0.06 0.11,-0.09 0.07,-0.02 0.15,-0.05 0.22,-0.07 0.12,-0.02 0.26,0.0 0.38,-0.04 0.1,-0.04 0.17,-0.14 0.27,-0.2 0.22,-0.13 0.47,-0.21 0.69,-0.35 0.15,-0.1 0.25,-0.25 0.38,-0.38 0.15,-0.14 0.3,-0.29 0.46,-0.42 0.08,-0.07 0.18,-0.11 0.27,-0.18 0.12,-0.1 0.24,-0.19 0.35,-0.29 0.05,-0.03 0.11,-0.05 0.15,-0.09 0.11,-0.08 0.2,-0.17 0.31,-0.24 0.04,-0.03 0.1,-0.02 0.13,-0.04 0.11,-0.08 0.19,-0.19 0.29,-0.29 0.01,-0.01 0.35,-0.31 0.35,-0.31 0.21,-0.34 0.09,-0.25 0.15,-0.51 0.02,-0.07 0.06,-0.13 0.07,-0.2 0.05,-0.36 -0.05,-0.73 -0.11,-1.08 -0.03,-0.15 -0.03,-0.31 -0.07,-0.46 -0.02,-0.09 -0.08,-0.17 -0.11,-0.27 -0.04,-0.12 -0.17,-0.77 -0.29,-0.91 -0.13,-0.16 -0.33,-0.24 -0.49,-0.38 -0.06,-0.05 -0.13,-0.11 -0.18,-0.18 -0.1,-0.12 -0.08,-0.22 -0.24,-0.31 -0.06,-0.03 -0.12,-0.04 -0.18,-0.07 -0.36,-0.14 -0.59,-0.2 -0.95,-0.31 -0.41,-0.12 -0.65,-0.22 -1.04,-0.31 -0.24,-0.06 -0.48,-0.11 -0.73,-0.15 -0.17,-0.03 -0.34,-0.04 -0.51,-0.07 -0.16,-0.03 -0.31,-0.08 -0.46,-0.11 -0.58,-0.12 -1.18,-0.23 -1.77,-0.24 -0.27,-0.01 -0.53,0.01 -0.8,0.0 -0.19,-0.01 -0.38,-0.03 -0.57,-0.04 -0.32,-0.01 -0.63,-0.02 -0.95,-0.02 -0.49,-0.01 -0.99,-0.0 -1.48,-0.02 -0.49,-0.02 -0.97,-0.1 -1.46,-0.13 -0.43,-0.03 -0.85,0.07 -1.28,0.04 -1.3,-0.08 -0.34,-0.07 -1.22,-0.07 -0.16,0.0 -0.32,-0.01 -0.49,0.0 -0.13,0.01 -0.69,0.13 -0.95,0.13 -0.24,0.01 -0.49,-0.02 -0.73,0.0 -0.08,0.01 -0.31,0.15 -0.38,0.18 -0.18,0.07 -0.4,0.05 -0.57,0.13 -0.12,-0.04 -0.09,0.1 -0.15,0.13 -0.21,0.1 -0.44,0.16 -0.66,0.22 -0.12,0.04 -0.24,0.07 -0.35,0.11 -0.03,0.01 -0.06,0.03 -0.09,0.04 -0.18,0.06 -0.37,0.11 -0.55,0.18 -0.11,0.04 -0.2,0.09 -0.31,0.13 -0.09,0.03 -0.19,0.05 -0.29,0.09 -0.06,0.02 -0.1,0.07 -0.15,0.09 -0.06,0.02 -0.12,0.03 -0.18,0.04 -0.05,0.02 -0.07,0.09 -0.11,0.11 -0.06,0.03 -0.11,0.0 -0.15,0.04 -0.05,0.04 -0.09,0.09 -0.13,0.13 -0.1,0.09 -0.22,0.16 -0.31,0.27 -0.25,0.29 -0.12,0.36 -0.27,0.55 -0.06,0.08 -0.15,0.14 -0.2,0.22 -0.03,0.04 -0.03,0.1 -0.04,0.15 -0.08,0.21 -0.15,0.46 -0.24,0.66 -0.04,0.09 -0.11,0.17 -0.15,0.27 -0.02,0.03 -0.02,0.07 -0.02,0.11 -0.02,0.12 -0.03,0.25 -0.04,0.38 -0.02,0.14 -0.09,0.36 -0.11,0.49 -0.03,0.19 -0.03,0.63 -0.02,0.8 0.0,0.04 0.03,0.07 0.02,0.11 -0.01,0.06 -0.09,0.1 -0.11,0.15 -0.03,0.06 -0.04,0.13 -0.07,0.2 -0.06,0.14 -0.13,0.18 -0.09,0.33 0.01,0.05 0.16,0.18 0.18,0.2 0.06,0.07 0.06,0.17 0.11,0.24 0.04,0.06 0.09,0.1 0.13,0.15 0.01,0.01 -0.01,0.03 0.0,0.04 0.01,0.01 0.03,0.01 0.04,0.02 0.01,0.01 -0.0,0.02 0.0,0.02 0.01,0.02 0.04,0.07 0.04,0.04 0.0,-0.03 -0.06,-0.04 -0.04,-0.07 0.02,-0.02 0.07,-0.02 0.09,0.0 0.02,0.02 0.01,0.06 0.02,0.09 0.02,0.03 0.07,0.04 0.07,0.07 -0.16,0.42 -0.1,0.09 -0.04,0.2 0.02,0.04 0.02,0.08 0.04,0.11 0.1,0.14 0.24,0.32 0.4,0.42 0.02,0.01 0.05,0.01 0.07,0.02 0.06,0.0 0.01,0.05 0.02,0.07 0.07,0.07 0.19,0.12 0.27,0.15 0.05,0.02 0.01,-0.05 0.02,-0.07 0.01,-0.01 0.01,-0.0 0.02,0.0 0.06,0.01 0.12,0.01 0.18,0.02 0.1,0.02 0.18,0.08 0.27,0.13 0.07,0.04 0.12,0.12 0.2,0.15 0.02,0.01 0.05,-0.01 0.07,0.0 0.01,0.01 -0.01,0.03 0.0,0.04 0.03,0.04 0.05,0.08 0.09,0.11 0.01,0.01 0.03,0.0 0.04,0.0 0.15,0.0 0.14,-0.06 0.22,-0.2 z","M530.16,585.2 v -0.48 l 0.29,-0.01 c 0.16,-0.01 0.57,-0.02 0.9,-0.03 l 0.61,-0.01 0.07,0.25 c 0.04,0.14 0.11,0.35 0.16,0.48 0.05,0.13 0.08,0.24 0.08,0.24 -0.01,0.01 -0.48,0.02 -1.06,0.02 l -1.05,0.01 z","M520.63,582.97 c 0.56,0.34 1.11,0.41 1.75,0.51 0.1,0.02 0.24,0.06 0.33,0.07 0.07,0.01 0.13,-0.01 0.2,0.0 0.28,0.03 0.49,0.07 0.77,0.07 0.08,0.0 0.16,0.02 0.24,0.0 0.04,-0.01 0.07,-0.04 0.11,-0.04 0.11,-0.02 0.24,0.0 0.35,0.0 0.18,0.0 0.36,-0.01 0.53,0.0 1.24,0.08 0.47,0.03 0.99,0.09 0.07,0.01 0.15,0.02 0.22,0.02 0.03,0.0 0.06,-0.01 0.09,0.0 0.06,0.02 0.11,0.06 0.18,0.07 0.1,0.01 0.21,-0.01 0.31,-0.02 0.17,-0.01 0.34,-0.03 0.51,-0.04 0.16,-0.01 0.32,0.01 0.49,0.0 0.04,-0.0 0.09,-0.02 0.13,-0.02 0.06,-0.0 0.14,0.05 0.18,0.0 0.03,-0.04 -0.11,-0.04 -0.11,-0.09 0.0,-0.04 0.07,-0.02 0.11,-0.02 0.09,-0.01 0.18,-0.02 0.27,-0.02 0.14,-0.01 0.37,0.04 0.51,0.04 0.2,0.01 0.4,0.0 0.6,0.0 0.27,0.0 -0.07,-0.01 0.15,0.02 0.1,0.01 0.18,-0.01 0.27,-0.02 0.25,-0.04 0.2,0.0 0.42,0.04 0.06,0.01 0.12,-0.02 0.18,0.02 0.06,0.05 0.09,0.13 0.15,0.18 0.04,0.02 0.09,-0.01 0.13,0.0 0.05,0.01 0.09,0.1 0.11,0.11 0.03,0.02 0.27,0.01 0.33,0.02 0.06,0.01 0.15,0.04 0.2,0.07 0.03,0.02 0.04,0.06 0.07,0.07 0.02,0.0 0.14,0.01 0.15,0.02 0.01,0.01 0.01,0.04 0.02,0.04 0.03,0.02 0.07,0.02 0.11,0.02 0.02,0.0 0.05,-0.01 0.07,0.0 0.02,0.01 0.02,0.05 0.04,0.07 0.06,0.04 0.07,-0.06 0.18,0.07 0.02,0.03 0.02,0.06 0.04,0.09 0.01,0.01 0.03,0.01 0.04,0.02 0.01,0.01 0.01,0.03 0.02,0.04 0.11,0.11 -0.03,-0.09 0.09,0.07 0.01,0.01 0.02,0.03 0.02,0.04 0.0,0.01 -0.01,0.02 0.0,0.02 0.13,0.04 0.02,-0.12 0.2,0.09 0.01,0.02 -0.01,0.05 0.0,0.07 0.02,0.03 0.04,0.06 0.07,0.09 0.01,0.0 0.02,-0.01 0.02,0.0 0.01,0.01 -0.01,0.02 0.0,0.02 0.01,0.01 0.03,-0.01 0.04,0.0 0.01,0.01 -0.03,0.01 -0.02,0.02 0.01,0.01 0.03,-0.01 0.04,0.0 0.08,0.08 -0.02,0.53 0.02,0.66 0.04,0.13 0.07,0.27 0.02,0.4 -0.02,0.05 0.02,0.09 0.02,0.13 0.0,0.04 -0.08,0.04 -0.11,0.07 -0.18,0.13 0.08,-0.01 -0.15,0.18 -0.03,0.02 -0.07,0.03 -0.11,0.04 -0.13,0.06 -0.23,0.13 -0.38,0.18 -0.18,0.06 -0.58,0.12 -0.77,0.15 -0.16,0.03 -0.37,-0.01 -0.53,0.02 -0.1,0.02 -0.19,0.05 -0.29,0.07 -0.28,0.04 -0.56,0.03 -0.84,0.07 -0.14,0.02 -0.28,0.05 -0.42,0.07 -0.15,0.02 -0.37,-0.03 -0.51,0.02 -0.04,0.01 -0.01,0.09 -0.04,0.11 -0.08,0.04 -0.18,0.03 -0.27,0.04 -0.04,0.01 -0.07,0.02 -0.11,0.02 -0.41,0.04 -0.82,0.08 -1.24,0.11 -0.35,0.03 -0.71,-0.02 -1.06,0.0 -0.13,0.01 -0.26,0.04 -0.4,0.04 -0.15,0.01 -0.3,-0.02 -0.44,0.0 -0.07,0.01 -0.15,0.03 -0.22,0.04 -0.11,0.01 -0.22,-0.0 -0.33,0.0 -0.19,-0.24 -0.28,0.04 -0.42,0.04 -0.13,0.01 -0.27,-0.01 -0.4,0.0 -0.07,0.01 -0.13,0.04 -0.2,0.04 -0.04,0.01 -0.09,0.0 -0.13,0.0 -0.15,0.03 -0.29,0.07 -0.44,0.09 -0.04,0.01 -0.09,-0.0 -0.13,0.0 -0.15,0.01 -0.29,0.02 -0.44,0.02 -0.24,0.01 -0.49,0.02 -0.73,0.02 -0.15,0.0 -0.31,-0.01 -0.46,0.0 -0.04,0.0 -0.09,0.02 -0.13,0.02 -0.24,0.01 -0.49,0.01 -0.73,0.02 -0.13,0.01 -0.25,0.02 -0.38,0.02 -0.18,0.01 -0.38,-0.04 -0.55,0.0 -0.02,0.0 -0.03,0.02 -0.04,0.02 -0.56,0.05 -0.28,0.05 -0.66,-0.04 -0.06,-0.02 -0.13,-0.0 -0.2,-0.02 -0.04,-0.01 -0.07,-0.06 -0.11,-0.07 -0.03,-0.01 -0.06,0.02 -0.09,0.0 -0.05,-0.03 -0.09,-0.09 -0.13,-0.13 -0.05,-0.04 -0.1,-0.1 -0.15,-0.13 -0.03,-0.02 -0.08,-0.01 -0.11,-0.02 -0.01,-0.0 0.0,-0.02 0.0,-0.02 -0.01,-0.02 -0.04,-0.04 -0.04,-0.07 -0.01,-0.02 0.0,-0.04 0.0,-0.07 -0.0,-0.02 -0.02,-0.03 -0.02,-0.04 -0.01,-0.08 -0.05,-0.49 -0.02,-0.57 0.07,-0.26 0.04,-0.02 0.13,-0.22 0.04,-0.09 0.04,-0.19 0.09,-0.27 0.04,-0.06 0.1,-0.09 0.15,-0.13 0.05,-0.08 0.11,-0.16 0.15,-0.24 0.03,-0.06 0.04,-0.12 0.07,-0.18 0.03,-0.06 0.08,-0.12 0.11,-0.18 0.02,-0.03 0.02,-0.08 0.04,-0.11 0.06,-0.1 0.14,-0.19 0.2,-0.29 0.1,-0.16 0.04,-0.16 0.13,-0.33 0.02,-0.04 0.07,-0.07 0.09,-0.11 0.12,-0.23 -0.06,0.01 -0.02,-0.22 0.0,-0.02 0.12,-0.07 0.15,-0.09 0.07,-0.04 0.14,-0.08 0.22,-0.11 0.04,-0.01 0.08,-0.01 0.11,-0.02 0.05,-0.02 0.09,-0.06 0.13,-0.09 0.08,-0.04 0.16,-0.05 0.24,-0.09 0.47,-0.21 -0.01,0.02 0.31,-0.18 0.02,-0.01 0.05,-0.01 0.07,-0.02 0.07,-0.04 0.13,-0.12 0.2,-0.18 0.01,-0.01 0.04,-0.01 0.04,-0.02 0.01,-0.04 -0.04,-0.09 -0.02,-0.13 0.02,-0.03 0.05,-0.05 0.07,-0.09 0.01,-0.01 -0.01,-0.03 0.0,-0.04 0.01,-0.03 0.03,-0.04 0.04,-0.07 0.07,-0.15 0.11,-0.12 0.27,-0.04 z","M519.13,585.78 c -2.0,-0.02 -3.01,-0.05 -3.71,-0.11 -0.35,-0.03 -0.9,-0.11 -1.01,-0.14 -0.06,-0.02 -0.15,-0.02 -0.27,-0.01 -0.58,0.05 -5.24,0.04 -7.4,-0.02 -0.43,-0.01 -1.34,-0.04 -2.02,-0.06 -1.44,-0.04 -5.03,-0.15 -6.43,-0.2 -3.52,-0.12 -4.17,-0.14 -4.37,-0.16 l -0.23,-0.01 v -0.48 -0.48 l 0.08,0.0 c 0.05,0.0 0.32,0.01 0.61,0.02 0.68,0.03 4.58,0.16 6.38,0.22 3.76,0.12 6.03,0.18 9.06,0.23 3.94,0.07 5.39,0.1 5.7,0.12 0.18,0.01 0.41,0.03 0.52,0.03 1.86,0.12 7.55,0.12 13.4,-0.0 l 0.73,-0.01 v 0.48 0.48 l -0.73,0.02 c -0.4,0.01 -1.04,0.02 -1.42,0.04 -2.09,0.06 -6.2,0.1 -8.88,0.07 z","M491.44,585.0 c -6.0,-0.24 -10.79,-0.43 -10.92,-0.44 l -0.11,-0.01 0.01,-0.47 c 0.0,-0.26 0.01,-0.47 0.01,-0.48 0.0,-0.0 0.89,0.03 1.97,0.07 1.92,0.08 3.93,0.15 5.78,0.22 0.5,0.02 1.56,0.06 2.34,0.09 0.78,0.03 1.71,0.06 2.07,0.08 0.35,0.01 0.74,0.03 0.87,0.04 l 0.23,0.01 v 0.48 0.48 l -0.18,-0.0 c -0.1,-0.0 -1.03,-0.04 -2.06,-0.08 z","M478.39,584.47 c -3.94,-0.17 -4.62,-0.2 -4.63,-0.2 -0.01,0.0 -0.01,-0.11 -0.01,-0.49 v -0.49 l 0.1,0.01 c 0.16,0.01 1.05,0.05 2.6,0.12 0.72,0.03 2.41,0.1 3.12,0.13 0.39,0.02 0.74,0.03 0.78,0.03 l 0.07,0.01 v 0.49 c 0.0,0.27 -0.0,0.48 -0.01,0.48 -0.01,-0.0 -0.91,-0.04 -2.01,-0.09 z","M473.06,584.25 c -1.06,-0.05 -1.65,-0.07 -1.96,-0.09 -0.16,-0.01 -0.29,-0.01 -0.29,-0.01 -0.0,-0.0 0.36,-0.97 0.36,-0.98 0.0,-0.0 0.1,0.0 0.23,0.01 0.13,0.01 0.48,0.02 0.8,0.04 0.31,0.01 0.78,0.04 1.05,0.05 0.26,0.01 0.48,0.02 0.49,0.02 0.01,0.0 0.01,0.09 0.01,0.49 v 0.49 l -0.01,-0.0 c -0.01,-0.0 -0.31,-0.01 -0.67,-0.03 z","M470.76,584.2 l -0.03,-0.19 0.06,-0.25 0.02,0.33 z","M470.78,584.2 l -0.27,-1.22 0.7,0.04 z","M531.78,583.81 c 0.53,2.66 1.19,2.62 1.19,2.62 l 0.25,-1.78 z","M349.54,206.48 c -0.7,-0.42 -1.29,-0.77 -1.29,-0.77 -0.01,-0.01 -0.02,-0.03 -0.04,-0.26 -0.01,-0.14 -0.02,-0.27 -0.02,-0.29 -0.0,-0.04 -0.0,-0.04 0.03,0.04 0.04,0.11 0.06,0.16 0.12,0.25 0.12,0.2 0.29,0.38 0.56,0.59 0.23,0.17 0.44,0.3 1.09,0.69 0.55,0.33 0.86,0.51 0.86,0.52 0.0,0.0 -0.0,0.0 -0.01,0.0 -0.0,-0.0 -0.58,-0.34 -1.28,-0.76 z"]},"grid":{"sectors":[{"id":"troieshchyna","name":"Деснянський","baseMw":130,"population":0.16,"district":"Деснянський"},{"id":"pozniaky","name":"Дарницький","baseMw":100,"population":0.13,"district":"Дарницький"},{"id":"solomianskyi","name":"Солом’янський","baseMw":74,"population":0.1,"district":"Солом’янський"},{"id":"obolon","name":"Оболонський","baseMw":105,"population":0.13,"district":"Оболонський"},{"id":"podil","name":"Подільський","baseMw":66,"population":0.075,"district":"Подільський"},{"id":"borshchahivka","name":"Святошинський","baseMw":98,"population":0.12,"district":"Святошинський"},{"id":"pechersk","name":"Печерський","baseMw":78,"population":0.095,"district":"Печерський"},{"id":"rusanivka","name":"Дніпровський","baseMw":49,"population":0.055,"district":"Дніпровський"},{"id":"teremky","name":"Голосіївський","baseMw":69,"population":0.08,"district":"Голосіївський"},{"id":"lukianivka","name":"Шевченківський","baseMw":48,"population":0.055,"district":"Шевченківський"}],"critical":[{"id":"likarnia","name":"Допоміжні служби лікарні","sectorId":"pozniaky","fuelMin":240},{"id":"water","name":"Насоси верхніх поверхів","sectorId":"troieshchyna","fuelMin":270},{"id":"telecom","name":"Резерв квартального звʼязку","sectorId":"podil","fuelMin":300}]},"city":{"name":"Київ","timezone":"Europe/Kyiv","sponsor":null,"masyvy":[{"name":"Троєщина","locative":"на Троєщині","district":"Деснянський","districtSlug":"desnianskyi","homeSectorId":"troieshchyna"},{"name":"Лісовий масив","locative":"на Лісовому масиві","district":"Деснянський","districtSlug":"desnianskyi","homeSectorId":"troieshchyna"},{"name":"Вигурівщина","locative":"на Вигурівщині","district":"Деснянський","districtSlug":"desnianskyi","homeSectorId":"troieshchyna"},{"name":"Позняки","locative":"на Позняках","district":"Дарницький","districtSlug":"darnytskyi","homeSectorId":"pozniaky"},{"name":"Осокорки","locative":"на Осокорках","district":"Дарницький","districtSlug":"darnytskyi","homeSectorId":"pozniaky"},{"name":"Харківський масив","locative":"на Харківському масиві","district":"Дарницький","districtSlug":"darnytskyi","homeSectorId":"pozniaky"},{"name":"Бортничі","locative":"у Бортничах","district":"Дарницький","districtSlug":"darnytskyi","homeSectorId":"pozniaky"},{"name":"Русанівка","locative":"на Русанівці","district":"Дніпровський","districtSlug":"dniprovskyi","homeSectorId":"rusanivka"},{"name":"Березняки","locative":"на Березняках","district":"Дніпровський","districtSlug":"dniprovskyi","homeSectorId":"rusanivka"},{"name":"Стара Дарниця","locative":"у Старій Дарниці","district":"Дніпровський","districtSlug":"dniprovskyi","homeSectorId":"rusanivka"},{"name":"Оболонь","locative":"на Оболоні","district":"Оболонський","districtSlug":"obolonskyi","homeSectorId":"obolon"},{"name":"Мінський масив","locative":"на Мінському масиві","district":"Оболонський","districtSlug":"obolonskyi","homeSectorId":"obolon"},{"name":"Пуща-Водиця","locative":"у Пущі-Водиці","district":"Оболонський","districtSlug":"obolonskyi","homeSectorId":"obolon"},{"name":"Виноградар","locative":"на Виноградарі","district":"Подільський","districtSlug":"podilskyi","homeSectorId":"podil"},{"name":"Поділ","locative":"на Подолі","district":"Подільський","districtSlug":"podilskyi","homeSectorId":"podil"},{"name":"Борщагівка","locative":"на Борщагівці","district":"Святошинський","districtSlug":"sviatoshynskyi","homeSectorId":"borshchahivka"},{"name":"Академмістечко","locative":"на Академмістечку","district":"Святошинський","districtSlug":"sviatoshynskyi","homeSectorId":"borshchahivka"},{"name":"Святошин","locative":"у Святошині","district":"Святошинський","districtSlug":"sviatoshynskyi","homeSectorId":"borshchahivka"},{"name":"Теремки","locative":"на Теремках","district":"Голосіївський","districtSlug":"holosiivskyi","homeSectorId":"teremky"},{"name":"Деміївка","locative":"на Деміївці","district":"Голосіївський","districtSlug":"holosiivskyi","homeSectorId":"teremky"},{"name":"Голосіїв","locative":"у Голосієві","district":"Голосіївський","districtSlug":"holosiivskyi","homeSectorId":"teremky"},{"name":"Чоколівка","locative":"на Чоколівці","district":"Солом’янський","districtSlug":"solomianskyi","homeSectorId":"solomianskyi"},{"name":"Відрадний","locative":"на Відрадному","district":"Солом’янський","districtSlug":"solomianskyi","homeSectorId":"solomianskyi"},{"name":"Жуляни","locative":"у Жулянах","district":"Солом’янський","districtSlug":"solomianskyi","homeSectorId":"solomianskyi"},{"name":"Караваєві дачі","locative":"на Караваєвих дачах","district":"Солом’янський","districtSlug":"solomianskyi","homeSectorId":"solomianskyi"},{"name":"Нивки","locative":"на Нивках","district":"Шевченківський","districtSlug":"shevchenkivskyi","homeSectorId":"lukianivka"},{"name":"Сирець","locative":"на Сирці","district":"Шевченківський","districtSlug":"shevchenkivskyi","homeSectorId":"lukianivka"},{"name":"Лукʼянівка","locative":"на Лукʼянівці","district":"Шевченківський","districtSlug":"shevchenkivskyi","homeSectorId":"lukianivka"},{"name":"Шулявка","locative":"на Шулявці","district":"Шевченківський","districtSlug":"shevchenkivskyi","homeSectorId":"lukianivka"},{"name":"Печерськ","locative":"на Печерську","district":"Печерський","districtSlug":"pecherskyi","homeSectorId":"pechersk"},{"name":"Звіринець","locative":"на Звіринці","district":"Печерський","districtSlug":"pecherskyi","homeSectorId":"pechersk"}]},"nezlamnist":{"source":"https://gisserver.kyivcity.gov.ua/mayno/rest/services/KYIV_API/Public_protection/MapServer/1/query?where=1%3D1&outFields=*&returnGeometry=true&outSR=4326&f=geojson&resultRecordCount=10000","updatedAt":"2026-09-14T08:16:13.000Z","builtAt":"2026-09-19T20:37:15.575Z","total":1169,"districts":[{"name":"Голосіївський","slug":"holosiivskyi","count":102,"generator":102,"heater":73,"points":[{"name":"АТБ","address":"вул. Степана Рудницького, 14-Б","schedule":"Щодня з 05:00 до 23:56"},{"name":"Школа №260","address":"вул. Героїв Маріуполя, 7-Б","schedule":"Щодня з 00:00 до 23:00"},{"name":"Концертний зал «Stereo Plaza»","address":"просп. Валерія Лобановського, 119","schedule":"Щодня з 00:00 до 23:00"}]},{"name":"Дарницький","slug":"darnytskyi","count":117,"generator":111,"heater":84,"points":[{"name":"Дитяча школа мистецтв №4","address":"вул. Анни Ахматової, 5","schedule":"ПН — СБ: 10:00–19:00"},{"name":"Гімназія №323","address":"вул. Олександра Мишуги, 5","schedule":"Щодня з 08:00 до 22:00"},{"name":"Ліцей №303","address":"вул. Михайла Драгоманова, 9-А","schedule":"Щодня з 08:00 до 20:00"}]},{"name":"Деснянський","slug":"desnianskyi","count":117,"generator":116,"heater":101,"points":[{"name":"Школа №250","address":"просп. Червоної Калини, 49-Б","schedule":"Щодня з 08:00 до 20:00"},{"name":"Pride cafe","address":"вул. Рональда Рейгана, 9","schedule":"Щодня з 07:30 до 21:00"},{"name":"Дитячо-юнацька спортивна школа №23","address":"просп. Червоної Калини, 26-А","schedule":"Щодня з 08:00 до 17:00"}]},{"name":"Дніпровський","slug":"dniprovskyi","count":114,"generator":114,"heater":109,"points":[{"name":"Підлітковий клуб «Юність»","address":"вул. Празька, 18","schedule":"Щодня з 14:00 до 19:00"},{"name":"Школа №148","address":"вул. Будівельників, 37","schedule":"Цілодобово"},{"name":"Maestro","address":"вул. Івана Микитенка, 20-Б","schedule":"Цілодобово"}]},{"name":"Оболонський","slug":"obolonskyi","count":110,"generator":110,"heater":83,"points":[{"name":"Навчально-виховний комплекс №143","address":"вул. Богатирська, 2-Б","schedule":"Щодня з 08:00 до 22:00"},{"name":"Стаціонарний пункт незламності ДСНС","address":"вул. Бережанська, 7","schedule":"Цілодобово"},{"name":"Стаціонарний пункт незламності ГУ НП","address":"просп. Дмитра Павличка, 10-А","schedule":"Цілодобово"}]},{"name":"Печерський","slug":"pecherskyi","count":61,"generator":58,"heater":45,"points":[{"name":"Бозна Coffee","address":"вул. Левандовська, 3-А","schedule":"Щодня з 08:00 до 20:00"},{"name":"This is Пивбар","address":"б-р Лесі Українки, 26","schedule":"Щодня з 09:00 до 22:00"},{"name":"Ліцей №145","address":"вул. Шота Руставелі, 46","schedule":"Щодня з 08:00 до 22:00"}]},{"name":"Подільський","slug":"podilskyi","count":104,"generator":104,"heater":73,"points":[{"name":"ЗДО №8","address":"вул. Наталії Ужвій, 7-А","schedule":"Цілодобово"},{"name":"ЗДО №307","address":"вул. Братська, 7/11","schedule":"Цілодобово"},{"name":"ЗДО №188","address":"вул. Івана Виговського, 6-А","schedule":"Цілодобово"}]},{"name":"Святошинський","slug":"sviatoshynskyi","count":138,"generator":135,"heater":126,"points":[{"name":"Стаціонарний пункт незламності ГУ НП","address":"просп. Берестейський, 109","schedule":"Цілодобово"},{"name":"Управління соціального захисту населення","address":"вул. Гната Юри, 14-Б","schedule":"Щодня з 08:00 до 18:00"},{"name":"Київський міжнародний університет","address":"вул. Львівська, 49","schedule":"Щодня з 08:00 до 20:00"}]},{"name":"Солом’янський","slug":"solomianskyi","count":102,"generator":102,"heater":45,"points":[{"name":"Бібліотека №15","address":"вул. Олекси Тихого, 34/36","schedule":"Щодня з 08:00 до 22:00"},{"name":"Позашкільний навчальний заклад «Міжшкільний плавальний басейн «Олімпік» м. Києва»","address":"вул. Кавказька, 10","schedule":"Щодня з 08:00 до 22:00"},{"name":"Школа-дитячий садочок «Сяйво»","address":"вул. Андрія Мельника, 12","schedule":"Цілодобово"}]},{"name":"Шевченківський","slug":"shevchenkivskyi","count":204,"generator":182,"heater":162,"points":[{"name":"ЗДО №465","address":"вул. Данила Щербаківського, 49-Г","schedule":"Цілодобово"},{"name":"Школа №135","address":"вул. Михайла Коцюбинського, 12-Б","schedule":"Цілодобово"},{"name":"ЗДО №348","address":"вул. Печенізька, 18","schedule":"Цілодобово"}]}]},"stories":[{"id":"baker","sectorId":"podil","speaker":"Пекар із Подолу","avatar":"baker","title":"Хліб до ранкової черги","at":540,"deadline":675,"need":45,"success":"Хліб буде. За круасани не обіцяю. Паливо до лікарні вже везуть.","failure":"Сьогодні заміс не встигли. Завтра спробуємо знову.","reward":"fuel"},{"id":"osbb","sectorId":"obolon","speaker":"Пані Людмила","avatar":"osbb","title":"Спільне заряджання","at":915,"deadline":1275,"need":60,"success":"Зарядились усі. Навіть той, хто казав, що графіків не існує.","failure":"Подовжувач змотала. Люди зайдуть в інше вікно."},{"id":"workshop","sectorId":"lukianivka","speaker":"Майстер із Лукʼянівки","title":"Повернути павербанки людям","at":750,"deadline":975,"need":35,"success":"Павербанки віддали. Люди питали, кому дякувати. Сказав — зміні.","failure":"Частина замовлень лишилася до завтра."},{"id":"school","sectorId":"teremky","speaker":"Вчителька","title":"Допишіть контрольну","at":600,"deadline":810,"need":35,"success":"Дописали. Двоє просили ще темряви, але ні.","failure":"Контрольну перенесли. Діти щасливі, вчителька — не дуже."},{"id":"laundry","sectorId":"borshchahivka","speaker":"Пральня біля дому","title":"Дійти до віджиму","at":825,"deadline":1035,"need":50,"success":"Усі машини дійшли. Шкарпетки, як завжди, не всі.","failure":"Цикл перервали. Речі дочекаються наступного вікна."},{"id":"dinner","sectorId":"pozniaky","speaker":"Харчоблок лікарні","title":"Гарячий обід","at":690,"deadline":900,"need":45,"success":"Обід поїхав у відділення теплим. Дякуємо.","failure":"Сьогодні видали готові набори. Гаряче перенесли."},{"id":"library","sectorId":"solomianskyi","speaker":"Бібліотекарка","title":"Встигнути на онлайн-іспит","at":660,"deadline":820,"need":30,"success":"Іспит склали. Тиша знову бібліотечна.","failure":"Іспит перенесли. Шукають інше вікно."},{"id":"pharmacy","sectorId":"rusanivka","speaker":"Аптекар","title":"Облік вечірніх замовлень","at":990,"deadline":1150,"need":35,"success":"Замовлення зібрали. Люди заберуть до закриття.","failure":"Частину замовлень перенесли на ранок."},{"id":"tailor","sectorId":"pechersk","speaker":"Майстриня","title":"Закінчити теплі ковдри","at":780,"deadline":940,"need":45,"success":"Ковдри готові. Передали у теплу кімнату.","failure":"Дошиють при наступному вікні."},{"id":"canteen","sectorId":"troieshchyna","speaker":"Кухарка","title":"Вечеря для сусідів","at":1080,"deadline":1240,"need":40,"success":"Вечеря гаряча. Сідайте, кому треба.","failure":"Сьогодні готові набори. Гаряче — наступного разу."},{"id":"music","sectorId":"teremky","speaker":"Викладач музики","title":"Записати дитячий концерт","at":900,"deadline":1060,"need":25,"success":"Концерт записали. Сусіди теж чули, їм сподобалось.","failure":"Порепетирували акустично. Запис наступного разу."},{"id":"print","sectorId":"lukianivka","speaker":"Друкар","title":"Надрукувати таблички пунктів","at":600,"deadline":760,"need":30,"success":"Таблички готові. Тепер пункт легше знайти.","failure":"Поки напишуть від руки."}],"calls":[{"id":"brief","speaker":"Начальник зміни","role":"Службова лінія","avatar":null,"at":510,"until":570,"condition":"always","text":"До вечора ліміт знизиться. Не тримай одну чергу в темряві надовго. Краще мінятися.","choices":[{"label":"Прийняв. Тримаю баланс","effect":"ack","detail":"Показати прогноз наступної години."}]},{"id":"baker","speaker":"Пекар із Подолу","role":"Знайомий голос","avatar":"baker","at":550,"until":640,"condition":"baker","text":"Це я, з пекарні. Тісто не читає графіків. Якщо встигнемо — хліб у пункт і паливо до лікарні.","choices":[{"label":"Стежу за вашим вікном","effect":"baker","detail":"Відкрити прогрес справи. Світло перемикаєш сам."},{"label":"Гарантувати не можу","effect":"ack","detail":"Не береш нового зобовʼязання."}]},{"id":"mother","speaker":"Мама","role":"Особисте","avatar":"mother","at":720,"until":775,"condition":"always","text":"Ти поїв? І не роби мені краще за всіх. Я термос набрала. Просто хотіла почути.","choices":[{"label":"Поїв. Увечері ще наберу","effect":"mother","detail":"Мама напише про свій вечір. Без бонусів."},{"label":"Мамо, я зараз на зміні","effect":"mother","detail":"Коротка розмова. Мама все розуміє."}]},{"id":"osbb","speaker":"Пані Людмила","role":"Голова ОСББ · Оболонь","avatar":"osbb","at":810,"until":875,"condition":"always","text":"Люди готові заряджатись разом. Тільки скажіть, на котру годину подовжувач діставати. І графік закріпіть!","choices":[{"label":"Обіцяю світло з 18:00 до 21:00","effect":"promiseOsbb","detail":"Оболонь: вечірня обіцянка. Її виконання впливає на бал."},{"label":"Орієнтуйтесь на панель, без гарантії","effect":"ack","detail":"Без нової обіцянки. Прохання про заряджання лишається."}]},{"id":"deputy","speaker":"Пан із приймальні","role":"Невідомий номер","avatar":null,"at":930,"until":980,"condition":"always","text":"У нас тут невеличка зустріч. Залишите світло? Я вам ще зателефоную, домовились?","choices":[{"label":"Лише пів години","effect":"debt","detail":"Поділ: обіцянка на 30 хв. О 19:20 попросять ще."},{"label":"Усі за спільним графіком","effect":"ack","detail":"Жодних особистих зобовʼязань."}]},{"id":"rumor","speaker":"Адмін, закріпіть","role":"Чат ОСББ","avatar":"osbb","at":1000,"until":1050,"condition":"dark","text":"Навпроти світиться! У чаті вже три версії. Одна з них — що ви родич голови будинку.","choices":[{"label":"Перевірити повідомлення","effect":"verify","detail":"Відповідь за 15 ігрових хвилин. Чутка не змінює ліміт."},{"label":"Опублікувати фактичний стан","effect":"facts","detail":"Показати стан черг. Довіра трохи зростає."},{"label":"Не беру зобовʼязання","effect":"ack","detail":"Без перевірки. Чат продовжить обговорення."}]},{"id":"journalist","speaker":"Журналістка «Мого Києва»","role":"Запит редакції","avatar":null,"at":970,"until":1190,"condition":"inequality","text":"У вашій домашній черзі суттєво менше темряви, ніж у середнього мешканця. Можете пояснити рішення?","choices":[{"label":"Відкрити журнал перемикань","effect":"disclose","detail":"Прозорий журнал; начальник зміни побачить відповідь."},{"label":"Планую наступну ротацію","effect":"equalize","detail":"Обіцяєш вимкнути домашню чергу протягом 45 хв."},{"label":"Технічна особливість","effect":"technical","detail":"Твердження звірять із журналом. Без прихованої зміни фізики."}]},{"id":"clinic","speaker":"Координаторка допомоги","role":"Важлива розмова · без таймера","avatar":null,"at":1100,"until":1290,"condition":"longDark","serious":true,"text":"У мешканця вдома електрозалежне медичне обладнання. Графік гри не може бути гарантією живлення. Для такої ситуації потрібен особистий план із медичною командою.","choices":[{"label":"Зберегти довідковий блок у звіт","effect":"medical","detail":"Гра на паузі. У звіті буде посилання на офіційні контакти, без ігрової поради щодо лікування."}]},{"id":"school","speaker":"Вчителька","role":"Шкільний чат","avatar":null,"at":600,"until":660,"condition":"school","text":"Контрольну дописали. Двоє учнів просили вимкнути ще на хвилинку. Я сказала: диспетчер сьогодні за освіту.","choices":[{"label":"Передавайте вітання","effect":"ack","detail":"Запис у журналі. Без бонусів."}]},{"id":"workshop","speaker":"Майстер із Лукʼянівки","role":"Майстерня","avatar":null,"at":900,"until":970,"condition":"workshop","text":"Павербанки в роботі. Наші пів години видно у вас на панелі. Я теж хочу додому, тільки спершу це дороблю.","choices":[{"label":"Бачу вашу справу","effect":"ack","detail":"Дедлайн у рядку Лукʼянівки."}]},{"id":"mall","speaker":"Адміністратор ТРЦ","role":"Робоча лінія","avatar":null,"at":1150,"until":1200,"condition":"dark","text":"Вивіску вимкнули, холодильники перевели на резерв. У нас тепер романтичний шопінг. Тільки без шопінгу.","choices":[{"label":"Дякую за координацію","effect":"facts","detail":"Довіра зростає; ліміт незмінний."}]},{"id":"neighbor","speaker":"Сергій, 16-й поверх","role":"Сусідський чат","avatar":null,"at":1220,"until":1260,"condition":"longDark","text":"Підняв сусідці термос. Ліфт почекає, чай — ні. Просто повідомляю: у нас тримаються.","choices":[{"label":"Дякую, Сергію","effect":"ack","detail":"Теплий запис у хроніці."}]},{"id":"chief","speaker":"Начальник зміни","role":"Службова лінія","avatar":null,"at":1200,"until":1290,"condition":"investigation","text":"Запит бачив. Наприкінці покажи журнал і фактичну темряву. Мені потрібні цифри, а не пояснення про особливості.","choices":[{"label":"Журнал відкритий","effect":"disclose","detail":"Відповідь увійде в підсумок розслідування."}]},{"id":"thanks","speaker":"Координатор пункту","role":"Кінець зміни","avatar":null,"at":1320,"until":1390,"condition":"always","text":"Термос у консьєржа. Чашку беріть свою. Це повідомлення без прохання — просто щоб ви знали.","choices":[{"label":"Прийняв. Дякую","effect":"ack","detail":"Зміна добігає кінця."}]},{"id":"metro_morning","speaker":"Диспетчер метро","role":"Ранковий пік","at":455,"until":540,"condition":"always","text":"Платформи вже повні. Можемо збільшити інтервал: збережемо половину потужності, але люди чекатимуть довше.","choices":[{"label":"Тимчасово вимкнути службу","effect":"metroEco","detail":"Служба зупиниться повністю. Поверни живлення, щойно вистачатиме потужності."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"water_pressure","speaker":"Черговий водоканалу","role":"Верхні поверхи","at":610,"until":700,"condition":"always","text":"На верхніх поверхах тиск як настрій у понеділок. Перевірте живлення насосів, будь ласка.","choices":[{"label":"Відновити насоси повністю","effect":"waterFull","detail":"Потрібен вільний запас у мережі."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"tram","speaker":"Водій трамвая","role":"Борщагівка","at":650,"until":740,"condition":"always","text":"Пасажири питають, чи скоро. Кажу: ми не затор, ми тимчасова зупинка з краєвидом. Місту потрібна економія.","choices":[{"label":"Попросити місто відкласти бойлери","effect":"campaign","detail":"−8% побутового попиту на 45 хв; −4 довіри."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"repair_dispatch","speaker":"Майстриня аварійної бригади","role":"Робоча лінія","at":480,"until":620,"condition":"crew","text":"Маємо одну машину й дві пари рук. Оберіть заявку на панелі. Всі адреси одночасно не вміщаються навіть у наш бус.","choices":[{"label":"Відправити на найстаршу заявку","effect":"crewFirst","detail":"30 хв на виконання; нагорода в картці заявки."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"energy_neighbor","speaker":"Сусідня диспетчерська · симуляція","role":"Резерв потужності","at":800,"until":900,"condition":"always","text":"Маємо вікно на 40 МВт. Позичимо на 45 хвилин, потім 90 хвилин повертатимеш по 20 МВт. Рахуємо чесно.","choices":[{"label":"Взяти резерв із поверненням","effect":"loan","detail":"Позика вплине на майбутній ліміт."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"heat_evening","speaker":"Черговий тепломереж","role":"Вечірній пік","at":1030,"until":1100,"condition":"always","text":"Ліміт зараз просяде. Половинна циркуляція збереже частину тепла і звільнить потужність. Повна зупинка гірша для будинків.","choices":[{"label":"Тимчасово вимкнути службу","effect":"heatEco","detail":"Служба зупиниться повністю. Поверни живлення, щойно вистачатиме потужності."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"metro_evening","speaker":"Диспетчер метро","role":"Платформи заповнюються","at":1070,"until":1160,"condition":"always","text":"Якщо зупинимо рух, люди лишаться на станціях. Якщо зменшимо частоту — чекатимуть довше. Остаточний режим за вами.","choices":[{"label":"Тимчасово вимкнути службу","effect":"metroEco","detail":"Служба зупиниться повністю. Поверни живлення, щойно вистачатиме потужності."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"osbb_boilers","speaker":"Голова сусіднього ОСББ","role":"Добровільна економія","at":920,"until":1010,"condition":"always","text":"Можу написати про бойлери. Тільки без трьох знаків оклику: люди вже думають, що це голосове.","choices":[{"label":"Оголосити 45 хв економії","effect":"campaign","detail":"Побутове навантаження −8%; звернення витрачає довіру."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"lift","speaker":"Консьєрж із Позняків","role":"Ліфтовий хол","at":740,"until":825,"condition":"longDark","text":"Ліфт стоїть. Сергій уже доставив три термоси й тепер оголошує себе вертикальною маршруткою. Не забудьте про ротацію.","choices":[{"label":"Зафіксувати й опублікувати стан","effect":"facts","detail":"Прозорість додає довіри. Світло треба повернути вручну."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"coffee","speaker":"Бариста на Золотих воротах","role":"Кавова пауза","at":570,"until":690,"condition":"always","text":"Еспресо не обіцяю, фільтр буде. Кияни дивляться на ручну кавомолку як на інновацію. Як там баланс?","choices":[{"label":"Попросити відкласти зайві прилади","effect":"campaign","detail":"Економія по всьому місту на 45 хв."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"market","speaker":"Продавчиня з Житнього","role":"Холодильні вітрини","at":850,"until":940,"condition":"dark","text":"Все, що можна, зібрали в одну вітрину. Сир із ковбасою тепер сусіди. Нам би чесне вікно, без сюрпризів.","choices":[{"label":"Опублікувати стан черг","effect":"facts","detail":"Без нової обіцянки; +3 довіри."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"library","speaker":"Бібліотекарка","role":"Тиха кімната","at":950,"until":1040,"condition":"always","text":"У читальній залі заряджають телефони. Вперше прошу відвідувачів не тиші, а не вмикати чайник одночасно.","choices":[{"label":"Попросити місто заощадити","effect":"campaign","detail":"Економія −8% на 45 хв, якщо вистачає довіри."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"courier","speaker":"Курʼєр на велосипеді","role":"Паливо в дорозі","at":1120,"until":1230,"condition":"crew","text":"Підʼїзд знайшов. Тепер шукаю підʼїзд до підʼїзду. Бригада вільна? У вас нова заявка.","choices":[{"label":"Відправити бригаду","effect":"crewFirst","detail":"Виконати найстаршу доступну заявку."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"water_return","speaker":"Черговий водоканалу","role":"Повернення тиску","at":1220,"until":1320,"condition":"always","text":"Пік минає. Перевірте, чи не лишили насоси в обмеженні. Вода сама до шістнадцятого поверху не передумає.","choices":[{"label":"Повернути повне живлення насосам","effect":"waterFull","detail":"Спершу потрібна вільна потужність."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"debt_return","speaker":"Сусідня диспетчерська · симуляція","role":"Енергетичний борг","at":1140,"until":1290,"condition":"loan","text":"Наше вечірнє вікно настало. Повернення вже йде через ліміт. Знаємо, невчасно. Саме тому попереджали.","choices":[{"label":"Попросити місто допомогти економією","effect":"campaign","detail":"Зменшення попиту може полегшити повернення."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]},{"id":"roof","speaker":"Мешканець із Виноградаря","role":"Вечірній чат","at":1260,"until":1350,"condition":"always","text":"З даху видно, як світло повертається кварталами. Не всі вікна одразу. Але видно, що хтось працює.","choices":[{"label":"Дякую. Продовжуємо ротацію","effect":"ack","detail":"Особиста репліка без додаткового бонусу."},{"label":"Поки без нового зобовʼязання","effect":"ack","detail":"Продовжити керувати з пульта."}]}],"events":[{"id":"city-1","title":"Чайники прокинулися","sectorId":"troieshchyna","mw":12,"duration":30,"window":0,"at":570,"condition":"on","text":"Чайники прокинулися. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-2","title":"Кавʼярні відкрились","sectorId":"podil","mw":8,"duration":45,"window":0,"at":570,"condition":"on","text":"Кавʼярні відкрились. Тимчасове побутове навантаження: +8 МВт."},{"id":"city-3","title":"Пральні в роботі","sectorId":"borshchahivka","mw":10,"duration":60,"window":0,"at":570,"condition":"on","text":"Пральні в роботі. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-4","title":"Майстерні закінчують день","sectorId":"lukianivka","mw":7,"duration":30,"window":0,"at":570,"condition":"on","text":"Майстерні закінчують день. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-5","title":"Вечеря на плитах","sectorId":"pechersk","mw":12,"duration":45,"window":0,"at":570,"condition":"on","text":"Вечеря на плитах. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-6","title":"Повернення додому","sectorId":"pozniaky","mw":10,"duration":60,"window":1,"at":695,"condition":"on","text":"Повернення додому. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-7","title":"Заряджаються гаджети","sectorId":"obolon","mw":7,"duration":30,"window":1,"at":695,"condition":"on","text":"Заряджаються гаджети. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-8","title":"Вечірні насоси","sectorId":"rusanivka","mw":6,"duration":45,"window":1,"at":695,"condition":"on","text":"Вечірні насоси. Тимчасове побутове навантаження: +6 МВт."},{"id":"city-9","title":"Обігрівачі у квартирах","sectorId":"solomianskyi","mw":9,"duration":60,"window":1,"at":695,"condition":"on","text":"Обігрівачі у квартирах. Тимчасове побутове навантаження: +9 МВт."},{"id":"city-10","title":"Світло у підʼїздах","sectorId":"teremky","mw":5,"duration":30,"window":1,"at":695,"condition":"on","text":"Світло у підʼїздах. Тимчасове побутове навантаження: +5 МВт."},{"id":"city-11","title":"Чайники прокинулися","sectorId":"troieshchyna","mw":12,"duration":45,"window":2,"at":820,"condition":"on","text":"Чайники прокинулися. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-12","title":"Кавʼярні відкрились","sectorId":"podil","mw":8,"duration":60,"window":2,"at":820,"condition":"on","text":"Кавʼярні відкрились. Тимчасове побутове навантаження: +8 МВт."},{"id":"city-13","title":"Пральні в роботі","sectorId":"borshchahivka","mw":10,"duration":30,"window":2,"at":820,"condition":"on","text":"Пральні в роботі. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-14","title":"Майстерні закінчують день","sectorId":"lukianivka","mw":7,"duration":45,"window":2,"at":820,"condition":"on","text":"Майстерні закінчують день. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-15","title":"Вечеря на плитах","sectorId":"pechersk","mw":12,"duration":60,"window":2,"at":820,"condition":"on","text":"Вечеря на плитах. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-16","title":"Повернення додому","sectorId":"pozniaky","mw":10,"duration":30,"window":3,"at":945,"condition":"on","text":"Повернення додому. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-17","title":"Заряджаються гаджети","sectorId":"obolon","mw":7,"duration":45,"window":3,"at":945,"condition":"on","text":"Заряджаються гаджети. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-18","title":"Вечірні насоси","sectorId":"rusanivka","mw":6,"duration":60,"window":3,"at":945,"condition":"on","text":"Вечірні насоси. Тимчасове побутове навантаження: +6 МВт."},{"id":"city-19","title":"Обігрівачі у квартирах","sectorId":"solomianskyi","mw":9,"duration":30,"window":3,"at":945,"condition":"on","text":"Обігрівачі у квартирах. Тимчасове побутове навантаження: +9 МВт."},{"id":"city-20","title":"Світло у підʼїздах","sectorId":"teremky","mw":5,"duration":45,"window":3,"at":945,"condition":"on","text":"Світло у підʼїздах. Тимчасове побутове навантаження: +5 МВт."},{"id":"city-21","title":"Чайники прокинулися","sectorId":"troieshchyna","mw":12,"duration":60,"window":4,"at":1070,"condition":"on","text":"Чайники прокинулися. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-22","title":"Кавʼярні відкрились","sectorId":"podil","mw":8,"duration":30,"window":4,"at":1070,"condition":"on","text":"Кавʼярні відкрились. Тимчасове побутове навантаження: +8 МВт."},{"id":"city-23","title":"Пральні в роботі","sectorId":"borshchahivka","mw":10,"duration":45,"window":4,"at":1070,"condition":"on","text":"Пральні в роботі. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-24","title":"Майстерні закінчують день","sectorId":"lukianivka","mw":7,"duration":60,"window":4,"at":1070,"condition":"on","text":"Майстерні закінчують день. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-25","title":"Вечеря на плитах","sectorId":"pechersk","mw":12,"duration":30,"window":4,"at":1070,"condition":"on","text":"Вечеря на плитах. Тимчасове побутове навантаження: +12 МВт."},{"id":"city-26","title":"Повернення додому","sectorId":"pozniaky","mw":10,"duration":45,"window":5,"at":1195,"condition":"on","text":"Повернення додому. Тимчасове побутове навантаження: +10 МВт."},{"id":"city-27","title":"Заряджаються гаджети","sectorId":"obolon","mw":7,"duration":60,"window":5,"at":1195,"condition":"on","text":"Заряджаються гаджети. Тимчасове побутове навантаження: +7 МВт."},{"id":"city-28","title":"Вечірні насоси","sectorId":"rusanivka","mw":6,"duration":30,"window":5,"at":1195,"condition":"on","text":"Вечірні насоси. Тимчасове побутове навантаження: +6 МВт."},{"id":"city-29","title":"Обігрівачі у квартирах","sectorId":"solomianskyi","mw":9,"duration":45,"window":5,"at":1195,"condition":"on","text":"Обігрівачі у квартирах. Тимчасове побутове навантаження: +9 МВт."},{"id":"city-30","title":"Світло у підʼїздах","sectorId":"teremky","mw":5,"duration":60,"window":5,"at":1195,"condition":"on","text":"Світло у підʼїздах. Тимчасове побутове навантаження: +5 МВт."},{"id":"pulse-0","title":"Двір одночасно гріє воду","sectorId":"troieshchyna","mw":12,"duration":25,"window":0,"at":570,"condition":"on","text":"Двір одночасно гріє воду. Додатково 12 МВт на 25 хв."},{"id":"pulse-1","title":"Пекарні почали другий заміс","sectorId":"pozniaky","mw":16,"duration":35,"window":1,"at":695,"condition":"on","text":"Пекарні почали другий заміс. Додатково 16 МВт на 35 хв."},{"id":"pulse-2","title":"Пральні машини наздоганяють графік","sectorId":"solomianskyi","mw":20,"duration":45,"window":2,"at":820,"condition":"on","text":"Пральні машини наздоганяють графік. Додатково 20 МВт на 45 хв."},{"id":"pulse-3","title":"Коворкінг заряджає батареї","sectorId":"obolon","mw":24,"duration":55,"window":3,"at":945,"condition":"on","text":"Коворкінг заряджає батареї. Додатково 24 МВт на 55 хв."},{"id":"pulse-4","title":"Магазини охолоджують вітрини","sectorId":"podil","mw":28,"duration":25,"window":4,"at":1070,"condition":"on","text":"Магазини охолоджують вітрини. Додатково 28 МВт на 25 хв."},{"id":"pulse-5","title":"Бойлери повернулись після паузи","sectorId":"borshchahivka","mw":12,"duration":35,"window":5,"at":1195,"condition":"on","text":"Бойлери повернулись після паузи. Додатково 12 МВт на 35 хв."},{"id":"pulse-6","title":"Майстерні запустили обладнання","sectorId":"pechersk","mw":16,"duration":45,"window":0,"at":570,"condition":"on","text":"Майстерні запустили обладнання. Додатково 16 МВт на 45 хв."},{"id":"pulse-7","title":"Школа готує гарячий обід","sectorId":"rusanivka","mw":20,"duration":55,"window":1,"at":695,"condition":"on","text":"Школа готує гарячий обід. Додатково 20 МВт на 55 хв."},{"id":"pulse-8","title":"Підʼїзди заряджають ліхтарі","sectorId":"teremky","mw":24,"duration":25,"window":2,"at":820,"condition":"on","text":"Підʼїзди заряджають ліхтарі. Додатково 24 МВт на 25 хв."},{"id":"pulse-9","title":"Ресторан завершує заготовки","sectorId":"lukianivka","mw":28,"duration":35,"window":3,"at":945,"condition":"on","text":"Ресторан завершує заготовки. Додатково 28 МВт на 35 хв."},{"id":"pulse-10","title":"Вечірня хвиля електроплит","sectorId":"troieshchyna","mw":12,"duration":45,"window":4,"at":1070,"condition":"on","text":"Вечірня хвиля електроплит. Додатково 12 МВт на 45 хв."},{"id":"pulse-11","title":"Гуртожиток кипʼятить чайники","sectorId":"pozniaky","mw":16,"duration":55,"window":5,"at":1195,"condition":"on","text":"Гуртожиток кипʼятить чайники. Додатково 16 МВт на 55 хв."},{"id":"pulse-12","title":"Мешканці заряджають ноутбуки","sectorId":"solomianskyi","mw":20,"duration":25,"window":0,"at":570,"condition":"on","text":"Мешканці заряджають ноутбуки. Додатково 20 МВт на 25 хв."},{"id":"pulse-13","title":"Пункт запустив обігрівач","sectorId":"obolon","mw":24,"duration":35,"window":1,"at":695,"condition":"on","text":"Пункт запустив обігрівач. Додатково 24 МВт на 35 хв."},{"id":"pulse-14","title":"Пекарня прогріває другу піч","sectorId":"podil","mw":28,"duration":45,"window":2,"at":820,"condition":"on","text":"Пекарня прогріває другу піч. Додатково 28 МВт на 45 хв."},{"id":"pulse-15","title":"Сусіди підключили сушарки","sectorId":"borshchahivka","mw":12,"duration":55,"window":3,"at":945,"condition":"on","text":"Сусіди підключили сушарки. Додатково 12 МВт на 55 хв."},{"id":"pulse-16","title":"Насоси будинку наздоганяють тиск","sectorId":"pechersk","mw":16,"duration":25,"window":4,"at":1070,"condition":"on","text":"Насоси будинку наздоганяють тиск. Додатково 16 МВт на 25 хв."},{"id":"pulse-17","title":"Майстер заряджає інструмент","sectorId":"rusanivka","mw":20,"duration":35,"window":5,"at":1195,"condition":"on","text":"Майстер заряджає інструмент. Додатково 20 МВт на 35 хв."},{"id":"pulse-18","title":"Холодильники відновлюють температуру","sectorId":"teremky","mw":24,"duration":45,"window":0,"at":570,"condition":"on","text":"Холодильники відновлюють температуру. Додатково 24 МВт на 45 хв."},{"id":"pulse-19","title":"Кавʼярня готує термоси","sectorId":"lukianivka","mw":28,"duration":55,"window":1,"at":695,"condition":"on","text":"Кавʼярня готує термоси. Додатково 28 МВт на 55 хв."},{"id":"pulse-20","title":"Пральня бере нову партію","sectorId":"troieshchyna","mw":12,"duration":25,"window":2,"at":820,"condition":"on","text":"Пральня бере нову партію. Додатково 12 МВт на 25 хв."},{"id":"pulse-21","title":"Швейна майстерня завершує роботу","sectorId":"pozniaky","mw":16,"duration":35,"window":3,"at":945,"condition":"on","text":"Швейна майстерня завершує роботу. Додатково 16 МВт на 35 хв."},{"id":"pulse-22","title":"Кухні готують вечерю","sectorId":"solomianskyi","mw":20,"duration":45,"window":4,"at":1070,"condition":"on","text":"Кухні готують вечерю. Додатково 20 МВт на 45 хв."},{"id":"pulse-23","title":"Гаражі заряджають акумулятори","sectorId":"obolon","mw":24,"duration":55,"window":5,"at":1195,"condition":"on","text":"Гаражі заряджають акумулятори. Додатково 24 МВт на 55 хв."},{"id":"pulse-24","title":"Підʼїзд вмикає освітлення","sectorId":"podil","mw":28,"duration":25,"window":0,"at":570,"condition":"on","text":"Підʼїзд вмикає освітлення. Додатково 28 МВт на 25 хв."},{"id":"pulse-25","title":"Мешканці гріють кімнати","sectorId":"borshchahivka","mw":12,"duration":35,"window":1,"at":695,"condition":"on","text":"Мешканці гріють кімнати. Додатково 12 МВт на 35 хв."},{"id":"pulse-26","title":"Спортзал повертає вентиляцію","sectorId":"pechersk","mw":16,"duration":45,"window":2,"at":820,"condition":"on","text":"Спортзал повертає вентиляцію. Додатково 16 МВт на 45 хв."},{"id":"pulse-27","title":"Пункт заряджає рації","sectorId":"rusanivka","mw":20,"duration":55,"window":3,"at":945,"condition":"on","text":"Пункт заряджає рації. Додатково 20 МВт на 55 хв."},{"id":"pulse-28","title":"Магазин прогріває пекарський цех","sectorId":"teremky","mw":24,"duration":25,"window":4,"at":1070,"condition":"on","text":"Магазин прогріває пекарський цех. Додатково 24 МВт на 25 хв."},{"id":"pulse-29","title":"Останній цикл посудомийок","sectorId":"lukianivka","mw":28,"duration":35,"window":5,"at":1195,"condition":"on","text":"Останній цикл посудомийок. Додатково 28 МВт на 35 хв."}],"chat":[{"id":"ambient-0","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Шановні сусіди, графік закріплено. Фото котів — після графіка.","cooldown":45,"oncePerRun":true},{"id":"ambient-1","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"ambient","text":"Хто залишив каштани біля щитової?","cooldown":45,"oncePerRun":true},{"id":"ambient-2","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Це декор. Але доступ до щитової залиште.","cooldown":45,"oncePerRun":true,"requires":"ambient-1"},{"id":"ambient-3","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"ambient","text":"Повідомлення «а коли?» не прискорює час.","cooldown":45,"oncePerRun":true},{"id":"ambient-4","speaker":"Лівий берег","avatar":"neighbor","trigger":"ambient","text":"Лівий берег на звʼязку. Перекличка без географічних суперечок.","cooldown":45,"oncePerRun":true},{"id":"ambient-5","speaker":"Кава на розі","avatar":"cafe","trigger":"ambient","text":"Фільтр є. Новини сьогодні без цукру.","cooldown":45,"oncePerRun":true},{"id":"ambient-6","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"ambient","text":"Хтось бачив мій подовжувач? Довгий. Характер складний.","cooldown":45,"oncePerRun":true},{"id":"ambient-7","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"ambient","text":"Пароль від вайфаю на дверях. Пароля від дверей немає.","cooldown":45,"oncePerRun":true},{"id":"ambient-8","speaker":"Сусідка","avatar":"neighbor","trigger":"ambient","text":"Термос — це коли плануєш на крок уперед.","cooldown":45,"oncePerRun":true},{"id":"ambient-9","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Людмило Петрівно, ви знову не туди пишете. Ой. Це я.","cooldown":45,"oncePerRun":true},{"id":"ambient-10","speaker":"Лівий берег","avatar":"neighbor","trigger":"ambient","text":"До правого сьогодні швидше повідомленням.","cooldown":45,"oncePerRun":true},{"id":"ambient-11","speaker":"Кава на розі","avatar":"cafe","trigger":"ambient","text":"Розетка не бронюється серветкою.","cooldown":45,"oncePerRun":true},{"id":"ambient-12","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"ambient","text":"У цьому чаті навіть мовчання надсилають голосовим.","cooldown":45,"oncePerRun":true},{"id":"ambient-13","speaker":"Сусідка","avatar":"neighbor","trigger":"ambient","text":"Купила свічку для затишку. Затишок тепер за розкладом.","cooldown":45,"oncePerRun":true},{"id":"ambient-14","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"ambient","text":"Домовий чат сьогодні працює потужніше за підстанцію.","cooldown":45,"oncePerRun":true},{"id":"ambient-15","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Генератор у чаті не продаємо. Спочатку скажіть, чий він.","cooldown":45,"oncePerRun":true},{"id":"ambient-16","speaker":"Лівий берег","avatar":"neighbor","trigger":"ambient","text":"На Позняках вітер без графіка. Стабільність.","cooldown":45,"oncePerRun":true},{"id":"ambient-17","speaker":"Кава на розі","avatar":"cafe","trigger":"ambient","text":"Молоко є, терпіння закінчується о девʼятій.","cooldown":45,"oncePerRun":true},{"id":"ambient-18","speaker":"Сусідка","avatar":"neighbor","trigger":"ambient","text":"Зустріла сусідів на сходах. Виявляється, у них є імена.","cooldown":45,"oncePerRun":true},{"id":"ambient-19","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"ambient","text":"Двадцять сім непрочитаних. Одне з них по суті.","cooldown":45,"oncePerRun":true},{"id":"ambient-20","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Поставте плюс, хто прочитав. Мінус теж вважається.","cooldown":45,"oncePerRun":true},{"id":"ambient-21","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"ambient","text":"Хто паркується на газоні? Це питання працює і без світла.","cooldown":45,"oncePerRun":true},{"id":"ambient-22","speaker":"Кава на розі","avatar":"cafe","trigger":"ambient","text":"У нас можна просто посидіти. Не все сьогодні за гроші.","cooldown":45,"oncePerRun":true},{"id":"ambient-23","speaker":"Сусідка","avatar":"neighbor","trigger":"ambient","text":"Павербанк заряджений. Я — не дуже.","cooldown":45,"oncePerRun":true},{"id":"ambient-24","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"ambient","text":"Графік не гороскоп. Але читають однаково уважно.","cooldown":45,"oncePerRun":true},{"id":"dark-0","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"dark","text":"Ліфт теж вирішив побути на паузі.","cooldown":45,"oncePerRun":true},{"id":"dark-1","speaker":"Кава на розі","avatar":"cafe","trigger":"dark","text":"Світла немає. Термос поки тримає обороти.","cooldown":45,"oncePerRun":true},{"id":"dark-2","speaker":"Пані Людмила","avatar":"osbb","trigger":"dark","text":"У нашій черзі темно. На панелі це теж видно.","cooldown":45,"oncePerRun":true},{"id":"dark-3","speaker":"Сусідка","avatar":"neighbor","trigger":"dark","text":"Холодильник відкриваємо з метою, а не від нудьги.","cooldown":45,"oncePerRun":true},{"id":"dark-4","speaker":"Лівий берег","avatar":"neighbor","trigger":"dark","text":"Вікна темні, чат яскравий.","cooldown":45,"oncePerRun":true},{"id":"dark-5","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"dark","text":"Перевіряйте стан своєї черги. Фото сусіднього вікна — не графік.","cooldown":45,"oncePerRun":true},{"id":"dark-6","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"dark","text":"Сходи сьогодні зарахую як спортзал.","cooldown":45,"oncePerRun":true},{"id":"dark-7","speaker":"Кава на розі","avatar":"cafe","trigger":"dark","text":"Кавомолка відпочиває. Бариста пояснює різницю між чаєм і еспресо.","cooldown":45,"oncePerRun":true},{"id":"dark-8","speaker":"Сусідка","avatar":"neighbor","trigger":"dark","text":"Знайшла ліхтарик. Тепер шукаю, куди поклала окуляри.","cooldown":45,"oncePerRun":true},{"id":"dark-9","speaker":"Пані Людмила","avatar":"osbb","trigger":"dark","text":"Один термос у консьєржа. Чашку беріть свою.","cooldown":45,"oncePerRun":true},{"id":"lit-0","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"lit","text":"Світло є. Поставив чайник. Не наврочте.","cooldown":45,"oncePerRun":true},{"id":"lit-1","speaker":"Кава на розі","avatar":"cafe","trigger":"lit","text":"Машина прогрілась. Черга на розетку вже довша.","cooldown":45,"oncePerRun":true},{"id":"lit-2","speaker":"Пані Людмила","avatar":"osbb","trigger":"lit","text":"Заряджайте потрібне, поки є вікно.","cooldown":45,"oncePerRun":true},{"id":"lit-3","speaker":"Сусідка","avatar":"neighbor","trigger":"lit","text":"Пральна машина згадала, на чому зупинилась.","cooldown":45,"oncePerRun":true},{"id":"lit-4","speaker":"Лівий берег","avatar":"neighbor","trigger":"lit","text":"Лівий берег світиться. Правому теж бажаємо.","cooldown":45,"oncePerRun":true},{"id":"lit-5","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"lit","text":"Світло повернулось. Повідомлень стало ще більше.","cooldown":45,"oncePerRun":true},{"id":"lit-6","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"lit","text":"Чай є. Тепер можна обговорювати графік.","cooldown":45,"oncePerRun":true},{"id":"lit-7","speaker":"Кава на розі","avatar":"cafe","trigger":"lit","text":"Фільтр готовий. Кришечки знову не ті.","cooldown":45,"oncePerRun":true},{"id":"lit-8","speaker":"Пані Людмила","avatar":"osbb","trigger":"lit","text":"Подовжувачі забрати після заряджання. Підписані теж.","cooldown":45,"oncePerRun":true},{"id":"lit-9","speaker":"Сусідка","avatar":"neighbor","trigger":"lit","text":"Встигла подзвонити мамі. Вона спитала, чи я їла.","cooldown":45,"oncePerRun":true},{"id":"warm-0","speaker":"Сусідка","avatar":"neighbor","trigger":"warm","text":"Занесли сусідці гарячий чай. Вона передає всім привіт.","cooldown":45,"oncePerRun":true},{"id":"warm-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"warm","text":"Сьогодні посварились менше. Теж результат.","cooldown":45,"oncePerRun":true},{"id":"warm-2","speaker":"Кава на розі","avatar":"cafe","trigger":"warm","text":"Останній чай — за рахунок закладу.","cooldown":45,"oncePerRun":true},{"id":"warm-3","speaker":"Лівий берег","avatar":"neighbor","trigger":"warm","text":"До зустрічі завтра. Тут, у чаті.","cooldown":45,"oncePerRun":true},{"id":"warm-4","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"warm","text":"Закріплю подяку. Графік зачекає.","cooldown":45,"oncePerRun":true},{"id":"warm-5","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"warm","text":"Подовжувач знайшовся. Він був потрібніший сусідам.","cooldown":45,"oncePerRun":true},{"id":"warm-6","speaker":"Пані Людмила","avatar":"osbb","trigger":"warm","text":"Хто приніс печиво — дякуємо. Баночку повернемо.","cooldown":45,"oncePerRun":true},{"id":"warm-7","speaker":"Сусідка","avatar":"neighbor","trigger":"warm","text":"Вікна засвітились. Як маленькі «я вдома».","cooldown":45,"oncePerRun":true},{"id":"warm-8","speaker":"Кава на розі","avatar":"cafe","trigger":"warm","text":"Бариста теж людина. Йде заряджатись додому.","cooldown":45,"oncePerRun":true},{"id":"warm-9","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"warm","text":"Зміну закриваємо без голосування у чаті.","cooldown":45,"oncePerRun":true},{"id":"promise-0","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"promise","text":"Адмін, закріпіть графік.","cooldown":45,"oncePerRun":true},{"id":"promise-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"promise","text":"Вечірнє вікно побачила. Людям передала.","cooldown":45,"oncePerRun":true},{"id":"promise-2","speaker":"Сусідка","avatar":"neighbor","trigger":"promise","text":"Планувати вечір уже трохи легше.","cooldown":45,"oncePerRun":true},{"id":"promise-3","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"promise","text":"Будильник на початок вікна поставив.","cooldown":45,"oncePerRun":true},{"id":"promise-4","speaker":"Кава на розі","avatar":"cafe","trigger":"promise","text":"Кавоварка про обіцянку ще не знає. Зараз пояснимо.","cooldown":45,"oncePerRun":true},{"id":"broken-0","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"broken","text":"Адмін, відкріпіть графік.","cooldown":45,"oncePerRun":true},{"id":"broken-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"broken","text":"Обіцяне вікно не витримали. Люди вже прийшли.","cooldown":45,"oncePerRun":true},{"id":"broken-2","speaker":"Сусідка","avatar":"neighbor","trigger":"broken","text":"Переплановуємо вечір. Знову.","cooldown":45,"oncePerRun":true},{"id":"broken-3","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"broken","text":"Будильник спрацював. Графік — ні.","cooldown":45,"oncePerRun":true},{"id":"broken-4","speaker":"Кава на розі","avatar":"cafe","trigger":"broken","text":"Бронювання розетки переносимо разом із графіком.","cooldown":45,"oncePerRun":true},{"id":"support-0","speaker":"Пані Людмила","avatar":"osbb","trigger":"support","text":"Пункт відкрили. Подовжувач розклала.","cooldown":45,"oncePerRun":true},{"id":"support-1","speaker":"Сусідка","avatar":"neighbor","trigger":"support","text":"Пароль від вайфаю який?","cooldown":45,"oncePerRun":true},{"id":"support-2","speaker":"Адмін, закріпіть","avatar":"admin","trigger":"support","text":"На дверях. Так, на тих самих.","cooldown":45,"oncePerRun":true,"requires":"support-1"},{"id":"support-3","speaker":"Сергій · 16-й","avatar":"neighbor","trigger":"support","text":"Зарядився сам і допоміг сусіду.","cooldown":45,"oncePerRun":true},{"id":"support-4","speaker":"Кава на розі","avatar":"cafe","trigger":"support","text":"Термос для пункту вже несуть.","cooldown":45,"oncePerRun":true},{"id":"new-ambient-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"ambient","text":"На Шулявці навіть чайник питає, куди тут повертати.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Оголошення: подовжувач не є частиною квартири. Поверніть.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-2","speaker":"Лівий берег","avatar":null,"trigger":"ambient","text":"Хто підписав павербанк «борщ»? Питаю для порядку.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-3","speaker":"Сусідка","avatar":null,"trigger":"ambient","text":"На Подолі домовились зустрітися біля світлого вікна. Орієнтир рухається.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"ambient","text":"Зараз би на фунікулер. Але можна просто постояти під нахилом.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-5","speaker":"Кава на розі","avatar":null,"trigger":"ambient","text":"Сусіди, чат не споживає нашу чергу. Можете не економити літери.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-6","speaker":"Сергій · 16-й","avatar":null,"trigger":"ambient","text":"Кіт сів на графік. Вважаємо це погодженням.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-7","speaker":"Пані Людмила","avatar":"osbb","trigger":"ambient","text":"Батарейки знайшлись. Тепер шукаємо пристрій, якому вони підходять.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-8","speaker":"Лівий берег","avatar":null,"trigger":"ambient","text":"Хто забрав термос із написом «не брати»? Це була інструкція.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-9","speaker":"Сусідка","avatar":null,"trigger":"ambient","text":"На Позняках вітер заряджає тільки характер.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-10","speaker":"Адмін, закріпіть","avatar":null,"trigger":"ambient","text":"Лівий берег передає правому: ми тут. Як завжди, через міст.","cooldown":22,"oncePerRun":true},{"id":"new-ambient-11","speaker":"Кава на розі","avatar":null,"trigger":"ambient","text":"Нова одиниця часу: поки закипить чужий чайник.","cooldown":22,"oncePerRun":true},{"id":"new-dark-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"dark","text":"Пральна машина зупинилась на драматичній паузі.","cooldown":22,"oncePerRun":true},{"id":"new-dark-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"dark","text":"Шукаю ліхтарик при світлі іншого ліхтарика. Київський квест.","cooldown":22,"oncePerRun":true},{"id":"new-dark-2","speaker":"Лівий берег","avatar":null,"trigger":"dark","text":"Сходи сьогодні безкоштовний фітнес. Абонемент продовжено.","cooldown":22,"oncePerRun":true},{"id":"new-dark-3","speaker":"Сусідка","avatar":null,"trigger":"dark","text":"Чай у термосі ще теплий. Сусідська дипломатія працює.","cooldown":22,"oncePerRun":true},{"id":"new-dark-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"dark","text":"На кухні тихо. Навіть холодильник задумався.","cooldown":22,"oncePerRun":true},{"id":"new-dark-5","speaker":"Кава на розі","avatar":null,"trigger":"dark","text":"У домі темно, але в когось усе одно працює дриль. Як?","cooldown":22,"oncePerRun":true},{"id":"new-dark-6","speaker":"Сергій · 16-й","avatar":null,"trigger":"dark","text":"Павербанк показує одну риску. Я йому морально допомагаю.","cooldown":22,"oncePerRun":true},{"id":"new-dark-7","speaker":"Пані Людмила","avatar":"osbb","trigger":"dark","text":"Вікно потрібне не для краси. Там у людей вечеря.","cooldown":22,"oncePerRun":true},{"id":"new-lit-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"lit","text":"Є! Чайник пішов на старт. Стримую пральну машину.","cooldown":22,"oncePerRun":true},{"id":"new-lit-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"lit","text":"Світло дали. Не всі прилади разом, сусіди.","cooldown":22,"oncePerRun":true},{"id":"new-lit-2","speaker":"Лівий берег","avatar":null,"trigger":"lit","text":"Холодильник загудів як старий знайомий.","cooldown":22,"oncePerRun":true},{"id":"new-lit-3","speaker":"Сусідка","avatar":null,"trigger":"lit","text":"Заряджаю ноутбук і віру в графік.","cooldown":22,"oncePerRun":true},{"id":"new-lit-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"lit","text":"Повернули світло. Кіт робить вигляд, що це він.","cooldown":22,"oncePerRun":true},{"id":"new-lit-5","speaker":"Кава на розі","avatar":null,"trigger":"lit","text":"Пральна машина продовжила монолог.","cooldown":22,"oncePerRun":true},{"id":"new-lit-6","speaker":"Сергій · 16-й","avatar":null,"trigger":"lit","text":"Тісто дочекалося. Пекар не спав.","cooldown":22,"oncePerRun":true},{"id":"new-lit-7","speaker":"Пані Людмила","avatar":"osbb","trigger":"lit","text":"Вікна засвітилися. Підʼїзд одразу став домашнім.","cooldown":22,"oncePerRun":true},{"id":"new-metro-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"metro","text":"Метро рідше. На платформі вже клуб за інтересами.","cooldown":22,"oncePerRun":true},{"id":"new-metro-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"metro","text":"Диспетчере, про метро не забудьте. Ми додому теж хочемо.","cooldown":22,"oncePerRun":true},{"id":"new-metro-2","speaker":"Лівий берег","avatar":null,"trigger":"metro","text":"На пересадці стоїмо. Ліхтарі є, поїзд чекаємо.","cooldown":22,"oncePerRun":true},{"id":"new-metro-3","speaker":"Сусідка","avatar":null,"trigger":"metro","text":"Домовились зустрітись за два поїзди. Тепер це філософія.","cooldown":22,"oncePerRun":true},{"id":"new-metro-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"metro","text":"Ескалатор гуде, люди мовчки дивляться на табло.","cooldown":22,"oncePerRun":true},{"id":"new-metro-5","speaker":"Кава на розі","avatar":null,"trigger":"metro","text":"Пішки через міст? Спочатку дайте допити чай.","cooldown":22,"oncePerRun":true},{"id":"new-water-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"water","text":"На шістнадцятому вода знову стала чуткою.","cooldown":22,"oncePerRun":true},{"id":"new-water-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"water","text":"Насоси поверніть, будь ласка. Каструля сама не наповниться.","cooldown":22,"oncePerRun":true},{"id":"new-water-2","speaker":"Лівий берег","avatar":null,"trigger":"water","text":"Тиск слабкий. Сусіди діляться запасом.","cooldown":22,"oncePerRun":true},{"id":"new-water-3","speaker":"Сусідка","avatar":null,"trigger":"water","text":"Термос універсальний, але душ ним не заміниш.","cooldown":22,"oncePerRun":true},{"id":"new-water-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"water","text":"Нижні поверхи передають верхнім воду. Вертикальна солідарність.","cooldown":22,"oncePerRun":true},{"id":"new-water-5","speaker":"Кава на розі","avatar":null,"trigger":"water","text":"Чекаємо воду. Кран уже перевірили, дякуємо.","cooldown":22,"oncePerRun":true},{"id":"new-heat-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"heat","text":"Батареї вистигають. Котів до опалення не підключати.","cooldown":22,"oncePerRun":true},{"id":"new-heat-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"heat","text":"Светр номер два. На третій дуже не хочеться переходити.","cooldown":22,"oncePerRun":true},{"id":"new-heat-2","speaker":"Лівий берег","avatar":null,"trigger":"heat","text":"Вікна зачинили. Тепло тепер бережемо всім підʼїздом.","cooldown":22,"oncePerRun":true},{"id":"new-heat-3","speaker":"Сусідка","avatar":null,"trigger":"heat","text":"Тепломережі, ми вас памʼятаємо. Повертайтесь.","cooldown":22,"oncePerRun":true},{"id":"new-heat-4","speaker":"Адмін, закріпіть","avatar":null,"trigger":"heat","text":"Чай не заміняє батареї, але підтримує переговори.","cooldown":22,"oncePerRun":true},{"id":"new-heat-5","speaker":"Кава на розі","avatar":null,"trigger":"heat","text":"Плед у кожного свій. Тепло в домі — спільне.","cooldown":22,"oncePerRun":true},{"id":"new-crew-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"crew","text":"Бус бригади біля будинку. Не перекривайте виїзд.","cooldown":22,"oncePerRun":true},{"id":"new-crew-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"crew","text":"Майстрам передали каву. Без черги.","cooldown":22,"oncePerRun":true},{"id":"new-crew-2","speaker":"Лівий берег","avatar":null,"trigger":"crew","text":"Дайте бригаді попрацювати. Порад у чаті вже вистачає.","cooldown":22,"oncePerRun":true},{"id":"new-crew-3","speaker":"Сусідка","avatar":null,"trigger":"crew","text":"Заявку закрили. Фото кота на честь події дозволено.","cooldown":22,"oncePerRun":true},{"id":"new-loan-0","speaker":"Сергій · 16-й","avatar":null,"trigger":"loan","text":"Енергію позичили. Головне — не як мій сусід драбину.","cooldown":22,"oncePerRun":true},{"id":"new-loan-1","speaker":"Пані Людмила","avatar":"osbb","trigger":"loan","text":"Зараз запас, потім повернення. Записав собі в графік.","cooldown":22,"oncePerRun":true},{"id":"new-loan-2","speaker":"Лівий берег","avatar":null,"trigger":"loan","text":"Резерв виручив. Борг теж прийде за розкладом.","cooldown":22,"oncePerRun":true},{"id":"new-loan-3","speaker":"Сусідка","avatar":null,"trigger":"loan","text":"Електрична взаємодопомога. Подовжувач до сусіднього міста не потрібен.","cooldown":22,"oncePerRun":true}]},assets:{"baker":"https://my-kiev.com/wp-content/uploads/2026/09/blekaut-v2-baker.webp","osbb":"https://my-kiev.com/wp-content/uploads/2026/09/blekaut-v2-osbb.webp","mother":"https://my-kiev.com/wp-content/uploads/2026/09/blekaut-v2-mother.webp"}};
/* _core/rng.js */
(function (root) {
'use strict';
const C = root.GameCore || (root.GameCore = {});
// Детермінована випадковість. У моделі не має бути жодного Math.random():
// без відтворюваності неможливий ані тюнінг, ані спільна «зміна дня».
function mulberry32(seed) {
let a = seed | 0;
return function () {
a = (a + 0x6D2B79F5) | 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
function pad2(n) {
return (n < 10 ? '0' : '') + n;
}
// Локальна календарна дата гравця: доба міняється опівночі за його годинником.
function todayKey(date) {
const d = date instanceof Date ? date : new Date();
return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate());
}
// Сид доби — хеш ключа дати. Однаковий у всіх, у кого сьогодні той самий день.
function dailySeed(date) {
const key = typeof date === 'string' ? date : todayKey(date);
let h = 2166136261;
for (let i = 0; i < key.length; i += 1) {
h ^= key.charCodeAt(i);
h = Math.imul(h, 16777619);
}
return (h >>> 0);
}
function kyivDay(date) {
const parts = new Intl.DateTimeFormat('en-CA', {timeZone: 'Europe/Kyiv', year: 'numeric', month: '2-digit', day: '2-digit'}).formatToParts(date || new Date());
return ['year', 'month', 'day'].map(function (k) { return parts.find(function (p) { return p.type === k; }).value; }).join('-');
}
C.rng = {
kyivDay: kyivDay,
mulberry32: mulberry32,
dailySeed: dailySeed,
todayKey: todayKey
};
})(typeof globalThis !== 'undefined' ? globalThis : this);
/* _core/store.js */
(function (root) {
'use strict';
const C = root.GameCore || (root.GameCore = {});
C.createStore = function (key, defaults, normalize) {
const clone = function (x) { return JSON.parse(JSON.stringify(x)); };
let memory = null;
function storage() { try { return root.localStorage || null; } catch (e) { return null; } }
function available() {
try { const s = storage(); if (!s) return false; s.setItem(key + '-probe', '1'); s.removeItem(key + '-probe'); return true; } catch (e) { return false; }
}
function load() {
if (!available()) return memory === null ? defaults() : clone(memory);
try {
const raw = storage().getItem(key);
if (!raw) return defaults();
const parsed = JSON.parse(raw);
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return defaults();
return normalize ? normalize(parsed) : parsed;
} catch (e) { return defaults(); }
}
function save(value) {
memory = clone(value);
try { const s = storage(); if (s) s.setItem(key, JSON.stringify(value)); } catch (e) { /* tab memory remains available */ }
return value;
}
return {load: load, save: save, available: available, patch: function (x) { return save(Object.assign(load(), x)); }};
};
})(globalThis);
/* _core/dom.js */
(function (root) {
'use strict';
const C = root.GameCore || (root.GameCore = {});
// Дрібний спільний хелпер для ui/*. Власний модуль, а не побічний продукт
// схеми: інакше ui/hud мовчки залежав би від того, що ui/schema завантажився
// раніше, і порядок тримав би тільки список ORDER у build.py.
function el(tag, cls, text) {
const node = document.createElement(tag);
if (cls) node.className = cls;
if (text !== undefined && text !== null) node.textContent = String(text);
return node;
}
// Форматування числа й хвилини доби живе тут із тієї самої причини, з якої
// тут живе el(): його однаково потребують і звіт, і шер-картка. Якби воно
// лишалось у ui/report, ui/share залежав би від ui/report і від порядку
// склейки - рівно та форма, заради якої цей модуль і заводили.
//
// Число: нерозривний пробіл у розрядах і кома в дробовій частині. Картку
// людина кладе поруч зі звітом і звіряє очима, тому правило одне на обидва.
function num(value, digits) {
const v = Number(value);
if (!isFinite(v)) return String.fromCharCode(0x2014);
const d = digits === undefined ? 0 : digits;
const parts = Math.abs(v).toFixed(d).split('.');
parts[0] = parts[0].split('').map(function (ch, i, a) { return ch + (i < a.length - 1 && (a.length - i - 1) % 3 === 0 ? String.fromCharCode(0x00A0) : ''); }).join('');
const body = parts.length > 1 ? parts[0] + ',' + parts[1] : parts[0];
return (v < 0 ? '-' : '') + body;
}
function minutes(value) {
return num(value, 1) + ' хв';
}
// Хвилина доби -> ГГ:ХХ. Модель тримає свою копію всередині себе; сюди
// ходять тільки ui/*.
function clock(minute) {
const m = Math.max(0, Math.round(Number(minute) || 0));
const h = Math.floor(m / 60) % 24;
const mm = m % 60;
return (h < 10 ? '0' : '') + h + ':' + (mm < 10 ? '0' : '') + mm;
}
C.dom = { el: el, num: num, minutes: minutes, clock: clock };
})(typeof globalThis !== 'undefined' ? globalThis : this);
/* core/core.js */
if(typeof module!=='undefined'&&module.exports){require('../../../_core/rng.js');require('../../../_core/store.js');}
(function(B){
'use strict';
B.VERSION='1.4.0';
B.clamp=(n,a,b)=>Math.min(b,Math.max(a,n));
B.clone=x=>JSON.parse(JSON.stringify(x));
B.hash=text=>globalThis.GameCore.rng.dailySeed(String(text));
B.random=globalThis.GameCore.rng.mulberry32;
B.today=globalThis.GameCore.rng.kyivDay;
B.clock=function(n){const t=Math.floor(n+.00001);return String(Math.floor(t/60)).padStart(2,'0')+':'+String(t%60).padStart(2,'0');};
B.duration=function(n){const m=Math.max(0,Math.round(n));return m>=60?Math.floor(m/60)+' год '+m%60+' хв':m+' хв';};
const storage=globalThis.GameCore.createStore('bd-blekaut-v2'+(typeof location!=='undefined'&&new URLSearchParams(location.search).has('qa')?'-qa':''),()=>({}));
B.store=Object.assign(storage,{record:function(result){const x=storage.load();const k=result.key;const best=x.bestByKey||{};if(!best[k]||best[k].score<result.score)best[k]={score:result.score,date:result.date};const keys=Object.keys(best);if(keys.length>40)delete best[keys[0]];return storage.save(Object.assign(x,{last:result,bestByKey:best,checkpoint:null,shifts:(Number(x.shifts)||0)+1}));}});
})(globalThis.BD=globalThis.BD||{});
/* sim/params.js */
(function(B){
'use strict';
B.P={start:360,end:1440,step:.25,minutesPerSecond:1.5,protectedMw:65,grace:18,openingGrace:12,openingUntil:400,restoreGrace:22,supportMw:3,maxSupport:3,blockSoft:120,blockPenalty:.004,fuelRefill:1.4,promiseFloor:.80,promiseTolerance:8,notice:45,maxPromises:2,callSeconds:15,maxCalls:14,callGap:38,eventQuota:6,saifiFree:7,saifiBudget:12,darkBudget:170,emergencyBudget:85,emergencyCost:14,giniMid:.25,giniWidth:.075,rankAt:[20,40,60,78]};
B.ranks=['Зміна з характером','Пульт уже знайомий','Місто тримається','Майстер рівноваги','Той, кого місто не помітило'];
})(globalThis.BD=globalThis.BD||{});
/* sim/demand.js */
(function(B){
'use strict';
const bell=(t,c,w)=>Math.exp(-Math.pow((t-c)/w,2)/2);
B.demand={
curve:t=>.66+.16*bell(t,510,90)+.11*bell(t,780,190)+.38*bell(t,1170,110),
weight:t=>t>=1080&&t<1260?1.65:t>=1020&&t<1320?1.2:t<480?.6:.9,
limit:function(t,frost,emergency){let n=t<400?410:t<430?410+(t-400)*5:t<700?560:t<730?560-(t-700)*4:t<900?440:t<1060?470:490;if(t>=1320)n=560;if(emergency!==false&&t>=1060&&t<1170)n-=t<1090?290:290*(1170-t)/80;return n-frost*25;},
load:(sector,t,frost)=>sector.baseMw*B.demand.curve(t)*(1+frost*.10)
};
})(globalThis.BD=globalThis.BD||{});
/* sim/operations.js */
(function(B){
'use strict';
const definitions=[
{id:'metro',name:'Метро',symbol:'M',mw:65,peakMw:105,detail:'Рідші поїзди або зупинка руху. На платформах накопичуються пасажири.'},
{id:'water',name:'Водопостачання',symbol:'≈',mw:45,peakMw:55,detail:'Нижчий тиск або зупинка насосів. Верхні поверхи втрачають воду.'},
{id:'heat',name:'Теплопостачання',symbol:'≋',mw:40,peakMw:50,detail:'Менша циркуляція або зупинка. Будинки поступово холонуть.'}
];
const incidents=[
['Контакт на підстанції','Бригада підтягне зʼєднання. Поверне 45 МВт на 90 хв.','repair'],
['Генератор на останній каністрі','Доставити паливо: +90 хв усім допоміжним резервам.','fuel'],
['Кабель під мокрим снігом','Перевести лінію на обхід: +45 МВт на 90 хв.','repair'],
['Пункт просить подовжувачі','Доставити комплект і термоси: +8 довіри.','care'],
['Перекидний рубильник заїдає','Полагодити резервний ввід: +45 МВт на 90 хв.','repair'],
['Насоси потребують огляду','Бригада відновить місцевий резерв: +90 хв усім резервам.','fuel'],
['Розетка для цілого підʼїзду','Організувати чергу заряджання: +8 довіри.','care'],
['Лід на резервній лінії','Огляд і перемикання: +45 МВт на 90 хв.','repair'],
['Павербанки для консьєржів','Розвезти запас: +8 довіри.','care'],
['Паливо затрималось у дворі','Знайти заїзд для доставки: +90 хв усім резервам.','fuel'],
['Нагрівається силова шафа','Відновити охолодження: +45 МВт на 90 хв.','repair'],
['Сусіди відкрили теплу кімнату','Допомогти облаштувати простір: +8 довіри.','care']
];
function peak(t){return (t>=480&&t<600)||(t>=1020&&t<1260);}
function init(s){const rng=B.random(s.seed+90210);s.ops={services:definitions.map(x=>({...x,mode:1,changed:0,impact:0})),jobs:[],boostUntil:0,crew:null,loans:[],campaignUntil:0,campaignReady:0,crisisAnnounced:false};const choices=incidents.map(x=>({x,r:rng()})).sort((a,b)=>a.r-b.r).map(item=>item.x);for(let i=0;i<6;i++){const x=choices[i];s.ops.jobs.push({id:'job-'+i,title:x[0],detail:x[1],reward:x[2],at:450+i*145+Math.floor(rng()*15),deadline:560+i*145,state:'pending',ends:0});}}
function usage(service,t){return (peak(t)?service.peakMw:service.mw)*service.mode;}
function load(s,t){return s.ops.services.reduce((n,x)=>n+usage(x,t),0);}
function adjustment(s,t){const o=s.ops;let n=t<o.boostUntil?45:0;for(const l of o.loans){if(t>=l.at&&t<l.until)n+=40;else if(t>=l.until&&t<l.paidAt)n-=20;}return n;}
function demandFactor(s,t){return t<s.ops.campaignUntil?.92:1;}
function dispatch(sim,a){const s=sim.state(),o=s.ops,t=s.minute;const fail=reason=>({ok:false,reason});
if(a.type==='service'){
const x=o.services.find(x=>x.id===a.id);if(!x||![0,1].includes(a.mode))return fail('Невідомий режим служби.');
if(x.mode===a.mode)return fail('Цей режим уже працює.');
if(t-x.changed<10)return fail('Перемикання ще виконується. Зачекай '+Math.ceil(10-t+x.changed)+' хв зміни.');
const need=(peak(t)?x.peakMw:x.mw)*(a.mode-x.mode);if(need>0&&need>sim.balance(t).room+1)return fail('Для відновлення звільни '+Math.ceil(need-sim.balance(t).room)+' МВт.');
x.mode=a.mode;x.changed=t;s.trust=B.clamp(s.trust-(a.mode===0?4:a.mode===.5?1:0),0,100);sim.log('service',x.name+': '+(a.mode===1?'повне живлення':a.mode===.5?'ощадний режим':'зупинено')+'.');sim.say(x.name,a.mode===0?(x.id==='metro'?'Рух призупинено. Пасажири чекають на станціях. Віднови живлення, щойно зможеш.':x.id==='water'?'Насоси зупинено. Сусіди на верхніх поверхах чекають воду.':'Циркуляцію зупинено. Будинки починають втрачати тепло.'):a.mode===.5?'Працюємо ощадно. Потужності менше, послуга повільніша.':'Повне живлення повернулось. Надолужуємо.');return {ok:true};
}
if(a.type==='crew'){
const j=o.jobs.find(x=>x.id===a.id&&x.state==='open');if(!j)return fail('Заявка вже недоступна.');if(o.crew)return fail('Бригада зайнята. Дочекайся завершення роботи.');if(t+30>j.deadline)return fail('До дедлайну вже не встигнути.');j.state='working';j.ends=t+30;o.crew=j.id;sim.log('crew','Бригада вирушила: '+j.title+'. 30 хв у дорозі та на роботі.');return {ok:true};
}
if(a.type==='loan'){
if(o.loans.some(l=>t<l.paidAt))return fail('Спочатку поверни поточну позику.');if(o.loans.length>=2)return fail('Дві поставки на зміну вже використано.');if(t<600||t>1260)return fail('Резерв доступний з 10:00 до 21:00.');
o.loans.push({at:t,until:t+45,paidAt:t+135,announced:false,settled:false});sim.log('loan','Сусідня диспетчерська (симуляція): +40 МВт на 45 хв; далі повернення 20 МВт протягом 90 хв.');return {ok:true};
}
if(a.type==='campaign'){
if(t<o.campaignReady)return fail('Наступне звернення о '+B.clock(o.campaignReady)+'.');if(s.trust<35)return fail('Довіра нижча за 35%. Місто поки не готове до нового звернення.');o.campaignUntil=t+45;o.campaignReady=t+150;s.trust-=4;sim.say('Диспетчер','На 45 хв відкладаємо бойлери й пральні машини. Добровільна економія: побутове навантаження −8%.');sim.log('campaign','Оголошено добровільну економію на 45 хв.');return {ok:true};
}
return null;
}
function step(sim,dt){const s=sim.state(),o=s.ops,t=s.minute;
for(const x of o.services){const harm=(1-x.mode)*dt*(peak(t)?2:1);x.impact+=harm;s.trust=B.clamp(s.trust-harm/120,0,100);}
for(const j of o.jobs){if(j.state==='pending'&&t>=j.at){j.state='open';sim.log('request','Нова заявка: '+j.title+'. Бригада потрібна до '+B.clock(j.deadline)+'.');}if(j.state==='working'&&t+dt>=j.ends){j.state='done';o.crew=null;if(j.reward==='repair')o.boostUntil=t+dt+90;if(j.reward==='fuel')for(const c of s.criticals)c.bonusFuel=(c.bonusFuel||0)+90;if(j.reward==='care')s.trust=B.clamp(s.trust+8,0,100);sim.log('crew','Завершено: '+j.title+'. '+j.detail);sim.say('Бригада','Заявку закрили. Тепер би нам каву, але можна наступну адресу.');}if(j.state==='open'&&t>=j.deadline){j.state='missed';s.trust=Math.max(0,s.trust-3);sim.log('crew','Не встигли: '+j.title+'. Місцева проблема лишилась.');}}
for(const l of o.loans){if(!l.announced&&t>=l.until){l.announced=true;sim.log('loan','Почалось повернення позики: доступний ліміт менший на 20 МВт протягом 90 хв.');sim.say('Сусідня диспетчерська · симуляція','Тепер наша черга. Повернення вже враховано в ліміті.');}if(!l.settled&&t>=l.paidAt){l.settled=true;sim.log('loan','Енергетичний борг повернуто повністю.');}}
if(!o.crisisAnnounced&&t>=1030){o.crisisAnnounced=true;sim.say('Начальник зміни','О 17:40 провал ліміту. Навіть міські служби потребуватимуть тимчасового вимкнення. Підготуй бригаду, резерв або план обмежень.');sim.log('warning','О 17:40 різке падіння ліміту: пріоритети міських служб вирішує диспетчер.');}
}
function score(s){return B.clamp(1-s.ops.services.reduce((n,x)=>n+x.impact,0)/2400,.05,1);}
B.operations={init,load,usage,peak,adjustment,demandFactor,dispatch,step,score};
})(globalThis.BD=globalThis.BD||{});
/* sim/civic.js */
(function(B){
'use strict';
const people=[['deputy','Депутат Березовий','Приймальня депутата','podil','Кум святкує ювілей. Увімкни Поділ на пів години. Машину з пальним знайдемо.','fuel',true],['hospital','Олена Романівна','Керівниця лікарні','obolon','Лабораторія має завершити аналізи. Потрібні 30 хв світла. Допоможете — поділимось резервом.','fuel',false],['builder','Артур Бетонович','Забудовник','pechersk','Презентація ЖК «Автономний». Генератор, блін, не завівся. Виручи своїх.','power',true],['volunteer','Назар','Координатор волонтерів','troieshchyna','Паяємо зарядні станції. Дайте пів години — підкинемо резервну лінію.','power',false],['editor','Ірина','Редакторка міського медіа','lukianivka','Студії треба передати міський ефір. 30 хв світла — пояснимо людям реальний графік.','trust',false],['bossfriend','Кум начальника','Дуже особистий номер','pechersk','Начальник сказав: «Ти зрозумієш». Сауну вже протопили, лишилося світло.','trust',true],['rail','Марина','Координаторка евакуаційного хабу','teremky','У хабі заряджають звʼязок. Тримай живлення 30 хв — допоможемо з пальним.','fuel',false],['business','Пан Леонід','Голова бізнес-асоціації','pozniaky','Холодильники складу здаються. Втримай 30 хв — відкриємо вам резервний ввід.','power',false]];
function init(s,enabled){s.civic={enabled:enabled!==false,risk:0,neglect:0,warning:0,scandal:0,missed:0,lastReaction:0,deals:[],bonusUntil:0,people:people.map(x=>({id:x[0],name:x[1],role:x[2],sector:s.sectors.some(y=>y.id===x[3])?x[3]:s.home,text:x[4],reward:x[5],favor:x[6],relation:0}))};}
function rating(s){const c=s.civic;return Math.round(B.clamp(s.trust*.7+(100-c.risk)*.3-c.scandal*.3,0,100));}
function calls(s){return s.civic.people.map((p,i)=>({id:'contact-'+p.id,person:p.id,speaker:p.name,role:p.role+' · вигаданий персонаж',at:470+i*85,until:1390,condition:'always',text:p.text+' Черга: '+s.sectors.find(x=>x.id===p.sector).name+'.',choices:[{label:p.favor?'Домовились, зроблю виняток':'Беру заявку',detail:'30 хв безперервного світла за 60 хв. Успіх: стосунки +20, '+(p.reward==='fuel'?'+60 хв резерву':p.reward==='power'?'+30 МВт на 60 хв':'+8 довіри')+(p.favor?'; одразу −6 довіри, +12 розголосу.':''),effect:'contactAccept'},{label:'За загальною чергою, без обіцянки',detail:'Стосунки −5. Прозора відповідь: +1 довіри.',effect:'contactRefuse'}]}));}
function answer(sim,c,effect){const s=sim.state(),v=s.civic,p=v.people.find(p=>p.id===c.person);if(!p)return false;if(effect==='contactAccept'){if(v.deals.some(d=>d.person===p.id&&d.state==='open'))return false;v.deals.push({person:p.id,sector:p.sector,progress:0,deadline:s.minute+60,state:'open'});if(p.favor){v.scandal=B.clamp(v.scandal+12,0,100);s.trust=B.clamp(s.trust-6,0,100);sim.say('Сусід із калькулятором','Ага, для кума мегавати знайшлись. Скриншот уже в чаті.');}sim.log('contact','Обіцянка для '+p.name+': 30 хв світла до '+B.clock(s.minute+60)+'.');}else {p.relation=B.clamp(p.relation-5,-100,100);s.trust=B.clamp(s.trust+1,0,100);}return true;}
function missed(sim,c){const s=sim.state(),v=s.civic,p=v.people.find(p=>p.id===c.person);v.missed++;s.trust=B.clamp(s.trust-2,0,100);if(p)p.relation=B.clamp(p.relation-10,-100,100);v.risk=B.clamp(v.risk+3,0,100);sim.say(c.speaker,'Дзвінок скинули. Добре, звернення реєструю письмово.');sim.log('call',c.speaker+': проігноровано. Довіра −2, ризик +3'+(p?', стосунки −10':'')+'.');}
function step(sim,dt,restorable){const s=sim.state(),c=s.civic;if(!c.enabled)return;
const total=s.sectors.reduce((n,x)=>n+x.population,0),off=s.sectors.filter(x=>!x.on),fraction=off.reduce((n,x)=>n+x.population,0)/total;
const neglect=restorable>0&&s.spareTime>12;c.neglect=neglect?c.neglect+dt:Math.max(0,c.neglect-dt*2);
const home=s.sectors.find(x=>x.id===s.home),mean=s.sectors.reduce((n,x)=>n+x.dark*x.population,0)/total;if(home.on&&mean-home.dark>60){c.scandal=B.clamp(c.scandal+dt*.08,0,100);s.trust=B.clamp(s.trust-dt*.04,0,100);}
const long=off.filter(x=>x.block>120).length;
const serviceWaste=s.ops.services.some(x=>x.mode===0&&sim.balance(s.minute).room>=B.operations.usage({...x,mode:1},s.minute));
if(neglect||serviceWaste){c.risk=B.clamp(c.risk+dt*(fraction>.85?1.6:.42)+(serviceWaste?dt*.25:0),0,100);s.trust=B.clamp(s.trust-dt*(fraction>.85?.45:.1),0,100);}else c.risk=Math.max(0,c.risk-dt*.35);
s.trust=B.clamp(s.trust-long*dt*.012,0,100);
for(const d of c.deals){if(d.state!=='open')continue;const p=c.people.find(x=>x.id===d.person);if(s.minute>=d.deadline){d.state='broken';p.relation=B.clamp(p.relation-25,-100,100);s.trust=B.clamp(s.trust-5,0,100);c.risk=B.clamp(c.risk+8,0,100);sim.say(p.name,'Обіцяли — зірвали. Наступного разу без моєї допомоги.');sim.log('contact',p.name+': обіцянку порушено. Стосунки −25, довіра −5.');continue;}d.progress=s.sectors.find(x=>x.id===d.sector).on?d.progress+dt:0;if(d.progress>=30){d.state='kept';p.relation=B.clamp(p.relation+20,-100,100);if(p.reward==='fuel')for(const x of s.criticals)x.bonusFuel=(x.bonusFuel||0)+60;if(p.reward==='power')c.bonusUntil=Math.max(s.minute,c.bonusUntil)+60;if(p.reward==='trust')s.trust=B.clamp(s.trust+8,0,100);sim.say(p.name,'Домовленість виконана. Нашу допомогу вже передали.');sim.log('contact',p.name+': стосунки +20; бонус '+(p.reward==='fuel'?'60 хв резерву':p.reward==='power'?'30 МВт на 60 хв':'8 довіри')+'.');}}
const level=c.risk>=70?2:c.risk>=35?1:0;if(level>c.warning){c.warning=level;sim.say('Начальник зміни',level===1?'Це не економія, це бездіяльність. Потужність є — повертай світло!':'Останнє попередження. Ще трохи такого керування — здаєш перепустку.');sim.log('discipline',level===1?'Догана: поверни живлення, яке дозволяє ліміт.':'Ризик звільнення понад 70%. Відновлюй живлення негайно.');}
if(s.minute-c.lastReaction>=35&&(neglect||long>2)){c.lastReaction=s.minute;const lines=['Ви там охрініли? Ліміт є, світла немає. Це що за керування?','Бляха, холодильник уже тепліший за батарею. Увімкніть хоч по черзі!','Кому ще темно? Реєструємо колективну скаргу, а не сорок смайликів.','У кума розетка VIP, а ми знову печерні люди?'];sim.say('Обурені мешканці',lines[Math.floor(s.minute/35)%lines.length]);}
if(c.risk>=100){s.done=true;s.reason='dismissed';sim.log('discipline','Відсторонено від зміни за бездіяльність. Керування прийняв резервний диспетчер.');}
}
B.civic={init,rating,calls,answer,missed,step};
})(globalThis.BD=globalThis.BD||{});
/* sim/model.js */
(function(B){
'use strict';
const P=B.P;
function create(options){
const o=options||{};const seed=Number(o.seed)||B.hash(o.date||B.today());const rng=B.random(seed);
const definitions=B.data.grid.sectors;
const home=definitions.find(x=>x.id===o.home)?.id||definitions[0].id;
const other=definitions.filter(x=>x.id!==home);const mother=other[Math.floor(rng()*other.length)].id;const friend=other.filter(x=>x.id!==mother)[Math.floor(rng()*(other.length-1))].id;
const extra=B.data.stories.slice(2).map(x=>({x,r:rng()})).sort((a,b)=>a.r-b.r).slice(0,4).map(x=>x.x);
const selected=[...B.data.stories.slice(0,2),...extra].sort((a,b)=>a.at-b.at);
const events=[];for(let w=0;w<P.eventQuota;w++){const pool=B.data.events.filter(e=>e.window===w);events.push(Object.assign({},pool[Math.floor(rng()*pool.length)],{at:570+w*125+Math.floor(rng()*20),applied:false}));}
let s={version:B.VERSION,seed,date:o.date||B.today(),home,homeName:o.homeName||definitions.find(x=>x.id===home).name,mother,friend,mode:o.mode==='reading'?'reading':'standard',minute:P.start,frost:rng(),done:false,reason:null,grace:0,spareTime:0,avoidable:0,emergencies:0,emergencyMin:0,trust:65,supportMinutes:0,personalCalls:0,callSlot:0,seenCalls:[],lastCallEnd:360,currentCall:null,callLog:[],debt:null,investigation:{stage:0,response:null,due:null,kept:null},verification:null,warmSent:false,motherSent:false,seq:0,journal:[],chat:[],usedChat:[],nextChat:480,flags:{},promises:[],events:o.events===false?[]:events,phone:o.phone!==false,stories:o.stories===false?[]:selected.map(x=>Object.assign({},x,{state:'pending',progress:0,rewarded:false,completedAt:null})),sectors:definitions.map(x=>Object.assign({},x,{on:true,dark:0,pain:0,starts:0,block:0,longest:0,changed:P.start,support:false,fairEpisodes:0,fairTaken:0})),criticals:B.data.grid.critical.map(x=>Object.assign({},x,{fuel:x.fuelMin,out:0,failed:false}))};
if(o.saved&&o.saved.version===B.VERSION)s=B.clone(o.saved);
if(!s.ops)B.operations.init(s);
if(!s.civic)B.civic.init(s,o.civic);
const sector=id=>s.sectors.find(x=>x.id===id);
function log(kind,text,details){const item={id:++s.seq,minute:s.minute,kind,text,details:details||null};s.journal.push(item);if(s.journal.length>500)s.journal.shift();return item;}
function say(speaker,text,avatar){s.chat.push({id:++s.seq,minute:s.minute,speaker,text,avatar:avatar||null});if(s.chat.length>80)s.chat.shift();}
function loads(t){return s.sectors.map(x=>B.demand.load(x,t,s.frost)*B.operations.demandFactor(s,t)+s.events.filter(e=>e.applied&&e.sectorId===x.id&&t>=e.started&&t<e.started+e.duration).reduce((a,e)=>a+e.mw,0));}
function balance(t){const a=loads(t);const limit=B.demand.limit(t,s.frost,o.emergency)+B.operations.adjustment(s,t)+(t<s.civic.bonusUntil?30:0);const load=P.protectedMw+B.operations.load(s,t)+s.sectors.reduce((v,x,i)=>v+(x.on?a[i]+(x.support?P.supportMw:0):0),0);return {limit,load,room:limit-load,loads:a};}
function switchPower(x,on,automatic){if(x.on===on)return;const snap=balance(s.minute);if(!on){x.starts++;x.block=0;if(snap.room<0){const candidate=s.sectors.filter(y=>y.on).sort((a,b)=>a.pain-b.pain)[0];if(candidate){candidate.fairEpisodes++;if(candidate.id===x.id)candidate.fairTaken++;}}}else x.block=0;x.on=on;x.changed=s.minute;log(automatic?'automatic':'toggle',(on?'Подано':'Знято')+' напругу: '+x.name+'.',{sectorId:x.id,on});if(!on&&x.id===s.home&&s.investigation.due!==null&&s.minute<=s.investigation.due){s.investigation.kept=true;s.investigation.due=null;}}
function dispatch(a){if(s.done)return {ok:false,reason:'Зміну завершено.'};const x=sector(a.sectorId);const b=balance(s.minute);
const operation=B.operations.dispatch({state:()=>s,balance,log,say},a);if(operation)return operation;
if(a.type==='toggle'){
if(!x)return {ok:false,reason:'Такої ділянки немає.'};
const need=b.loads[s.sectors.indexOf(x)]+(x.support?P.supportMw:0);
if(!x.on&&need>b.room+1)return {ok:false,reason:'Спочатку звільни '+Math.ceil(need-b.room)+' МВт в іншій черзі.'};
switchPower(x,!x.on,false);return {ok:true};
}
if(a.type==='support'){
if(s.minute<900)return {ok:false,reason:'Пункти підтримки відкриються о 15:00.'};
if(!x)return {ok:false,reason:'Оберіть ділянку.'};
if(!x.support&&(!x.on||b.room<P.supportMw))return {ok:false,reason:'Потрібні світло в ділянці та 3 вільні МВт.'};
if(!x.support&&s.sectors.filter(x=>x.support).length>=P.maxSupport)return {ok:false,reason:'На зміну доступні три пункти.'};
x.support=!x.support;log('support',(x.support?'Відкрито':'Закрито')+' пункт: '+x.name+'.');if(x.support)say('Пані Людмила','Подовжувач розклала. Пароль від вайфаю — на дверях.','osbb');return {ok:true};
}
if(a.type==='promise'){
if(s.minute<780)return {ok:false,reason:'Графік можна анонсувати з 13:00.'};
const from=a.from===undefined?1080:Number(a.from),to=a.to===undefined?1260:Number(a.to);
if(!x||!Number.isFinite(from)||!Number.isFinite(to)||from<s.minute||to<=from||to>P.end)return {ok:false,reason:'Обіцянка має стосуватися майбутнього вікна.'};
if(s.promises.filter(p=>p.kind!=='favor').length>=P.maxPromises&&a.kind!=='favor')return {ok:false,reason:'Дві обіцянки за зміну — межа. Перегляд не відкриває новий слот.'};
if(s.promises.some(p=>p.sectorId===x.id&&p.state==='open'&&p.to>from&&p.from<to))return {ok:false,reason:'Для цієї ділянки вже є обіцянка.'};
const p={id:'promise-'+s.promises.length,sectorId:x.id,name:x.name,from,to,dark:0,state:'open',kind:a.kind||'public'};s.promises.push(p);log('promise','Обіцяно: '+x.name+', '+B.clock(from)+'–'+B.clock(to)+'.');say('Адмін, закріпіть','Адмін, закріпіть графік.');return {ok:true};
}
if(a.type==='revise'){
const p=s.promises.find(x=>x.id===a.id&&x.state==='open');if(!p||s.minute>=p.from)return {ok:false,reason:'Вікно вже почалось або обіцянку закрито.'};p.state=p.from-s.minute>=P.notice?'revised':'broken';s.trust=Math.max(0,s.trust-5);log('promise','Графік переглянуто: '+p.name+'.');say('Адмін, закріпіть','Адмін, відкріпіть графік.');return {ok:true};
}
return {ok:false,reason:'Невідома дія.'};
}
function advanceStories(dt){const t=s.minute;
for(const r of s.stories){
if(r.state==='pending'&&t>=r.at){if(t+r.need>r.deadline){r.state='missed';log('story',r.failure,{id:r.id,done:false});continue;}if(s.stories.filter(x=>x.state==='active').length<2){r.state='active';say(r.speaker,'Потрібно '+r.need+' хв без перерви до '+B.clock(r.deadline)+'. '+r.title+'.',r.avatar);log('request',r.title+' — '+sector(r.sectorId).name+'.');}}
if(r.state!=='active')continue;
if(t>=r.deadline){r.state='missed';s.trust=B.clamp(s.trust-4,0,100);say(r.speaker,r.failure+' Довіра −4.',r.avatar);log('story',r.failure,{id:r.id,done:false});continue;}
if(sector(r.sectorId).on)r.progress+=Math.min(dt,r.deadline-t);else r.progress=0;
if(r.progress+1e-8>=r.need){r.state='done';s.trust=B.clamp(s.trust+3,0,100);r.completedAt=t+dt;r.progress=r.need;say(r.speaker,r.success,r.avatar);log('story',r.success,{id:r.id,done:true});if(r.reward==='fuel'&&!r.rewarded){r.rewarded=true;const c=s.criticals.find(c=>c.id==='likarnia');c.bonusFuel=(c.bonusFuel||0)+120;log('fuel','Пекар передав 120 хв резерву допоміжним службам лікарні.');}}
}
}
function bestRestorable(b){const off=s.sectors.map((x,i)=>({x,mw:b.loads[i]+(x.support?P.supportMw:0)})).filter(y=>!y.x.on);if(!off.length||Math.min(...off.map(y=>y.mw))>b.room+1)return 0;if(off.reduce((n,y)=>n+y.mw,0)<=b.room+1)return off.reduce((n,y)=>n+y.x.population,0);let best=0;for(let mask=1;mask<(1<<off.length);mask++){let mw=0,pop=0;for(let i=0;i<off.length;i++)if(mask&(1<<i)){mw+=off[i].mw;pop+=off[i].x.population;}if(mw<=b.room+1&&pop>best)best=pop;}return best;}
function step(minutes){let left=Math.max(0,Number(minutes)||0);while(left>1e-8&&!s.done){const dt=Math.min(P.step,left,P.end-s.minute);const t=s.minute;
B.operations.step({state:()=>s,log,say},dt);
for(const e of s.events){if(!e.applied&&!e.expired&&t>=e.at+60){e.expired=true;}if(!e.applied&&!e.expired&&t>=e.at&§or(e.sectorId).on){e.applied=true;e.started=t;log('event',e.text,{id:e.id,sectorId:e.sectorId});}}
let b=balance(t);if(b.room< -1){s.grace+=dt;if(s.grace>=(t<P.openingUntil?P.openingGrace:P.grace)){const xs=s.sectors.filter(x=>x.on).sort((a,c)=>b.loads[s.sectors.indexOf(c)]-b.loads[s.sectors.indexOf(a)]);for(const x of xs){switchPower(x,false,true);s.emergencies++;b=balance(t);if(b.room>=-1)break;}if(b.room< -1){s.emergencies++;s.trust=Math.max(0,s.trust-8);log('automatic','Захист обмежив міські служби. Потрібне ручне відновлення.');for(const service of s.ops.services){service.mode=0;service.changed=t;b=balance(t);if(b.room>=-1)break;}}s.emergencyMin+=dt;s.grace=0;}}else s.grace=0;
if(b.limit<P.protectedMw){s.done=true;s.reason='handover';break;}
const restorable=bestRestorable(b);s.spareTime=restorable>0?s.spareTime+dt:0;if(s.spareTime>P.restoreGrace)s.avoidable+=restorable*dt;
for(const x of s.sectors){if(!x.on){const before=Math.max(0,x.block-P.blockSoft);x.block+=dt;x.dark+=dt;const after=Math.max(0,x.block-P.blockSoft);x.pain+=dt*B.demand.weight(t)+P.blockPenalty*(after*after-before*before);x.longest=Math.max(x.longest,x.block);}if(x.support&&x.on){const before=Math.floor(s.supportMinutes/60);s.supportMinutes+=dt;s.trust=B.clamp(s.trust+dt/60,0,100);if(Math.floor(s.supportMinutes/60)>before&&s.supportMinutes<=180){log('support','Пункти підтримки: '+Math.floor(s.supportMinutes/60)+' год роботи. Сусіди зарядили телефони й зігрілися.');if(s.supportMinutes<=60)say('Пані Людмила','Телефони зарядили. Чай допили. Подовжувач поверніть, він іще попрацює.','osbb');}}}
for(const c of s.criticals){if(sector(c.sectorId).on)c.fuel=Math.min(c.fuelMin,c.fuel+dt*P.fuelRefill);else{const bonusUsed=Math.min(c.bonusFuel||0,dt);c.bonusFuel=Math.max(0,(c.bonusFuel||0)-bonusUsed);c.fuel=Math.max(0,c.fuel-(dt-bonusUsed));if(c.fuel===0&&!(c.bonusFuel>0)){c.out+=dt;if(!c.failed){c.failed=true;log('reserve',c.name+': резерв вичерпано, послугу тимчасово обмежено.');}}}}
for(const p of s.promises){if(p.state!=='open')continue;const overlap=Math.max(0,Math.min(t+dt,p.to)-Math.max(t,p.from));if(!sector(p.sectorId).on)p.dark+=overlap;if(t+dt>=p.to){p.state=p.dark<=P.promiseTolerance?'kept':'broken';s.trust=B.clamp(s.trust+(p.state==='kept'?6:-10),0,100);log('promise',(p.state==='kept'?'Виконано':'Порушено')+': '+p.name+', '+B.clock(p.from)+'–'+B.clock(p.to)+'.');say('Пані Людмила',p.state==='kept'?'Вікно витримали. Оце вже можна людям передати.':'Графік не витримали. Люди переплановують вечір.','osbb');}}
B.civic.step({state:()=>s,log,say,balance},dt,restorable);
advanceStories(dt);
if(s.verification&&t>=s.verification){s.verification=null;s.trust=B.clamp(s.trust+6,0,100);say('Адмін, закріпіть','То гірлянда на батарейках. Перевірено. Розходимось.');log('verification','Чутку перевірили: у сусідів автономна гірлянда.');}
if(s.debt&&s.debt.state==='open'&&t>=1160){s.debt.state='returned';log('debt','Пан із приймальні знову просить світло. Обіцяне раннє вікно вже завершене.');say('Приймальня','Ви ж тоді змогли. А зараз?');}
if(s.investigation.due!==null&&t>s.investigation.due){s.investigation.kept=false;s.investigation.due=null;log('investigation','Обіцяну ротацію домашньої черги не виконано.');s.trust=Math.max(0,s.trust-10);}
if(!s.motherSent&&t>=1275){s.motherSent=true;const m=sector(s.mother);say('Мама',m.on?'Світло є. Чай зробила. Ти після зміни набери.':'У нас ще темно. Термос тримає. Ти після зміни набери.','mother');log('personal','Мама: '+B.duration(m.dark)+' темряви на цей момент.');}
s.minute+=dt;left-=dt;if(s.minute>=P.end){s.minute=P.end;s.done=true;s.reason='shift';}
}
}
function metrics(){const total=s.sectors.reduce((v,x)=>v+x.population,0);const saidi=s.sectors.reduce((v,x)=>v+x.dark*x.population,0)/total;const saifi=s.sectors.reduce((v,x)=>v+x.starts*x.population,0)/total;const mean=s.sectors.reduce((v,x)=>v+x.pain*x.population,0)/total;let pairs=0;for(const x of s.sectors)for(const y of s.sectors)pairs+=x.population*y.population*Math.abs(x.pain-y.pain);const gini=mean?pairs/(2*total*total*mean):0;const promises=s.promises.filter(p=>p.kind!=='favor');const credit=promises.reduce((v,p)=>v+(p.state==='kept'?1:p.state==='revised'?.5:0),0);const factors={city:B.operations.score(s),equality:1/(1+Math.exp((gini-P.giniMid)/P.giniWidth)),promise:P.promiseFloor+(1-P.promiseFloor)*(promises.length?credit/promises.length:0),service:B.clamp(1-s.avoidable/P.darkBudget,0,1),control:B.clamp(1-(s.emergencies*P.emergencyCost+s.emergencyMin)/P.emergencyBudget,0,1),steadiness:B.clamp(1-Math.max(0,saifi-P.saifiFree)/P.saifiBudget,0,1),integrity:B.clamp(1-s.criticals.filter(c=>c.failed).length*.2,0,1)};let score=100;for(const v of Object.values(factors))score*=v;if(s.reason==='handover'||s.reason==='dismissed')score=0;score=Math.round(score*10)/10;return {rating:B.civic.rating(s),risk:s.civic.risk,score,rank:B.ranks[P.rankAt.filter(n=>score>=n).length],saidi,saifi,gini,factors,completed:s.stories.filter(r=>r.state==='done').length,promisesKept:promises.filter(p=>p.state==='kept').length,criticalOk:s.criticals.filter(c=>!c.failed).length,cityServices:s.ops.services.map(x=>({name:x.name,impact:x.impact})),repairs:s.ops.jobs.filter(j=>j.state==='done').length,loans:s.ops.loans.length};}
function snapshot(){const b=balance(s.minute);return Object.assign(B.clone(s),{balance:b,forecast:{limit:balance(Math.min(P.end,s.minute+60)).limit,load:balance(Math.min(P.end,s.minute+60)).load},metrics:metrics()});}
return {step,dispatch,snapshot,metrics,serialize:()=>B.clone(s),state:()=>s,log,say,sector,balance};
}
B.sim={create};
})(globalThis.BD=globalThis.BD||{});
/* data/narrative.js */
(function(B){
'use strict';
function eligible(call,sim){const s=sim.state();const m=sim.metrics();switch(call.condition){case 'always':return true;case 'crew':return s.ops.jobs.some(j=>j.state==='open');case 'loan':return s.ops.loans.some(l=>s.minute<l.paidAt);case 'dark':return s.sectors.some(x=>!x.on);case 'longDark':return s.sectors.some(x=>x.block>110);case 'baker':return s.stories.some(x=>x.id==='baker');case 'school':return s.stories.some(x=>x.id==='school'&&x.state==='done');case 'workshop':return s.stories.some(x=>x.id==='workshop'&&x.state==='active');case 'inequality':return m.saidi-sim.sector(s.home).dark>70;case 'investigation':return s.investigation.stage>0;default:return false;}}
function update(sim,seconds){const s=sim.state();if(s.done)return;
if(s.phone){
if(s.currentCall){if(!s.currentCall.serious&&s.mode!=='reading'){s.currentCall.left=Math.max(0,s.currentCall.left-seconds);if(s.currentCall.left===0)answer(sim,-1);}}
else if(s.minute>=450&&s.minute-s.lastCallEnd>=B.P.callGap&&s.seenCalls.length<B.P.maxCalls){
const mandatory=['baker','mother','osbb','thanks'];
const reserve=mandatory.filter(id=>!s.seenCalls.includes(id)&&B.data.calls.find(c=>c.id===id).until>s.minute).length;
let pool=[...B.data.calls,...B.civic.calls(s)].filter(c=>!s.seenCalls.includes(c.id)&&s.minute>=c.at&&s.minute<c.until&&eligible(c,sim));
const phaseLimit=s.minute<600?3:s.minute<780?6:s.minute<960?8:s.minute<1140?11:s.minute<1320?13:14;
if(s.seenCalls.length>=Math.min(phaseLimit,B.P.maxCalls-reserve))pool=pool.filter(c=>mandatory.includes(c.id));
pool.sort((a,b)=>{const priority=c=>mandatory.includes(c.id)?100:c.id==='journalist'||c.id==='chief'?80:c.person?50:0;return priority(b)-priority(a)||(B.hash(s.seed+':'+a.id)-B.hash(s.seed+':'+b.id));});
const c=pool[0];if(c){s.callSlot=(s.callSlot||0)+1;s.currentCall=Object.assign(B.clone(c),{left:B.P.callSeconds});s.seenCalls.push(c.id);if(c.id==='mother')s.personalCalls++;if(c.id==='journalist'){s.investigation.stage=2;sim.log('investigation','Редакція надіслала запит про нерівність відключень.');}if(c.id==='chief')s.investigation.stage=3;}
}
}
if(s.minute>=s.nextChat){
const m=sim.metrics();const home=sim.sector(s.home);if(s.minute>900&&s.investigation.stage===0&&m.saidi-home.dark>60){s.investigation.stage=1;sim.say('Сусідка','А чого в домашній черзі диспетчера світло довше? Хтось рахував?');}
const constrained=s.ops.services.filter(x=>x.mode<1);const special=constrained.length?constrained[B.hash(s.seed+':'+s.nextChat)%constrained.length].id:s.ops.crew?'crew':s.ops.loans.some(l=>s.minute<l.paidAt)?'loan':null;
let tag=special&&Math.floor(s.minute/22)%2===0?special:s.minute>1280?'warm':s.promises.some(p=>p.state==='broken')?'broken':s.sectors.some(x=>x.support&&x.on)?'support':s.minute%120<60?'ambient':s.sectors.some(x=>!x.on)?'dark':'lit';
let pool=B.data.chat.filter(x=>x.trigger===tag&&!s.usedChat.includes(x.id)&&(!x.requires||s.usedChat.includes(x.requires)));if(!pool.length)pool=B.data.chat.filter(x=>x.trigger==='ambient'&&!s.usedChat.includes(x.id)&&(!x.requires||s.usedChat.includes(x.requires)));
if(pool.length){const x=pool[B.hash(s.seed+':'+s.nextChat)%pool.length];s.usedChat.push(x.id);sim.say(x.speaker,x.text,x.avatar);}
s.nextChat=s.minute+22;
}
}
function answer(sim,index){const s=sim.state();const c=s.currentCall;if(!c)return {ok:false,reason:'Немає активного дзвінка.'};const choice=c.choices[index];if(!choice){B.civic.missed(sim,c);s.callLog.push({id:c.id,answer:'missed'});s.currentCall=null;s.lastCallEnd=s.minute;return {ok:true};}
let result={ok:true};if(c.person)B.civic.answer(sim,c,choice.effect);switch(choice.effect){
case 'metroEco':result=sim.dispatch({type:'service',id:'metro',mode:0});break;
case 'heatEco':result=sim.dispatch({type:'service',id:'heat',mode:0});break;
case 'waterFull':result=sim.dispatch({type:'service',id:'water',mode:1});break;
case 'campaign':result=sim.dispatch({type:'campaign'});break;
case 'loan':result=sim.dispatch({type:'loan'});break;
case 'crewFirst':{const job=s.ops.jobs.find(j=>j.state==='open');result=job?sim.dispatch({type:'crew',id:job.id}):{ok:false,reason:'Відкритих заявок немає.'};break;}
case 'promiseOsbb':result=sim.dispatch({type:'promise',sectorId:'obolon'});break;
case 'debt':result=sim.dispatch({type:'promise',sectorId:'podil',from:s.minute,to:Math.min(1440,s.minute+30),kind:'favor'});if(result.ok)s.debt={state:'open',at:s.minute};break;
case 'verify':s.verification=s.minute+15;break;
case 'facts':s.trust=B.clamp(s.trust+3,0,100);break;
case 'disclose':s.investigation.response='Журнал відкритий';s.trust=B.clamp(s.trust+5,0,100);break;
case 'equalize':s.investigation.response='Обіцяна ротація';s.investigation.due=s.minute+45;s.investigation.kept=null;break;
case 'technical':s.investigation.response='Технічне пояснення не підтверджене: черги умовні';s.trust=B.clamp(s.trust-7,0,100);break;
case 'medical':s.flags.medical=true;break;
case 'mother':s.flags.motherAnswered=true;break;
case 'baker':s.flags.bakerFocused=true;break;
}
if(!result.ok)return result;
sim.log('call',c.speaker+': «'+choice.label+'».',{id:c.id,effect:choice.effect});s.callLog.push({id:c.id,answer:choice.effect});s.currentCall=null;s.lastCallEnd=s.minute;return {ok:true};
}
B.narrative={update,answer,eligible};
})(globalThis.BD=globalThis.BD||{});
/* ui/dom.js */
if(typeof module!=='undefined'&&module.exports)require('../../../_core/dom.js');
(function(B){
'use strict';
B.el=globalThis.GameCore.dom.el;
B.button=function(text,fn,cls){const e=B.el('button',cls||'bd-btn',text);e.type='button';e.addEventListener('click',fn);return e;};
B.asset=function(name){return B.assets[name]||'';};
B.avatar=function(name,cls){if(['baker','mother','osbb'].includes(name)){const e=B.el('img','bd-avatar '+(cls||''));e.src=B.asset(name);e.alt='';e.width=48;e.height=48;return e;}return B.el('span','bd-avatar bd-avatar-fallback '+(cls||''),'●');};
B.reveal=function(minute,realSeconds){return {numbers:true,phone:minute>=510&&realSeconds>=100,critical:minute>=570&&realSeconds>=140,promise:minute>=780&&realSeconds>=280,support:minute>=900&&realSeconds>=360};};
})(globalThis.BD=globalThis.BD||{});
/* ui/city-map.js */
(function(B){
'use strict';
// Geographic district polygons from Winecko's Kyiv map (CC BY-SA 4.0).
// Original north-up coordinates are preserved; relief is purely illustrative.
const NS='http://www.w3.org/2000/svg';
let nodes={},rows={},selected=null,detachLayout=null;
function svg(tag,attrs={},text){const n=document.createElementNS(NS,tag);for(const [k,v] of Object.entries(attrs))n.setAttribute(k,v);if(text)n.textContent=text;return n;}
const project=(x,y,z=0)=>[28+x,32+y-z];
const point=(x,y,z=0)=>project(x,y,z).map(v=>Math.round(v*10)/10).join(',');
const poly=(p,z=0)=>'M'+p.map(([x,y])=>point(x,y,z)).join('L')+'Z';
function inside(x,y,p){let c=false;for(let i=0,j=p.length-1;i<p.length;j=i++){const a=p[i],b=p[j];if((a[1]>y)!==(b[1]>y)&&x<(b[0]-a[0])*(y-a[1])/(b[1]-a[1])+a[0])c=!c;}return c;}
function select(id){if(id===selected)return;for(const key of [selected,id]){if(!key)continue;const active=key===id;nodes[key]?.group.classList.toggle('bd-map-selected',active);nodes[key]?.label.classList.toggle('bd-map-selected',active);rows[key]?.classList.toggle('bd-selected',active);}selected=id;}
function build(sim,act){
if(detachLayout)detachLayout();
nodes={};rows={};selected=null;
for(const row of document.querySelectorAll('#bd-sectors .bd-sector'))rows[row.dataset.sector]=row;
const host=document.getElementById('bd-city-lights');host.textContent='';
const map=svg('svg',{viewBox:'0 0 700 600','class':'bd-kyiv-map','aria-label':'Карта десяти адміністративних районів Києва. Північ угорі. Натисніть район, щоб перемкнути світло.'});
const defs=svg('defs');map.append(defs);const districts=B.data['city-map'].districts;
const ground=svg('g'),labels=svg('g');map.append(ground);
// Four geometry paths per district replace thousands of filtered window nodes.
for(const a of districts){
const group=svg('g',{'class':'bd-map-district','data-map-sector':a.id,role:'button',tabindex:'0'});group.append(svg('title',{},a.name+' район'));
group.append(svg('path',{d:poly(a.polygon,-5),'class':'bd-district-depth'}),svg('path',{d:poly(a.polygon),'class':'bd-district-ground'}));
const clip=svg('clipPath',{id:'bd-clip-'+a.id});clip.append(svg('path',{d:poly(a.polygon)}));defs.append(clip);
// Batched, deterministic city texture: thousands of lit windows in two paths.
// Kept inside the geographic outline; no raster UI or per-window DOM nodes.
let roads='',lights='',blocks='';
const xs=a.polygon.map(p=>p[0]),ys=a.polygon.map(p=>p[1]);
const x0=Math.min(...xs),x1=Math.max(...xs),y0=Math.min(...ys),y1=Math.max(...ys);
let seed=17+a.id.length;
const rand=()=>{seed=(seed*1664525+1013904223)>>>0;return seed/4294967296;};
for(let y=y0;y<y1;y+=6){
const bend=rand()*18;
roads+='M'+point(x0,y)+'Q'+point((x0+x1)/2,y+bend)+' '+point(x1,y-8);
for(let x=x0;x<x1;x+=5){
const px=x+rand()*3,py=y+rand()*3;
if(!inside(px,py,a.polygon))continue;
blocks+='M'+point(px,py)+'h2.8v2h-2.8Z';
if(rand()>.35)lights+='M'+point(px,py)+'h'+(rand()>.7?'2':'0.7');
}
}
for(let x=x0;x<x1;x+=15)roads+='M'+point(x,y0)+'Q'+point(x-16,(y0+y1)/2)+' '+point(x+20,y1);
group.append(svg('path',{d:blocks,'class':'bd-city-blocks','pointer-events':'none'}));
group.append(svg('path',{d:roads,'class':'bd-map-streets','clip-path':'url(#bd-clip-'+a.id+')','pointer-events':'none'}));
group.append(svg('path',{d:lights,'class':'bd-window','pointer-events':'none'}));
const offsets={pechersk:[42,3],solomianskyi:[-22,27],lukianivka:[-5,-3],borshchahivka:[-28,0],podil:[0,-7]};const [dx,dy]=offsets[a.id]||[0,0];const [lx,ly]=project(...a.label);
const label=svg('g',{'class':'bd-map-label bd-map-district','data-map-label':a.id,transform:`translate(${lx+dx} ${ly+dy})`});
if(dx||dy)label.append(svg('path',{d:`M${-dx} ${-dy}L0 0`,'class':'bd-map-leader'}));
label.append(svg('rect',{x:-70,y:-17,width:140,height:36,rx:7}),svg('circle',{cx:-59,cy:-3,r:3.5,'class':'bd-map-dot'}),svg('text',{x:5,y:-2,'text-anchor':'middle','class':'bd-map-name'},a.name));
const status=svg('text',{y:11,'text-anchor':'middle','class':'bd-map-status'});label.append(status);
const toggle=()=>act({type:'toggle',sectorId:a.id});group.addEventListener('click',toggle);label.addEventListener('click',toggle);
group.addEventListener('keydown',e=>{if((e.key==='Enter'||e.key===' ')&&!e.repeat){e.preventDefault();toggle();}});group.addEventListener('focus',()=>select(a.id));
ground.append(group);labels.append(label);nodes[a.id]={group,label,status,lx:lx+dx,ly:ly+dy,on:null,text:null};
}
// River shoreline comes from the same source projection as the districts.
const river=svg('g',{transform:'matrix(1 0 0 1 28 32)','class':'bd-real-river','pointer-events':'none'});for(const d of B.data['city-map'].water)river.append(svg('path',{d}));map.append(river,labels);
map.append(svg('text',{x:420,y:485,'class':'bd-river-name',transform:'rotate(65 420 485)'},'ДНІПРО'));
map.append(svg('text',{x:40,y:520,'class':'bd-map-compass'},'ПН ↑'),svg('text',{x:40,y:542,'class':'bd-map-caption'},'10 АДМІНІСТРАТИВНИХ РАЙОНІВ'),svg('text',{x:40,y:556,'class':'bd-map-caption'},'ЗАБУДОВА Й ЕЛЕКТРОМЕРЕЖА — ІГРОВІ'));
host.append(map);
if(typeof window!=='undefined'&&window.matchMedia){
const media=window.matchMedia('(max-width:780px)');
const layout=()=>{
const scale=media.matches?1.6:1;
map.setAttribute('viewBox',media.matches?'35 25 640 930':'0 0 700 600');
ground.setAttribute('transform','scale(1 '+scale+')');
river.setAttribute('transform',`matrix(1 0 0 ${scale} 28 ${32*scale})`);
for(const n of Object.values(nodes))n.label.setAttribute('transform',`translate(${n.lx} ${n.ly*scale})`);
};
layout();media.addEventListener('change',layout);detachLayout=()=>media.removeEventListener('change',layout);
}
const controls=document.getElementById('bd-map-zoom');controls.textContent='';let zoom=1;
const minus=B.button('−',()=>resize(Math.max(1,zoom-.25)),'bd-zoom-button');minus.setAttribute('aria-label','Зменшити карту');
const plus=B.button('+',()=>resize(Math.min(2,zoom+.25)),'bd-zoom-button');plus.setAttribute('aria-label','Збільшити карту');
const value=B.el('span','','100%');value.setAttribute('aria-live','polite');
function resize(next){zoom=next;map.style.width=(zoom*100)+'%';map.style.height=typeof window!=='undefined'&&!window.matchMedia('(max-width:780px)').matches&&zoom!==1?(550*zoom)+'px':'';value.textContent=Math.round(zoom*100)+'%';minus.disabled=zoom===1;plus.disabled=zoom===2;}
controls.append(minus,value,plus);resize(1);select(sim.state().home||B.data.grid.sectors[0].id);
}
function render(s){
for(let i=0;i<s.sectors.length;i++){
const x=s.sectors[i],n=nodes[x.id];if(!n)continue;
if(n.on!==x.on){n.on=x.on;n.group.classList.toggle('bd-map-dark',!x.on);n.label.classList.toggle('bd-map-dark',!x.on);n.group.setAttribute('aria-pressed',String(x.on));n.group.setAttribute('aria-label',x.name+': '+(x.on?'вимкнути світло':'увімкнути світло'));}
const text=x.on?Math.round(s.balance.loads[i])+' МВт · світло є':'Без світла · '+B.duration(x.block);
if(n.text!==text){n.text=text;n.status.textContent=text;}
}
}
B.cityMap={build,render,select};
})(globalThis.BD=globalThis.BD||{});
/* ui/operations.js */
(function(B){
'use strict';
let serviceRows={},jobRows={},sound=false,audio=null;
function feedback(){if(!sound)return;try{audio=audio||new (window.AudioContext||window.webkitAudioContext)();if(audio.state==='suspended')audio.resume();const osc=audio.createOscillator(),gain=audio.createGain();osc.type='triangle';osc.frequency.setValueAtTime(900,audio.currentTime);osc.frequency.exponentialRampToValueAtTime(160,audio.currentTime+.035);gain.gain.setValueAtTime(.035,audio.currentTime);gain.gain.exponentialRampToValueAtTime(.001,audio.currentTime+.04);osc.connect(gain);gain.connect(audio.destination);osc.start();osc.stop(audio.currentTime+.045);}catch(e){sound=false;}}
function build(sim,act){const E=B.el,host=document.getElementById('bd-operations');host.textContent='';serviceRows={};jobRows={};
const head=E('div','bd-panel-heading');head.append(E('h3','','Ресурси зміни'));host.append(head);
const services=document.getElementById('bd-services');services.textContent='';for(const x of sim.state().ops.services){const box=E('div','bd-sector bd-service-card');const info=E('div');info.append(E('strong','bd-sector-name',x.name));const status=E('small','bd-sector-meta');info.append(status);const watts=E('span','bd-sector-numbers');const btn=B.button('',()=>{const service=sim.state().ops.services.find(y=>y.id===x.id);act({type:'service',id:x.id,mode:service.mode?0:1});},'bd-toggle');const rocker=E('span','bd-rocker');rocker.setAttribute('aria-hidden','true');rocker.append(E('i','bd-rocker-grip'));const label=E('span','bd-switch-label');btn.append(rocker,label);box.append(info,watts,btn);services.append(box);serviceRows[x.id]={box,watts,btn,label,status};}
const contacts=document.getElementById('bd-contacts');contacts.textContent='';const h=E('div','bd-panel-heading');h.append(E('h3','','Звʼязки та зобовʼязання'));contacts.append(h,E('p','bd-ops-note','Усі персонажі вигадані. Бонус дається за виконане прохання. Кумівство: −6 довіри й +12 розголосу за виняток.'));const list=E('div');list.id='bd-contact-list';contacts.append(list);
const tasks=E('details','bd-ops-tasks');tasks.open=false;const title=E('summary','','Бригада та заявки');title.id='bd-crew-status';tasks.append(title);const jobHost=E('div','bd-job-list');for(const j of sim.state().ops.jobs){const box=E('div','bd-job');const status=E('small');const progress=E('div','bd-job-track'),fill=E('i');progress.append(fill);const btn=B.button('Відправити бригаду',()=>act({type:'crew',id:j.id}),'bd-btn bd-small');btn.setAttribute('aria-label','Бригада: '+j.title);box.append(E('strong','',j.title),E('p','',j.detail),status,progress,btn);jobHost.append(box);jobRows[j.id]={box,status,btn,fill};}tasks.append(jobHost);host.append(tasks);
const reserve=E('details','bd-ops-tasks');reserve.append(E('summary','','Взаємодопомога та економія'));reserve.append(E('p','bd-ops-note','Сусідня диспетчерська під керуванням гри. Це симуляція обміну, а не інші гравці онлайн.'));
const status=E('p','bd-ops-note');status.id='bd-loan-status';const loan=B.button('Позичити 40 МВт',()=>act({type:'loan'}),'bd-btn bd-small');loan.id='bd-loan';reserve.append(status,loan,E('p','bd-ops-note','+40 МВт на 45 хв. Потім −20 МВт на 90 хв повернення. Максимум дві позики; друга — після погашення першої.'));
const campaign=B.button('Оголосити економію −8%',()=>act({type:'campaign'}),'bd-btn bd-small');campaign.id='bd-campaign';const hint=E('p','bd-ops-note');hint.id='bd-campaign-status';reserve.append(campaign,hint);host.append(reserve);
const soundBtn=B.button('Клацання: '+(sound?'увімкнено':'вимкнено'),()=>{sound=!sound;soundBtn.textContent='Клацання: '+(sound?'увімкнено':'вимкнено');soundBtn.setAttribute('aria-pressed',String(sound));feedback();},'bd-text-btn bd-sound');soundBtn.setAttribute('aria-pressed',String(sound));host.append(soundBtn);
B.cityMap.build(sim,act);
}
function render(s){const o=s.ops,t=s.minute;for(const x of o.services){const row=serviceRows[x.id];row.box.dataset.mode=String(x.mode);row.watts.textContent=Math.round(B.operations.usage(x,t))+' МВт'+(B.operations.peak(t)?' · ПІК':'');row.btn.setAttribute('aria-pressed',String(x.mode===1));row.btn.setAttribute('aria-label',x.name+': '+(x.mode?'вимкнути':'увімкнути'));row.label.textContent=x.mode?'УВІМК.':'ВИМК.';row.status.textContent=(x.mode?'Працює':'Зупинено')+' · '+B.duration(x.impact)+' втрат'+(t-x.changed<10?' · '+Math.ceil(10-t+x.changed)+' хв до перемикання':'');}
const c=s.civic;document.getElementById('bd-hud-rating').textContent='Рейтинг '+B.civic.rating(s)+' · ризик '+Math.round(c.risk)+'%';document.getElementById('bd-live-rating').textContent=B.civic.rating(s)+' / 100';document.getElementById('bd-live-trust').textContent=Math.round(s.trust)+'%';document.getElementById('bd-live-risk').textContent=Math.round(c.risk)+'%';const off=s.sectors.filter(x=>!x.on);document.getElementById('bd-live-dark').textContent=Math.round(off.reduce((n,x)=>n+x.population,0)/s.sectors.reduce((n,x)=>n+x.population,0)*100)+'% міста';
const target=s.sectors.find((x,i)=>!x.on&&s.balance.loads[i]<=s.balance.room+1);const notice=document.getElementById('bd-consequence');notice.dataset.danger=String(c.risk>=35);notice.textContent=target?'Є '+Math.floor(s.balance.room)+' вільних МВт. Увімкни '+target.name+'. Після 12 хв бездіяльності росте ризик звільнення; при 100% зміна закінчиться.':c.risk>0?'Повертай доступне живлення: ризик зменшується, коли потужність використовується. Ротуй черги до 2 год темряви.':'Рейтинг = 70% довіри + 30% безпеки посади − розголос привілеїв. Вимушений дефіцит не є бездіяльністю.';
const list=document.getElementById('bd-contact-list');const key=JSON.stringify([c.people.map(p=>p.relation),c.deals.map(d=>[d.person,d.state,Math.floor(d.progress),Math.ceil(d.deadline-t)]),c.missed,c.scandal]);if(list.dataset.key!==key){list.dataset.key=key;list.textContent='';for(const p of c.people){const d=c.deals.find(d=>d.person===p.id);const el=B.el('div','bd-contact');el.append(B.el('strong','',p.name),B.el('span','',p.relation>0?'+'+p.relation:String(p.relation)));el.append(B.el('small','',d?(d.state==='open'?'Світло '+Math.floor(d.progress)+'/30 хв · ще '+Math.max(0,Math.ceil(d.deadline-t))+' хв':d.state==='kept'?'Виконано · бонус отримано':'Порушено · допомогу втрачено'):p.role));list.append(el);}list.append(B.el('p','bd-ops-note','Пропущено дзвінків: '+c.missed+' · Розголос привілеїв: '+c.scandal+'/100. Пропуск: −2 довіри, +3 ризику; для контактів ще −10 стосунків.'));}
document.getElementById('bd-crew-status').textContent='Бригада: '+(o.crew?'на виїзді':'вільна')+' · заявки: '+o.jobs.filter(j=>j.state==='open').length;
for(const j of o.jobs){const row=jobRows[j.id];row.box.hidden=j.state==='pending'||j.state==='missed'||j.state==='done';row.btn.disabled=!!o.crew||j.state!=='open'||t+30>j.deadline;row.status.textContent=j.state==='working'?'Готово за '+Math.ceil(j.ends-t)+' хв':'Встигнути до '+B.clock(j.deadline)+' · робота 30 хв';row.fill.style.width=j.state==='working'?B.clamp((1-(j.ends-t)/30)*100,0,100)+'%':'0%';}
const loan=o.loans.find(l=>t<l.paidAt);document.getElementById('bd-loan-status').textContent=loan?(t<loan.until?'Отримуєш +40 МВт до '+B.clock(loan.until)+'. Після цього почнеться повернення.':'Повертаєш 20 МВт до '+B.clock(loan.paidAt)+'.'):'Боргу немає. Використано '+o.loans.length+' із 2 поставок.';document.getElementById('bd-loan').disabled=!!loan||o.loans.length>=2||t<600||t>1260;
document.getElementById('bd-campaign').disabled=t<o.campaignReady||s.trust<35;document.getElementById('bd-campaign-status').textContent=t<o.campaignUntil?'Місто економить до '+B.clock(o.campaignUntil)+'.':t<o.campaignReady?'Наступне звернення о '+B.clock(o.campaignReady)+'.':'На 45 хв, ціна −4 довіри. Потрібно щонайменше 35% довіри.';
B.cityMap.render(s);
}
B.opsUI={build,render,feedback};
})(globalThis.BD=globalThis.BD||{});
/* ui/report.js */
(function(B){
'use strict';
function buildResult(sim){const s=sim.snapshot();const m=s.metrics;const home=s.sectors.find(x=>x.id===s.home),mother=s.sectors.find(x=>x.id===s.mother);const meaningful=s.journal.filter(x=>['story','promise','debt','investigation','discipline','contact'].includes(x.kind));const stories=meaningful.filter(x=>x.kind==='story');const promises=meaningful.filter(x=>x.kind==='promise');const third=meaningful.filter(x=>['debt','investigation','discipline','contact'].includes(x.kind));const chronicle=[stories.at(-1),promises.at(-1),third.at(-1)||s.journal.findLast(x=>x.kind==='personal')].filter(Boolean);const baker=s.stories.find(x=>x.id==='baker');let episode=baker&&baker.state==='done'?'Хліб буде. За круасани не обіцяю.':m.completed?'Не всі плани вистояли. '+m.completed+' справи місто завершило.':'Термос у консьєржа. Чашку беріть свою.';return {version:B.VERSION,key:s.seed+':'+s.home+':'+s.mode+':'+B.VERSION,date:s.date,seed:s.seed,mode:s.mode,homeId:s.home,homeName:s.homeName,motherId:s.mother,score:m.score,rank:s.reason==='dismissed'?'Вас відсторонено від зміни':m.rank,metrics:m,homeDark:home.dark,motherDark:mother.dark,homeFair:home.fairEpisodes,homeTaken:home.fairTaken,personalCalls:s.personalCalls,chronicle,episode,investigation:s.investigation,supportMinutes:s.supportMinutes,medical:!!s.flags.medical,homeData:B.data.city.masyvy.find(x=>x.name===s.homeName)||B.data.city.masyvy.find(x=>x.homeSectorId===s.home),sectors:s.sectors.map(x=>({name:x.name,dark:x.dark})),endedAt:s.minute,completed:s.done,reason:s.reason};}
function render(host,r,actions){host.textContent='';const E=B.el;const hero=E('div','bd-report-hero');const intro=E('div');intro.append(E('p','bd-eyebrow',r.reason==='dismissed'?'ДОСТРОКОВЕ ЗВІЛЬНЕННЯ':'24:00 · ЗМІНА ЗАКІНЧИЛАСЬ'),E('h2','',r.rank));intro.querySelector('h2').id='bd-report-title';intro.append(E('p','bd-report-subtitle',r.reason==='dismissed'?'Потужність була, але місто лишалося без послуг. Після попереджень керування прийняв інший диспетчер.':'Місто прожило її по-різному. Ось що лишилося після твоїх рішень.'));const score=E('div','bd-score');score.append(E('strong','',String(r.score)),E('span','','ІЗ 100 БАЛІВ'));hero.append(intro,score);host.append(hero);
const stats=E('div','bd-report-stats');for(const [val,label] of [[B.duration(r.metrics.saidi),'Темрява середнього мешканця · SAIDI'],[r.metrics.saifi.toFixed(1),'Вимкнень на мешканця · SAIFI'],[String(r.metrics.completed),'Завершених справ'],[String(r.metrics.promisesKept),'Дотриманих вечірніх обіцянок']]){const el=E('div','bd-report-stat');el.append(E('strong','',val),E('small','',label));stats.append(el);}host.append(stats);
const factors=E('details','bd-report-section');factors.append(E('summary','','Як пораховано бал'));const f=E('div','bd-factor-list');for(const [id,label] of [['city','Міські служби'],['equality','Рівність болю'],['promise','Обіцянки'],['service','Без марної темряви'],['control','Керування мережею'],['steadiness','Спокійна ротація'],['integrity','Допоміжні резерви']]){const box=E('p');box.append(E('strong','',Math.round(r.metrics.factors[id]*100)+'%'),document.createTextNode(label));f.append(box);}factors.append(f,E('p','bd-note','Бал — добуток цих складників. Необхідна темрява сама по собі не є штрафом.'));host.append(factors);
const city=E('section','bd-report-section');city.append(E('h3','','Як працювало місто'));for(const item of r.metrics.cityServices||[])city.append(E('p','bd-personal-note',item.name+': '+B.duration(item.impact)+' зважених хвилин обмежень. У пік наслідки подвоюються.'));city.append(E('p','bd-personal-note','Виконано заявок бригади: '+(r.metrics.repairs||0)+'. Позик резерву: '+(r.metrics.loans||0)+'.'));host.append(city);
const personal=E('section','bd-report-section');personal.append(E('h3','','Твій дім. Решта міста.'));for(const [name,value] of [['Твій дім',r.homeDark],['Місто',r.metrics.saidi],['Мама',r.motherDark]]){const line=E('div','bd-personal-line');const bar=E('div');const fill=E('i');fill.style.width=B.clamp(value/1080*100,0,100)+'%';bar.append(fill);line.append(E('span','',name),bar,E('strong','',B.duration(value)));personal.append(line);}personal.append(E('p','bd-personal-note',r.homeName+': '+r.homeFair+' разів домашня ділянка була кандидатом під час твоїх перемикань; вимкнена в такому випадку '+r.homeTaken+' разів. Мама телефонувала '+r.personalCalls+' раз.'));if(r.investigation.stage)personal.append(E('p','bd-personal-note','Запит редакції: '+(r.investigation.response||'залишився без відповіді')+(r.investigation.kept===false?'. Обіцяну ротацію не виконано.':r.investigation.kept===true?'. Обіцяну ротацію виконано.':'.')));host.append(personal);
const story=E('section','bd-report-section');story.append(E('h3','','Хроніка твоєї зміни'));const chapters=E('div','bd-chronicle');const entries=r.chronicle.length?r.chronicle:[{minute:r.endedAt,text:r.episode}];for(const c of entries){const e=E('div','bd-chapter');e.append(E('time','',B.clock(c.minute)),E('p','',c.text));chapters.append(e);}story.append(chapters);if(r.supportMinutes>0)story.append(E('p','bd-personal-note','Пункти підтримки працювали сумарно '+B.duration(r.supportMinutes)+'. Кожна година роботи додавала довіри до диспетчера.'));host.append(story);
const share=E('section','bd-report-section');share.append(E('h3','','У кожного — своя історія'));const controls=E('div','bd-share-controls');let privateLabels=true;const privacy=B.button('Особисті мітки: показувати',()=>{privateLabels=!privateLabels;privacy.textContent='Особисті мітки: '+(privateLabels?'показувати':'приховати');privacy.setAttribute('aria-pressed',String(privateLabels));},'bd-btn bd-small');privacy.setAttribute('aria-pressed','true');controls.append(privacy,B.button('Зберегти PNG',()=>actions.share(r,privateLabels,true),'bd-btn bd-small'),B.button('Поділитись карткою ↗',()=>actions.share(r,privateLabels),'bd-btn bd-small'),B.button('Запросити на цю зміну',()=>actions.invite(r),'bd-btn bd-small'));share.append(controls);const best=B.store.load().bestByKey?.[r.key];share.append(E('p','bd-note','Режим: '+(r.mode==='reading'?'спокійний':'звичайний')+'. Найкращий результат цієї зміни: '+(best?.score??r.score)+'.'));host.append(share);
const utility=E('section','bd-report-section');utility.append(E('h3','','А тепер — про справжнє місто'));const cols=E('div','bd-utility');const left=E('div');const district=B.data.nezlamnist.districts.find(x=>x.slug===r.homeData?.districtSlug);if(district){left.append(E('p','',district.name+' район: '+district.count+' пунктів у зрізі, '+district.generator+' із генератором, '+district.heater+' з обігрівом.'));for(const p of district.points){const row=E('div','bd-utility-point');row.append(E('strong','',p.name),E('span','',p.address),E('span','',p.schedule));left.append(row);}}const map=E('a','','Перевірити пункти у своєму районі ↗');map.href='https://services.my-kiev.com/nezlamnist/';map.target='_blank';map.rel='noopener';left.append(map,E('p','bd-note','Дані: '+B.data.nezlamnist.updatedAt.slice(0,10)+'. Це добірка району, не найближчі до тебе адреси. Перед візитом перевір актуальний режим роботи.'));const right=E('div');right.append(E('p','','Ігрова черга не є твоєю справжньою чергою. Актуальні обмеження перевіряй у свого оператора.'));const link=E('a','','Офіційний сайт ДТЕК Київські електромережі ↗');link.href='https://www.dtek-kem.com.ua/ua';link.target='_blank';link.rel='noopener';right.append(link,E('p','bd-note','Автономність залежить від енергії батареї у Вт·год, споживання пристрою та втрат перетворення. Самих мА·год для оцінки часу недостатньо.'));right.append(E('p','',r.medical?'Важливу розмову збережено: гра не визначає порядок допомоги для електрозалежного медичного обладнання.':'Для питань щодо електрозалежного медичного обладнання потрібен окремий план із медичною командою; ігрові рішення не є інструкцією.'));const health=E('a','','Офіційні контакти МОЗ ↗');health.href='https://moz.gov.ua/uk/kontakti';health.target='_blank';health.rel='noopener';right.append(health);cols.append(left,right);utility.append(cols);host.append(utility);
}
B.report={buildResult,render};
})(globalThis.BD=globalThis.BD||{});
/* ui/share.js */
(function(B){
'use strict';
function canvas(r,personal){const c=document.createElement('canvas');c.width=1200;c.height=630;const x=c.getContext('2d');x.fillStyle='#faf7f0';x.fillRect(0,0,1200,630);x.fillStyle='#b93f35';x.font='18px sans-serif';x.fillText('МІЙ КИЇВ / ІНТЕРАКТИВНІ ІСТОРІЇ',60,60);x.font='bold 48px sans-serif';x.fillText('Блекаут-диспетчер',60,135);x.fillStyle='#1b1b1d';x.font='28px sans-serif';x.fillText(r.rank,60,188);x.font='bold 80px sans-serif';x.fillStyle='#b93f35';x.fillText(String(r.score),995,150);x.font='16px sans-serif';x.fillStyle='#6b6458';x.fillText('ІЗ 100',1005,181);const bars=personal?[['Твій дім',r.homeDark],['Місто',r.metrics.saidi],['Мама',r.motherDark]]:[['Середня темрява',r.metrics.saidi],['Завершено справ',r.metrics.completed*100]];bars.forEach(([label,value],i)=>{const y=265+i*70;x.fillStyle='#1b1b1d';x.font='20px sans-serif';x.fillText(label,60,y);x.fillStyle='#e4ddcf';x.fillRect(290,y-20,615,18);x.fillStyle=i===1?'#287249':'#b93f35';x.fillRect(290,y-20,615*B.clamp(value/1080,0,1),18);x.fillStyle='#1b1b1d';x.font='22px sans-serif';x.fillText(!personal&&i===1?String(r.metrics.completed):B.duration(value),940,y);});x.fillStyle='#b93f35';x.font='25px sans-serif';const phrase=r.episode;const words=phrase.split(' ');let line='',y=510;for(const word of words){if(x.measureText(line+word).width>1060){x.fillText(line,60,y);line='';y+=30;}line+=word+' ';}x.fillText(line,60,y);x.font='14px sans-serif';x.fillStyle='#6b6458';x.fillText('УМОВНА ЗИМА · '+r.date+' · '+(r.mode==='reading'?'СПОКІЙНИЙ РЕЖИМ':'ЗВИЧАЙНИЙ РЕЖИМ'),60,590);return c;}
function inviteUrl(r){const u=new URL(location.href);u.search='';u.hash='';u.searchParams.set('seed',String(r.seed));u.searchParams.set('v',B.VERSION);u.searchParams.set('mode',r.mode);return u.href;}
async function share(r,personal,downloadOnly){const c=canvas(r,personal);const blob=await new Promise(resolve=>c.toBlob(resolve,'image/png'));if(!blob)throw new Error('Не вдалося створити картку.');const file=new File([blob],'mii-kyiv-blackout.png',{type:'image/png'});if(!downloadOnly&&navigator.share&&navigator.canShare&&navigator.canShare({files:[file]})){try{await navigator.share({files:[file],title:'Моя зміна у Києві'});return 'shared';}catch(e){if(e.name==='AbortError')return 'cancelled';}}
const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download=file.name;document.body.append(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),60000);return 'downloaded';}
B.share={canvas,share,inviteUrl};
})(globalThis.BD=globalThis.BD||{});
/* ui/workspace.js */
(function(B){
'use strict';
if(typeof document==='undefined')return;
const root=document.getElementById('bdRoot');if(!root)return;
const sidebar=root.querySelector('.bd-sidebar');
const nav=B.el('nav','bd-workspace-nav');nav.setAttribute('aria-label','Панелі диспетчера');
const icons={resources:'M13 2 5 13h6l-1 9 9-13h-6z',people:'M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8M2 21v-3a7 7 0 0 1 14 0v3M17 4a4 4 0 0 1 0 7m2 4a6 6 0 0 1 3 6',plan:'M8 4H4v18h16V4h-4M8 2h8v5H8zM8 12h8M8 17h8',events:'M5 10a7 7 0 0 1 14 0v6l2 3H3l2-3zM9 22h6'};
function makeIcon(id){const icon=document.createElementNS('http://www.w3.org/2000/svg','svg');icon.setAttribute('viewBox','0 0 24 24');icon.setAttribute('class','bd-nav-icon');icon.setAttribute('aria-hidden','true');const path=document.createElementNS('http://www.w3.org/2000/svg','path');path.setAttribute('d',icons[id]);icon.append(path);return icon;}
const sections=[
['resources','Ресурси',['#bd-operations','.bd-services-panel','#bd-reserves']],
['people','Люди',['.bd-fold']],
['plan','План',['#bd-planning']],
['events','Події',['.bd-chat-panel','.bd-journal']]
];
const panels=[],buttons=[];
function activate(index){panels.forEach((panel,i)=>{panel.hidden=i!==index;buttons[i].setAttribute('aria-pressed',String(i===index));});}
sections.forEach(([id,name,selectors],index)=>{
const panel=B.el('section','bd-workspace-panel');panel.id='bd-workspace-'+id;panel.setAttribute('aria-label',name);
selectors.forEach(selector=>{const el=root.querySelector(selector);if(el){panel.append(el);if(el.tagName==='DETAILS')el.open=true;}});
if(id==='plan')panel.append(B.el('p','bd-plan-hint','Обіцянки світла на вечір стануть доступні під час зміни. Стеж за балансом і бережи запас потужності.'));
const button=B.button('',()=>activate(index),'bd-workspace-button');const icon=makeIcon(id);button.append(icon,B.el('span','',name));button.setAttribute('aria-controls',panel.id);
nav.append(button);sidebar.append(panel);panels.push(panel);buttons.push(button);
});
sidebar.prepend(nav);activate(1);
const phone=root.querySelector('.bd-phone-panel');root.querySelector('.bd-desk').append(phone);
})(globalThis.BD=globalThis.BD||{});
/* app.js */
(function(B){
'use strict';
if(typeof document==='undefined')return;
const root=document.getElementById('bdRoot');if(!root)return;
const $=id=>document.getElementById(id),E=B.el;
let paintStamp='';
let sim=null,screen='welcome',paused=false,dialog=false,returnFocus=null,real=0,lastFrame=0,lastPaint=0,lastSave=0,rows={},lastCall='',lastChat='',lastJournal='',lastPromises='',lastReserves='',lastTicker=0,result=null,lastStart=null,toastTimer=null;
const urlParams=new URLSearchParams(location.search);const local=location.protocol==='file:'||['127.0.0.1','localhost'].includes(location.hostname);const v1=local&&urlParams.get('events')==='0'&&urlParams.get('phone')==='0';
function show(name){screen=name;root.dataset.screen=name;for(const e of root.querySelectorAll('.bd-screen'))e.hidden=e.dataset.screen!==name;window.scrollTo({top:0,behavior:'instant'});}
function toast(text){$('bd-toast').textContent=text;$('bd-toast').hidden=false;clearTimeout(toastTimer);toastTimer=setTimeout(()=>$('bd-toast').hidden=true,5000);}
// WordPress strips form controls from stored HTML; create them after loading.
function mountControls(){$('bd-js-note').remove();root.querySelector('[role="dialog"]').setAttribute('aria-modal','true');for(const id of ['bd-home','bd-mode','bd-promise-sector']){const select=E('select');select.id=id;if(id==='bd-promise-sector')select.setAttribute('aria-label','Ділянка для обіцянки');$(id+'-mount').replaceWith(select);}for(const [value,label] of [['standard','Звичайний · 15 секунд на відповідь'],['reading','Спокійний · пауза під час розмов']]){const option=E('option','',label);option.value=value;$('bd-mode').append(option);}}
function populate(){mountControls();const saved=B.store.load();for(const m of B.data.city.masyvy){const o=E('option','',m.name);o.value=m.name;o.selected=m.name===saved.home;$('bd-home').append(o);}for(const s of B.data.grid.sectors){const o=E('option','',s.name);o.value=s.id;$('bd-promise-sector').append(o);}$('bd-mode').value=urlParams.get('mode')==='reading'?'reading':saved.mode||'standard';$('bd-resume').hidden=!saved.checkpoint||saved.checkpoint.version!==B.VERSION;}
function setup(){show('setup');$('bd-home').focus();}
function buildRows(){const host=$('bd-sectors');host.textContent='';rows={};for(const meta of B.data.grid.sectors){const row=E('div','bd-sector');row.dataset.sector=meta.id;const info=E('div');const head=E('div','bd-sector-head');const name=E('span','bd-sector-name',meta.name);name.append(E('kbd','bd-key',String((B.data.grid.sectors.indexOf(meta)+1)%10)));const tag=E('span','bd-person-tag');head.append(name,tag);const sub=E('div','bd-sector-meta');info.append(head,sub);const bars=E('div','bd-sector-bars');const numbers=E('div','bd-sector-numbers');const load=E('span'),dark=E('span');numbers.append(load,dark);const lightTrack=E('div','bd-mini-track'),lightFill=E('i'),darkTrack=E('div','bd-mini-track'),darkFill=E('i');lightTrack.append(lightFill);darkTrack.append(darkFill);bars.append(numbers,lightTrack,darkTrack);const button=B.button('',()=>act({type:'toggle',sectorId:meta.id}),'bd-toggle');const rocker=E('span','bd-rocker');rocker.setAttribute('aria-hidden','true');rocker.append(E('i','bd-rocker-grip'));const switchLabel=E('span','bd-switch-label','Світло');button.append(rocker,switchLabel);button.dataset.toggle=meta.id;button.setAttribute('aria-pressed','true');const task=E('div','bd-sector-task');const taskText=E('span'),taskTrack=E('span','bd-task-track'),taskFill=E('i');taskTrack.append(taskFill);task.append(taskText,taskTrack);const supportSlot=E('div','bd-support-slot');const support=B.button('Відкрити пункт · 3 МВт',()=>act({type:'support',sectorId:meta.id}),'bd-support-toggle');supportSlot.append(support);row.append(info,bars,button,task,supportSlot);host.append(row);rows[meta.id]={row,tag,sub,load,dark,lightFill,darkFill,button,switchLabel,task,taskText,taskFill,support,supportSlot};}}
function act(action){if(!sim||paused||dialog)return;if(action.type==='toggle')B.cityMap.select(action.sectorId);const r=sim.dispatch(action);if(!r.ok){render(true);toast(r.reason);$('bd-ticker').textContent=r.reason;}else {B.opsUI.feedback();render(true);const b=sim.balance(sim.state().minute);$('bd-ticker').textContent=b.room< -1?'Навантаження ще вище ліміту. Потрібна наступна черга.':sim.state().sectors.some(x=>!x.on)?'Баланс є. Не вимикай зайве: повертай світло, коли вистачає запасу, та міняй черги місцями.':'Усі черги зі світлом. Стеж за прогнозом.';}}
function start(options){const opts=options||{};const home=B.data.city.masyvy.find(m=>m.name===$('bd-home').value)||B.data.city.masyvy[0];const date=B.today();const sharedSeed=Number(urlParams.get('seed'));const seed=Number.isInteger(sharedSeed)&&sharedSeed>0?sharedSeed:B.hash(date);lastStart=opts.saved?{seed:opts.saved.seed,date:opts.saved.date,home:opts.saved.home,homeName:opts.saved.homeName,mode:opts.saved.mode}:{seed,date,home:home.homeSectorId,homeName:home.name,mode:$('bd-mode').value,...opts};sim=B.sim.create({...lastStart,...opts,events:!v1,phone:!v1,stories:!v1});real=(sim.state().minute-B.P.start)/B.P.minutesPerSecond;paused=false;dialog=false;lastFrame=0;lastCall='';acceptedCall='';lastChat='';lastJournal='';lastPromises='';lastReserves='';lastTicker=0;lastSave=0;buildRows();B.opsUI.build(sim,act);show('shift');$('bd-day-label').textContent=sim.state().date+' · '+(v1?'перевірка ядра':sim.state().mode==='reading'?'спокійний режим':'зміна дня');B.store.patch({home:sim.state().homeName,mode:sim.state().mode});if(!opts.saved){sim.say('Попередня зміна','Ліміт різко впав. Перевантаження вже на пульті. Приймай керування — відключай черги зараз.');sim.log('brief','Аварійне приймання: 8 секунд до захисного відключення. Негайно розвантаж мережу.');}render(true);$('bd-pause').focus();}
function isConversationPause(){return !!(sim&&sim.state().currentCall&&(sim.state().currentCall.serious||sim.state().mode==='reading'));}
function save(){if(sim&&!sim.state().done)B.store.patch({checkpoint:sim.serialize()});}
function advance(seconds){if(!sim||screen!=='shift'||paused||dialog||isConversationPause()||document.hidden)return;let left=Math.max(0,Number(seconds)||0);while(left>1e-8&&!sim.state().done&&!isConversationPause()){const dt=Math.min(left,1/6);sim.step(dt*B.P.minutesPerSecond);real+=dt;if(!v1)B.narrative.update(sim,dt);left-=dt;}if(sim.state().done)finish();}
function openDialog(help){if(screen!=='shift')return;returnFocus=document.activeElement;paused=true;dialog=true;$('bd-overlay').hidden=false;$('bd-map-credit').hidden=!help;$('bd-dialog-title').textContent=help?'Твої рішення тримають місто':'Час на ковток чаю';const host=$('bd-dialog-content');host.textContent='';if(help){const ul=E('ul');for(const text of ['Натисни район на карті, щоб вимкнути або повернути світло. Жовті вікна згасають, коли район знеструмлений. Навантаження має залишатися нижче позначки ліміту.','Щоб повернути світло одній ділянці, спочатку звільни місце в іншій. Міняй черги, не залишай одну в темряві надовго.','Дай справам мешканців безперервне вікно. Обіцянка — це відповідальність, а не додаткові очки.','Метро, воду й тепло можна обмежити: це звільняє потужність, але місто накопичує наслідки. Одна бригада виконує одну заявку за 30 хв. Позика повертається автоматично через зменшення ліміту. Пауза зупиняє все, включно з телефоном.'])ul.append(E('li','',text));host.append(ul);}else host.append(E('p','','Місто зачекає. Час зміни й телефон зупинені. Повернешся — продовжимо з цього ж моменту.'));$('bd-pause').textContent='▶ Продовжити';$('bd-dialog-close').focus();save();}
function closeDialog(){dialog=false;paused=false;$('bd-overlay').hidden=true;$('bd-pause').textContent='Ⅱ Пауза';lastFrame=performance.now();if(returnFocus&&returnFocus.isConnected)returnFocus.focus();else $('bd-pause').focus();}
let acceptedCall='';
function phoneCircle(){const circle=E('span','bd-call-circle');circle.setAttribute('aria-hidden','true');const icon=document.createElementNS('http://www.w3.org/2000/svg','svg');icon.setAttribute('viewBox','0 0 24 24');const path=document.createElementNS('http://www.w3.org/2000/svg','path');path.setAttribute('d','M6.62 10.79a15.1 15.1 0 0 0 6.59 6.59l2.2-2.2a1 1 0 0 1 1.02-.24c1.12.37 2.33.57 3.57.57a1 1 0 0 1 1 1V20a1 1 0 0 1-1 1C10.61 21 3 13.39 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.45.57 3.57a1 1 0 0 1-.25 1.02z');path.setAttribute('fill','currentColor');icon.append(path);circle.append(icon);return circle;}
function renderPhone(s){
const call=s.currentCall,accepted=!!call&&acceptedCall===call.id;
const key=call?call.id+':'+accepted:'empty';
if(key!==lastCall){lastCall=key;const host=$('bd-phone');host.textContent='';host.parentElement.classList.toggle('bd-call-alert',!!call);host.parentElement.classList.toggle('bd-call-connected',accepted);$('bd-phone-status').textContent=call?(accepted?'НА ЗВʼЯЗКУ':'ВХІДНИЙ ДЗВІНОК'):'НА ЗВʼЯЗКУ';
if(!call){host.textContent='';}
else {const e=E('div','bd-call');e.setAttribute('role','region');e.setAttribute('aria-label','Дзвінок: '+call.speaker);const island=E('div','bd-phone-island');island.setAttribute('aria-hidden','true');e.append(island,E('p','bd-call-kicker',accepted?'ОСОБИСТА ЛІНІЯ · РОЗМОВА':'МОБІЛЬНИЙ · ВХІДНИЙ ДЗВІНОК'));
const head=E('div','bd-call-head');const avatar=B.avatar(call.avatar);if(avatar.classList.contains('bd-avatar-fallback'))avatar.textContent=call.speaker.split(' ').slice(0,2).map(x=>x[0]).join('');head.append(avatar);const who=E('div');who.append(E('p','bd-call-name',call.speaker),E('p','bd-call-role',call.role));head.append(who);e.append(head);
const time=E('div','bd-call-time');time.id='bd-call-timer';e.append(time);
if(accepted){e.append(E('p','bd-call-text',call.text));call.choices.forEach((c,index)=>{const button=B.button('',()=>{if(paused||dialog)return;const reply=B.narrative.answer(sim,index);if(!reply.ok)toast(reply.reason);render(true);},'bd-call-choice');button.append(document.createTextNode(c.label),E('small','',c.detail));e.append(button);});}
else {e.append(E('p','bd-call-invitation','Місто має що тобі сказати.'));const controls=E('div','bd-call-actions');
if(!call.serious){const decline=B.button('',()=>{if(paused||dialog)return;B.narrative.answer(sim,-1);render(true);},'bd-call-control bd-decline');decline.setAttribute('aria-label','Відхилити дзвінок: −2 довіри, +3 ризику');decline.append(phoneCircle(),E('span','','Відхилити'));controls.append(decline);}
const accept=B.button('',()=>{if(paused||dialog)return;acceptedCall=call.id;render(true);$('bd-phone').querySelector('.bd-call-choice')?.focus();},'bd-call-control bd-accept');accept.append(phoneCircle(),E('span','','Прийняти'));controls.append(accept);e.append(controls);if(!call.serious)e.append(E('small','bd-decline-note','Пропуск: −2 довіри · +3 ризику'));}
e.append(E('div','bd-home-indicator'));host.append(e);}
}
if(call&&$('bd-call-timer'))$('bd-call-timer').textContent=call.serious||s.mode==='reading'?'Час гри призупинено':Math.ceil(call.left)+' с на відповідь';
}
function render(force){if(!sim||screen!=='shift')return;const state=sim.state();const stamp=state.minute+':'+state.currentCall?.id+':'+Math.ceil(state.currentCall?.left||0);if(!force&&stamp===paintStamp)return;paintStamp=stamp;const forecast=sim.balance(Math.min(B.P.end,state.minute+60));const s={...state,balance:sim.balance(state.minute),forecast};const v=B.reveal(s.minute,real);if(v1)Object.keys(v).forEach(k=>v[k]=true);const b=s.balance;const grace=s.minute<B.P.openingUntil?B.P.openingGrace:B.P.grace;const critical=b.room< -1;root.dataset.critical=String(critical);const seconds=Math.max(0,Math.ceil((grace-s.grace)/B.P.minutesPerSecond));$('bd-emergency').hidden=!critical;$('bd-emergency-title').textContent=s.minute<B.P.openingUntil?'АВАРІЙНЕ ПРИЙМАННЯ ЗМІНИ':'КРИТИЧНЕ ПЕРЕВАНТАЖЕННЯ';$('bd-emergency-count').textContent=seconds+' с';$('bd-emergency-task').textContent='Звільни '+Math.ceil(-b.room)+' МВт: вимкни райони або обмеж служби до втручання автоматики.';const max=Math.max(900,b.load,b.limit);$('bd-clock').textContent=B.clock(s.minute);$('bd-phase').textContent=s.minute<720?'Ранкова зміна':s.minute<1060?'Місто в русі':s.minute<1260?'Вечірній пік':'До кінця зміни';$('bd-hud').classList.toggle('bd-over',b.room< -1);$('bd-load-fill').style.width=b.load/max*100+'%';$('bd-limit-mark').style.left=b.limit/max*100+'%';$('bd-balance-label').textContent=v.numbers?Math.round(b.load)+' / '+Math.round(b.limit)+' МВт':b.room< -1?'Перебір потужності':'У межах ліміту';$('bd-energy-caption').textContent=v.numbers?(b.room< -1?'Звільни '+Math.ceil(-b.room)+' МВт':'Запас '+Math.floor(b.room)+' МВт'):b.room< -1?'Зменш навантаження до позначки':'Баланс є. Не вимикай зайве.';$('bd-forecast').textContent=v.numbers?'За годину: ліміт ≈ '+Math.round(s.forecast.limit)+' МВт':'Увімкнено — світиться';$('bd-lit-count').textContent=v.numbers?s.sectors.filter(x=>x.on).length+' / 10 зі світлом':b.room<0?'Потрібне рішення':'Баланс є';$('bd-city-caption').textContent=v.numbers?'Довіра до графіка: '+Math.round(s.trust)+'%':'Десять черг. Один ліміт.';
const notice=s.journal.filter(x=>x.kind!=='toggle').at(-1);
const longest=s.sectors.filter(x=>!x.on).sort((a,c)=>c.block-a.block)[0];
const restorable=s.sectors.find((x,i)=>!x.on&&b.loads[i]+(x.support?B.P.supportMw:0)<=b.room+1);
$('bd-ticker').textContent=!v.numbers?(b.room< -1?'Навантаження вище позначки. Вимкни одну чергу, щоб повернути баланс.':'Баланс є. Повертай світло, коли вистачає запасу.') :b.room< -1?'Звільни '+Math.ceil(-b.room)+' МВт. Знімай черги, доки навантаження не опуститься нижче ліміту.':restorable?'Є потужність повернути світло: '+restorable.name+'.':longest&&longest.block>110?longest.name+' без світла '+B.duration(longest.block)+'. Заплануй ротацію.':notice&&s.minute-notice.minute<20?B.clock(notice.minute)+' · '+notice.text:'Баланс є. Стеж за справами мешканців і прогнозом потужності.';
for(const x of s.sectors){const r=rows[x.id];if(!r.row.classList.contains('bd-selected'))continue;r.row.classList.toggle('bd-dark',!x.on);r.row.classList.toggle('bd-home',x.id===s.home);r.tag.textContent=x.id===s.home?'мій дім':x.id===s.mother?'мама':x.id===s.friend?'друг':'';r.tag.hidden=!r.tag.textContent;r.sub.textContent=x.on?'Під напругою':v.numbers?'Без світла · '+B.duration(x.block):'Без напруги';r.load.textContent=v.numbers?Math.round(b.loads[s.sectors.indexOf(x)])+' МВт':'';r.dark.textContent=v.numbers?B.duration(x.dark):'';r.lightFill.style.width=b.loads[s.sectors.indexOf(x)]/165*100+'%';r.darkFill.style.width=B.clamp(x.dark/Math.max(60,s.minute-360)*100,0,100)+'%';r.switchLabel.textContent=x.on?'УВІМК.':'ВИМК.';r.button.setAttribute('aria-pressed',String(x.on));r.button.setAttribute('aria-label',x.name+': '+(x.on?'зняти напругу':'подати напругу'));const task=s.stories.find(t=>t.sectorId===x.id&&t.state==='active');r.task.hidden=!task;if(task){r.taskText.textContent=task.title+' · ще '+Math.ceil(task.need-task.progress)+' хв · до '+B.clock(task.deadline);r.taskFill.style.width=task.progress/task.need*100+'%';}r.supportSlot.hidden=!v.support;r.support.textContent=x.support?(x.on?'Пункт працює · закрити':'Пункт без світла · закрити'):'Відкрити пункт · 3 МВт';r.support.setAttribute('aria-label',x.name+': '+r.support.textContent);r.support.setAttribute('aria-pressed',String(x.support));}
$('bd-planning').hidden=!v.promise;const promisesKey=JSON.stringify(s.promises);if(promisesKey!==lastPromises){lastPromises=promisesKey;const host=$('bd-promises');host.textContent='';const names={open:'обіцяно',kept:'дотримано',broken:'порушено',revised:'переглянуто'};for(const p of s.promises){const e=E('div','bd-promise-item');const text=E('div','',p.name);text.append(E('small','',B.clock(p.from)+'–'+B.clock(p.to)+' · '+names[p.state]));e.append(text);if(p.state==='open')e.append(B.button('Переглянути',()=>act({type:'revise',id:p.id}),'bd-text-btn'));host.append(e);}}
$('bd-reserves').hidden=!v.critical;const reserveKey=s.criticals.map(c=>Math.floor(c.fuel+(c.bonusFuel||0))+':'+c.failed+':'+s.sectors.find(x=>x.id===c.sectorId).on).join('|');if(reserveKey!==lastReserves){lastReserves=reserveKey;const host=$('bd-reserve-list');host.textContent='';for(const c of s.criticals){const on=s.sectors.find(x=>x.id===c.sectorId).on;const row=E('div','bd-reserve'+(c.fuel<60?' bd-low':''));row.append(E('span','',c.name),E('strong','',on?'Від мережі'+(c.bonusFuel?' · подарунок '+B.duration(c.bonusFuel):''):'Резерв '+B.duration(c.fuel+(c.bonusFuel||0))));host.append(row);}}
B.opsUI.render(s);renderPhone(s);const chatKey=s.chat.at(-1)?.id||0;if(chatKey!==lastChat){lastChat=chatKey;const host=$('bd-chat');const nearBottom=host.scrollHeight-host.scrollTop-host.clientHeight<70;host.textContent='';for(const c of s.chat.slice(-30)){const row=E('div','bd-message');const text=E('div','bd-message-content'),head=E('div','bd-message-head');head.append(E('span','',c.speaker),E('time','',B.clock(c.minute)));text.append(head,E('p','',c.text));row.append(B.avatar(c.avatar),text);host.append(row);}if(nearBottom)host.scrollTop=host.scrollHeight;}
const journalKey=s.journal.at(-1)?.id||0;if(journalKey!==lastJournal){lastJournal=journalKey;const host=$('bd-journal-list');host.textContent='';for(const j of s.journal.slice(-40).reverse())host.append(E('li','',B.clock(j.minute)+' · '+j.text));}
$('bd-shift-progress').style.width=(s.minute-360)/1080*100+'%';
}
function finish(){result=B.report.buildResult(sim);B.store.record(result);show('report');B.report.render($('bd-report-content'),result,{share:async(r,personal,downloadOnly)=>{try{const state=await B.share.share(r,personal,downloadOnly);if(state==='downloaded')toast('Картку збережено як PNG. Її можна надіслати у месенджер.');}catch(e){toast('Картку не вдалося зберегти. Спробуй ще раз.');}},invite:async r=>{const link=B.share.inviteUrl(r);try{await navigator.clipboard.writeText(link);toast('Посилання на цю зміну скопійовано.');}catch(e){const a=E('a','',link);a.href=link;$('bd-report-content').append(a);toast('Посилання додано під звітом.');}}});$('bd-report-title').tabIndex=-1;$('bd-report-title').focus();}
$('bd-play').addEventListener('click',setup);$('bd-back').addEventListener('click',()=>show('welcome'));$('bd-start').addEventListener('click',()=>start());$('bd-resume').addEventListener('click',()=>{const checkpoint=B.store.load().checkpoint;if(checkpoint)start({saved:checkpoint});});$('bd-pause').addEventListener('click',()=>dialog?closeDialog():openDialog(false));$('bd-help').addEventListener('click',()=>openDialog(true));$('bd-dialog-close').addEventListener('click',closeDialog);$('bd-promise').addEventListener('click',()=>act({type:'promise',sectorId:$('bd-promise-sector').value}));$('bd-replay').addEventListener('click',()=>start(lastStart));$('bd-new').addEventListener('click',setup);
for(const jump of root.querySelectorAll('[data-jump]'))jump.addEventListener('click',()=>{const target=$(jump.dataset.jump);target.scrollIntoView({behavior:'smooth',block:'center'});target.tabIndex=-1;target.focus({preventScroll:true});});
document.addEventListener('visibilitychange',()=>{if(document.hidden&&screen==='shift'&&!dialog)openDialog(false);});window.addEventListener('pagehide',save);document.addEventListener('keydown',e=>{if(screen==='shift'&&!paused&&!dialog&&!e.repeat&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&!['SELECT','INPUT','TEXTAREA'].includes(e.target.tagName)&&'1234567890'.includes(e.key)&&e.key.length===1){e.preventDefault();act({type:'toggle',sectorId:B.data.grid.sectors['1234567890'.indexOf(e.key)].id});}if(e.key==='Escape'&&screen==='shift'){e.preventDefault();dialog?closeDialog():openDialog(false);}if(dialog&&e.key==='Tab'){const buttons=[...$('bd-overlay').querySelectorAll('button,a,select')];if(e.shiftKey&&document.activeElement===buttons[0]){e.preventDefault();buttons.at(-1).focus();}else if(!e.shiftKey&&document.activeElement===buttons.at(-1)){e.preventDefault();buttons[0].focus();}}});
function frame(now){if(!lastFrame)lastFrame=now;const elapsed=(now-lastFrame)/1000;if(elapsed>=.1){lastFrame=now;advance(Math.min(.5,elapsed));}if(now-lastPaint>250){render();lastPaint=now;}if(now-lastSave>5000){save();lastSave=now;}requestAnimationFrame(frame);}
populate();show('welcome');requestAnimationFrame(frame);
B.app={start,advance,render,openDialog,closeDialog,getSim:()=>sim,getResult:()=>result,getScreen:()=>screen,isPaused:()=>paused||dialog||isConversationPause()};
})(globalThis.BD=globalThis.BD||{});