// ==UserScript== // @name KG_Latest_Games // @namespace klavogonki // @version 2.2.9 // @description Fast game creation buttons on all the pages // @match *://klavogonki.ru/* // @author Patcher // @icon https://www.google.com/s2/favicons?sz=64&domain=klavogonki.ru // ==/UserScript== (()=>{"use strict";var e={56:(e,t,a)=>{e.exports=function(e){var t=a.nc;t&&e.setAttribute("nonce",t)}},72:e=>{var t=[];function a(e){for(var a=-1,r=0;r{e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},314:e=>{e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var a="",r=void 0!==t[5];return t[4]&&(a+="@supports (".concat(t[4],") {")),t[2]&&(a+="@media ".concat(t[2]," {")),r&&(a+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),a+=e(t),r&&(a+="}"),t[2]&&(a+="}"),t[4]&&(a+="}"),a})).join("")},t.i=function(e,a,r,o,n){"string"==typeof e&&(e=[[null,e,void 0]]);var s={};if(r)for(var i=0;i0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=n),a&&(c[2]?(c[1]="@media ".concat(c[2]," {").concat(c[1],"}"),c[2]=a):c[2]=a),o&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=o):c[4]="".concat(o)),t.push(c))}},t}},540:e=>{e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},601:e=>{e.exports=function(e){return e[1]}},659:e=>{var t={};e.exports=function(e,a){var r=function(e){if(void 0===t[e]){var a=document.querySelector(e);if(window.HTMLIFrameElement&&a instanceof window.HTMLIFrameElement)try{a=a.contentDocument.head}catch(e){a=null}t[e]=a}return t[e]}(e);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(a)}},825:e=>{e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(a){!function(e,t,a){var r="";a.supports&&(r+="@supports (".concat(a.supports,") {")),a.media&&(r+="@media ".concat(a.media," {"));var o=void 0!==a.layer;o&&(r+="@layer".concat(a.layer.length>0?" ".concat(a.layer):""," {")),r+=a.css,o&&(r+="}"),a.media&&(r+="}"),a.supports&&(r+="}");var n=a.sourceMap;n&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(n))))," */")),t.styleTagTransform(r,e,t.options)}(t,e,a)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},911:(e,t,a)=>{a.d(t,{A:()=>i});var r=a(601),o=a.n(r),n=a(314),s=a.n(n)()(o());s.push([e.id,'.vocabulary-types-popup,.game-migration-popup,.vocabulary-creation-popup,.game-popup{position:fixed;display:flex;flex-direction:column;gap:5px;padding:5px;background-color:var(--rg-bg-primary);border:1px solid var(--rg-border-primary);border-radius:8px !important;box-shadow:0 2px 10px rgba(0,0,0,.1) !important;max-height:50vh;overflow-y:auto;scrollbar-width:none;z-index:2000;user-select:none}.vocabulary-types-popup .popup-header,.game-migration-popup .popup-header,.vocabulary-creation-popup .popup-header,.game-popup .popup-header{display:inline-flex;padding:6px;justify-content:space-between;align-items:center}.vocabulary-types-popup .popup-header-title,.game-migration-popup .popup-header-title,.vocabulary-creation-popup .popup-header-title,.game-popup .popup-header-title{font:600 14px "Montserrat",sans-serif;color:var(--rg-header-text);min-width:80px}.vocabulary-types-popup .popup-header-badge,.game-migration-popup .popup-header-badge,.vocabulary-creation-popup .popup-header-badge,.game-popup .popup-header-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;margin:0 8px;border-radius:4px !important;border:1.5px solid var(--rg-border-primary);background:var(--rg-bg-card);font:600 11px "Montserrat",sans-serif;white-space:nowrap;color:var(--rg-text-secondary);user-select:none;flex-shrink:0}.vocabulary-types-popup .popup-header-badge--voc,.game-migration-popup .popup-header-badge--voc,.vocabulary-creation-popup .popup-header-badge--voc,.game-popup .popup-header-badge--voc{color:var(--rg-gametype-voc);background:var(--rg-bg-card-pinned-voc);border-color:var(--rg-border-pinned-voc)}.vocabulary-types-popup .popup-header-badge--normal,.game-migration-popup .popup-header-badge--normal,.vocabulary-creation-popup .popup-header-badge--normal,.game-popup .popup-header-badge--normal{color:var(--rg-gametype-normal);background:var(--rg-bg-card-pinned-normal);border-color:var(--rg-border-pinned-normal)}.vocabulary-types-popup .popup-header-badge--abra,.game-migration-popup .popup-header-badge--abra,.vocabulary-creation-popup .popup-header-badge--abra,.game-popup .popup-header-badge--abra{color:var(--rg-gametype-abra);background:var(--rg-bg-card-pinned-abra);border-color:var(--rg-border-pinned-abra)}.vocabulary-types-popup .popup-header-badge--noerror,.game-migration-popup .popup-header-badge--noerror,.vocabulary-creation-popup .popup-header-badge--noerror,.game-popup .popup-header-badge--noerror{color:var(--rg-gametype-noerror);background:var(--rg-bg-card-pinned-noerror);border-color:var(--rg-border-pinned-noerror)}.vocabulary-types-popup .popup-header-badge--marathon,.game-migration-popup .popup-header-badge--marathon,.vocabulary-creation-popup .popup-header-badge--marathon,.game-popup .popup-header-badge--marathon{color:var(--rg-gametype-marathon);background:var(--rg-bg-card-pinned-marathon);border-color:var(--rg-border-pinned-marathon)}.vocabulary-types-popup .popup-header-badge--chars,.game-migration-popup .popup-header-badge--chars,.vocabulary-creation-popup .popup-header-badge--chars,.game-popup .popup-header-badge--chars{color:var(--rg-gametype-chars);background:var(--rg-bg-card-pinned-chars);border-color:var(--rg-border-pinned-chars)}.vocabulary-types-popup .popup-header-badge--digits,.game-migration-popup .popup-header-badge--digits,.vocabulary-creation-popup .popup-header-badge--digits,.game-popup .popup-header-badge--digits{color:var(--rg-gametype-digits);background:var(--rg-bg-card-pinned-digits);border-color:var(--rg-border-pinned-digits)}.vocabulary-types-popup .popup-header-badge--sprint,.game-migration-popup .popup-header-badge--sprint,.vocabulary-creation-popup .popup-header-badge--sprint,.game-popup .popup-header-badge--sprint{color:var(--rg-gametype-sprint);background:var(--rg-bg-card-pinned-sprint);border-color:var(--rg-border-pinned-sprint)}.vocabulary-types-popup .popup-header-badge-chip,.game-migration-popup .popup-header-badge-chip,.vocabulary-creation-popup .popup-header-badge-chip,.game-popup .popup-header-badge-chip{display:inline-flex;align-items:center;padding:1px 5px;border-radius:3px !important;background:var(--rg-hover-mix-color);font:500 10px "Montserrat",sans-serif;color:inherit;opacity:.85}.vocabulary-types-popup .popup-header-badge-chip--private,.game-migration-popup .popup-header-badge-chip--private,.vocabulary-creation-popup .popup-header-badge-chip--private,.game-popup .popup-header-badge-chip--private{background:var(--rg-bg-card-pinned-digits);border:1px solid var(--rg-border-pinned-digits);color:var(--rg-gametype-digits);opacity:1}.vocabulary-types-popup .popup-header-badge-chip--removed,.game-migration-popup .popup-header-badge-chip--removed,.vocabulary-creation-popup .popup-header-badge-chip--removed,.game-popup .popup-header-badge-chip--removed{background:var(--rg-bg-card-pinned-marathon);border:1px solid var(--rg-border-pinned-marathon);color:var(--rg-gametype-marathon);opacity:1}.vocabulary-types-popup .popup-header-controls,.game-migration-popup .popup-header-controls,.vocabulary-creation-popup .popup-header-controls,.game-popup .popup-header-controls{display:flex;gap:8px;align-items:center}.vocabulary-types-popup .popup-header-qualification,.game-migration-popup .popup-header-qualification,.vocabulary-creation-popup .popup-header-qualification,.game-popup .popup-header-qualification{display:flex;align-items:center;justify-content:center;width:16px;height:16px;cursor:pointer}.vocabulary-types-popup .popup-header-save,.game-migration-popup .popup-header-save,.vocabulary-creation-popup .popup-header-save,.game-popup .popup-header-save{display:flex;align-items:center;justify-content:center;width:16px;height:16px;cursor:pointer}.vocabulary-types-popup .popup-header-save svg,.game-migration-popup .popup-header-save svg,.vocabulary-creation-popup .popup-header-save svg,.game-popup .popup-header-save svg{transform-origin:center}.vocabulary-types-popup .rg-rotate,.game-migration-popup .rg-rotate,.vocabulary-creation-popup .rg-rotate,.game-popup .rg-rotate{animation:rg-rotate .6s ease}@keyframes rg-rotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.vocabulary-types-popup .popup-subheader,.game-migration-popup .popup-subheader,.vocabulary-creation-popup .popup-subheader,.game-popup .popup-subheader{font:600 14px "Montserrat",sans-serif;color:var(--rg-text-secondary);padding:6px}.vocabulary-types-popup .timeouts-container,.vocabulary-types-popup .idle-times-container,.game-migration-popup .timeouts-container,.game-migration-popup .idle-times-container,.vocabulary-creation-popup .timeouts-container,.vocabulary-creation-popup .idle-times-container,.game-popup .timeouts-container,.game-popup .idle-times-container{display:flex;width:320px;flex-direction:row;flex-wrap:wrap;gap:5px}.vocabulary-types-popup .timeouts-container .game-popup-button,.vocabulary-types-popup .idle-times-container .game-popup-button,.game-migration-popup .timeouts-container .game-popup-button,.game-migration-popup .idle-times-container .game-popup-button,.vocabulary-creation-popup .timeouts-container .game-popup-button,.vocabulary-creation-popup .idle-times-container .game-popup-button,.game-popup .timeouts-container .game-popup-button,.game-popup .idle-times-container .game-popup-button{display:inline-block;padding:5px 15px;font:600 14px "Montserrat",sans-serif;border-radius:4px !important;background:var(--rg-bg-card) !important;color:var(--rg-text-primary) !important;border:1.5px solid var(--rg-border-primary);cursor:pointer;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;text-decoration:none}.vocabulary-types-popup .timeouts-container .game-popup-button:hover,.vocabulary-types-popup .timeouts-container .game-popup-button:focus,.vocabulary-types-popup .idle-times-container .game-popup-button:hover,.vocabulary-types-popup .idle-times-container .game-popup-button:focus,.game-migration-popup .timeouts-container .game-popup-button:hover,.game-migration-popup .timeouts-container .game-popup-button:focus,.game-migration-popup .idle-times-container .game-popup-button:hover,.game-migration-popup .idle-times-container .game-popup-button:focus,.vocabulary-creation-popup .timeouts-container .game-popup-button:hover,.vocabulary-creation-popup .timeouts-container .game-popup-button:focus,.vocabulary-creation-popup .idle-times-container .game-popup-button:hover,.vocabulary-creation-popup .idle-times-container .game-popup-button:focus,.game-popup .timeouts-container .game-popup-button:hover,.game-popup .timeouts-container .game-popup-button:focus,.game-popup .idle-times-container .game-popup-button:hover,.game-popup .idle-times-container .game-popup-button:focus{border-color:var(--rg-border-hover);background:var(--rg-bg-hover);color:var(--rg-text-primary)}.vocabulary-types-popup .group-tab,.vocabulary-types-popup .popup-button,.game-migration-popup .group-tab,.game-migration-popup .popup-button,.vocabulary-creation-popup .group-tab,.vocabulary-creation-popup .popup-button,.game-popup .group-tab,.game-popup .popup-button{display:inline-flex;padding:5px 15px;min-height:30px;max-width:300px;font:600 14px "Montserrat",sans-serif;border-radius:4px !important;background:var(--rg-bg-card);color:var(--rg-text-primary);border:2px solid var(--rg-border-primary);cursor:pointer;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:fit-content;transition:border .1s ease,background-color .1s ease}.vocabulary-types-popup .group-tab:hover,.vocabulary-types-popup .group-tab:focus,.vocabulary-types-popup .popup-button:hover,.vocabulary-types-popup .popup-button:focus,.game-migration-popup .group-tab:hover,.game-migration-popup .group-tab:focus,.game-migration-popup .popup-button:hover,.game-migration-popup .popup-button:focus,.vocabulary-creation-popup .group-tab:hover,.vocabulary-creation-popup .group-tab:focus,.vocabulary-creation-popup .popup-button:hover,.vocabulary-creation-popup .popup-button:focus,.game-popup .group-tab:hover,.game-popup .group-tab:focus,.game-popup .popup-button:hover,.game-popup .popup-button:focus{border-color:var(--rg-border-hover);background:var(--rg-bg-hover);color:var(--rg-text-primary)}.vocabulary-types-popup .group-tab.active,.vocabulary-types-popup .popup-button.active,.game-migration-popup .group-tab.active,.game-migration-popup .popup-button.active,.vocabulary-creation-popup .group-tab.active,.vocabulary-creation-popup .popup-button.active,.game-popup .group-tab.active,.game-popup .popup-button.active{color:var(--rg-gametype-normal) !important;background-color:var(--rg-bg-card-pinned-normal) !important;border:2px solid var(--rg-border-pinned-normal) !important}.vocabulary-types-popup .group-tab.warning,.vocabulary-types-popup .popup-button.warning,.game-migration-popup .group-tab.warning,.game-migration-popup .popup-button.warning,.vocabulary-creation-popup .group-tab.warning,.vocabulary-creation-popup .popup-button.warning,.game-popup .group-tab.warning,.game-popup .popup-button.warning{color:var(--rg-gametype-chars) !important;background-color:var(--rg-bg-card-pinned-chars) !important;border:2px solid var(--rg-border-pinned-chars) !important}.vocabulary-types-popup .group-tab.danger,.vocabulary-types-popup .popup-button.danger,.game-migration-popup .group-tab.danger,.game-migration-popup .popup-button.danger,.vocabulary-creation-popup .group-tab.danger,.vocabulary-creation-popup .popup-button.danger,.game-popup .group-tab.danger,.game-popup .popup-button.danger{color:var(--rg-gametype-marathon) !important;background-color:var(--rg-bg-card-pinned-marathon) !important;border:2px solid var(--rg-border-pinned-marathon) !important}.vocabulary-types-popup .rank-slider-container,.game-migration-popup .rank-slider-container,.vocabulary-creation-popup .rank-slider-container,.game-popup .rank-slider-container{display:flex;flex-direction:column;align-items:stretch;margin:6px}.vocabulary-types-popup .rank-slider-container .rank-slider-display,.game-migration-popup .rank-slider-container .rank-slider-display,.vocabulary-creation-popup .rank-slider-container .rank-slider-display,.game-popup .rank-slider-container .rank-slider-display{margin:0 0 12px;font:600 14px "Montserrat",sans-serif;color:var(--rg-text-secondary)}.vocabulary-types-popup .rank-slider-container .rank-slider-track,.game-migration-popup .rank-slider-container .rank-slider-track,.vocabulary-creation-popup .rank-slider-container .rank-slider-track,.game-popup .rank-slider-container .rank-slider-track{position:relative;height:8px;background:var(--rg-rank-slider-track-bg);border-radius:4px !important;cursor:pointer;border:2px solid var(--rg-rank-slider-border);box-sizing:border-box}.vocabulary-types-popup .rank-slider-container .rank-slider-range,.game-migration-popup .rank-slider-container .rank-slider-range,.vocabulary-creation-popup .rank-slider-container .rank-slider-range,.game-popup .rank-slider-container .rank-slider-range{position:absolute;height:100%;background:var(--rg-rank-slider-range);border-radius:4px !important;z-index:1}.vocabulary-types-popup .rank-slider-container .rank-slider-handle,.game-migration-popup .rank-slider-container .rank-slider-handle,.vocabulary-creation-popup .rank-slider-container .rank-slider-handle,.game-popup .rank-slider-container .rank-slider-handle{position:absolute;top:50%;width:18px;height:18px;background:var(--rg-rank-slider-handle-bg);border:2px solid var(--rg-rank-slider-border);border-radius:50% !important;transform:translate(-50%, -50%);z-index:2;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,.08) !important;transition:border-color .2s,background .2s}.vocabulary-types-popup .rank-slider-container .rank-slider-handle:focus,.game-migration-popup .rank-slider-container .rank-slider-handle:focus,.vocabulary-creation-popup .rank-slider-container .rank-slider-handle:focus,.game-popup .rank-slider-container .rank-slider-handle:focus{outline:none;border-color:var(--rg-rank-slider-border-focus)}.vocabulary-types-popup .rank-slider-container .rank-slider-handle.overlap-left,.game-migration-popup .rank-slider-container .rank-slider-handle.overlap-left,.vocabulary-creation-popup .rank-slider-container .rank-slider-handle.overlap-left,.game-popup .rank-slider-container .rank-slider-handle.overlap-left{transform:translate(-100%, -50%)}.vocabulary-types-popup .rank-slider-container .rank-slider-handle.overlap-right,.game-migration-popup .rank-slider-container .rank-slider-handle.overlap-right,.vocabulary-creation-popup .rank-slider-container .rank-slider-handle.overlap-right,.game-popup .rank-slider-container .rank-slider-handle.overlap-right{transform:translate(0, -50%)}.latest-games-search-container{position:relative;margin:10px 10px 0;display:flex;flex-direction:row;align-items:center}.latest-games-search-container.latest-games-hidden{display:none}.latest-games-search-container #latest-games-search-input{width:100%;box-sizing:border-box;padding:8px 12px;font-size:15px;font-family:"Montserrat",sans-serif;border:1.5px solid var(--rg-border-primary);border-radius:6px !important;background:var(--rg-bg-card);color:var(--rg-text-primary);outline:none;transition:border-color .2s,background .2s,color .2s}.latest-games-search-container #latest-games-search-input:focus{border-color:var(--rg-border-hover);background:var(--rg-bg-hover);color:var(--rg-text-primary)}.latest-games-search-container .latest-games-clear-btn{position:absolute;top:50%;transform:translateY(-50%);width:24px;height:24px;border:none;outline:none;cursor:pointer;display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity .15s ease;z-index:1}.latest-games-search-container .latest-games-clear-btn svg{width:14px;height:14px}.latest-games-search-container .latest-games-clear-btn.visible{opacity:1;visibility:visible}.latest-games-search-noresults{display:inline-flex;padding:5px 15px;max-width:300px;font:500 14px "Montserrat",sans-serif;border-radius:4px !important;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:auto;justify-content:center;align-items:center;color:var(--rg-gametype-marathon);border:2px solid var(--rg-border-pinned-marathon);background-color:var(--rg-bg-card-pinned-marathon)}.latest-games-search-more{display:inline-flex;padding:5px 15px;max-width:300px;font:500 14px "Montserrat",sans-serif;border-radius:4px !important;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:auto;justify-content:center;align-items:center;color:var(--rg-gametype-chars);border:2px solid var(--rg-border-pinned-chars);background-color:var(--rg-bg-card-pinned-chars);cursor:pointer}.games-data-container .indicator{transition:.2s ease-in-out;font-family:"Montserrat",sans-serif;font-size:1.5em;font-weight:500;font-variant-numeric:tabular-nums;padding:8px;display:flex;justify-content:flex-start;align-items:center;cursor:default;border-radius:.2em !important;height:fit-content}.games-data-container{position:fixed;display:flex;flex-direction:row;top:50px;right:5px;gap:5px;user-select:none;z-index:2000}.games-data-container .period-indicators-container{display:flex;flex-direction:row;gap:5px}.games-data-container .period-indicators-container .period-indicator-description{padding-right:5px;font-family:"Montserrat",sans-serif;font-size:.5em;font-weight:600;text-transform:uppercase}.games-data-container .sleep-start-indicator,.games-data-container .sleep-replay-indicator{animation:bounceIn .3s ease forwards}.games-data-container .sleep-start-indicator{color:hsl(88,50%,55%);background-color:hsl(88,40%,20%);border:1px solid hsl(88,45%,35%);cursor:pointer}.games-data-container .sleep-start-indicator:hover{background-color:hsl(88,40%,27%);border-color:hsl(88,45%,50%)}.games-data-container .sleep-replay-indicator{color:hsl(208,50%,70%);background-color:hsl(208,40%,25%);border:1px solid hsl(208,45%,50%);cursor:pointer}.games-data-container .sleep-replay-indicator:hover{background-color:hsl(208,40%,32%);border-color:hsl(208,45%,65%)}.games-data-container .sleep-indicator-paused{opacity:.6;filter:saturate(0.4);animation:pulse 1.4s ease-in-out infinite}@keyframes pulse{0%,100%{opacity:.6}50%{opacity:.35}}.games-data-container .sleep-indicator-dismissing{animation:bounceOut .3s ease forwards !important}@keyframes bounceOut{0%{opacity:1;transform:scale(1)}40%{opacity:.6;transform:scale(0.92)}100%{opacity:0;transform:scale(0.85)}}@keyframes bounceIn{0%{opacity:0;transform:scale(0.85)}60%{opacity:1;transform:scale(1.05)}100%{opacity:1;transform:scale(1)}}.games-data-container .remaining-count-indicator{color:hsl(50,0%,75%);background-color:hsl(50,0%,15%);border:1px solid hsl(50,0%,30%)}.games-data-container .today-play-count-indicator{color:hsl(30,60%,65%);background-color:hsl(30,45%,20%);border:1px solid #963;cursor:pointer}.games-data-container .week-play-count-indicator{color:hsl(150,60%,65%);background-color:hsl(150,45%,20%);border:1px solid #396}.games-data-container .month-play-count-indicator{color:hsl(340,55%,65%);background-color:hsl(340,40%,20%);border:1px solid hsl(340,45%,40%)}.games-data-container .year-play-count-indicator{color:hsl(200,55%,65%);background-color:hsl(200,40%,20%);border:1px solid hsl(200,45%,40%)}.games-data-container .playlist-progress-indicator{border:1px solid;color:hsl(135,45%,65%);background-color:hsl(135,45%,20%);border-color:hsl(135,45%,40%);animation:bounceIn .3s ease forwards;padding:0;gap:0;overflow:hidden;cursor:default}.games-data-container .playlist-progress-indicator .playlist-hud-btn{color:hsl(135,45%,65%)}.games-data-container .playlist-progress-indicator .playlist-hud-btn:hover{background-color:hsl(135,45%,30%)}.games-data-container .playlist-progress-indicator .playlist-hud-btn:active{background-color:hsl(135,45%,35%)}.games-data-container .playlist-progress-indicator--paused{color:hsl(40,60%,65%);background-color:hsl(40,60%,20%);border-color:hsl(40,60%,40%);animation:bounceIn .3s ease forwards,hudPause 2s ease-in-out .3s infinite}.games-data-container .playlist-progress-indicator--paused .playlist-hud-btn{color:hsl(40,60%,65%)}.games-data-container .playlist-progress-indicator--paused .playlist-hud-btn:hover{background-color:hsl(40,60%,30%)}.games-data-container .playlist-progress-indicator--paused .playlist-hud-btn:active{background-color:hsl(40,60%,35%)}@keyframes hudPause{0%,100%{opacity:1}50%{opacity:.55}}.games-data-container .playlist-progress-indicator .playlist-hud-btn{display:inline-flex;align-items:center;justify-content:center;align-self:stretch;padding:0 7px;flex-shrink:0;background:rgba(0,0,0,0);border:none;outline:none;cursor:pointer;transition:background .15s ease}.games-data-container .playlist-progress-indicator .playlist-hud-btn svg{width:16px;height:16px;pointer-events:none;flex-shrink:0}.games-data-container .playlist-progress-indicator .playlist-hud-data{cursor:pointer;padding:8px}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-counter{font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:3px}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-counter svg{width:14px;height:14px;flex-shrink:0;pointer-events:none}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-reps{font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:3px;font-size:.72em;font-weight:600;align-self:stretch}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-reps svg{width:14px;height:14px;flex-shrink:0;pointer-events:none}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-cycles{font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:3px;font-size:.72em;font-weight:600;align-self:stretch}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-cycles svg{width:14px;height:14px;flex-shrink:0;pointer-events:none}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-shuffle{font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:3px;font-size:.72em;font-weight:600;align-self:stretch}.games-data-container .playlist-progress-indicator .playlist-hud-data .playlist-hud-shuffle svg{width:14px;height:14px;flex-shrink:0;pointer-events:none}.games-data-container .period-indicator:not(.show){display:none !important}.games-data-container .period-indicator.show{display:flex !important;animation:fallDown 320ms cubic-bezier(0.22, 0.9, 0.31, 1) both;animation-delay:var(--fall-delay, 0ms)}@keyframes fallDown{0%{transform:translateY(-20px) scaleY(0.98);opacity:0}100%{transform:translateY(0) scaleY(1);opacity:1}}.vocabulary-tooltip-popup{font:500 14px "Montserrat",sans-serif;position:fixed;background:var(--rg-bg-primary);color:var(--rg-text-primary);padding:0;z-index:1200;font-size:.9em;pointer-events:auto;white-space:pre-wrap;border:1px solid var(--rg-border-primary) !important;border-radius:4px !important;box-shadow:0 2px 5px rgba(0,0,0,.3) !important;max-width:700px;width:auto;max-height:80vh;overflow:hidden;word-wrap:break-word;overflow-wrap:break-word}.vocabulary-tooltip-popup .tooltip-header{padding:12px 16px;background:var(--rg-bg-secondary)}.vocabulary-tooltip-popup .tooltip-header .tooltip-author{display:flex;align-items:center;margin-bottom:10px;gap:10px}.vocabulary-tooltip-popup .tooltip-header .tooltip-author .tooltip-avatar{width:32px;height:32px;border-radius:.4rem;object-fit:contain;background:var(--rg-bg-tertiary);border:1px solid var(--rg-border-secondary)}.vocabulary-tooltip-popup .tooltip-header .tooltip-author .tooltip-author-name{font-weight:600;font-size:1.1em;color:var(--rg-text-primary);text-decoration:none}.vocabulary-tooltip-popup .tooltip-header .tooltip-author .tooltip-author-name:is(a):hover{text-decoration:underline}.vocabulary-tooltip-popup .tooltip-header .tooltip-title{font-size:1.1em;font-weight:600;margin-bottom:10px;line-height:1.3}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating{display:flex;align-items:center;gap:6px;margin-bottom:10px;font-size:1em}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .stars-container{position:relative;display:inline-grid;line-height:1}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .stars-container .stars-bg,.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .stars-container .stars-filled{grid-area:1/1;font-size:16px;line-height:1;letter-spacing:2px}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .stars-container .stars-bg{filter:grayscale(100%);opacity:.4}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .stars-container .stars-filled{overflow:hidden;white-space:nowrap}.vocabulary-tooltip-popup .tooltip-header .tooltip-rating .rating-count{color:var(--rg-text-secondary)}.vocabulary-tooltip-popup .tooltip-header .tooltip-users,.vocabulary-tooltip-popup .tooltip-header .tooltip-meta{color:var(--rg-text-secondary);margin-bottom:6px}.vocabulary-tooltip-popup .tooltip-header .tooltip-description{color:var(--rg-text-tertiary);margin-bottom:6px;line-height:1.4}.vocabulary-tooltip-popup .tooltip-header .tooltip-stats{font-size:.85em;color:var(--rg-text-tertiary);margin-bottom:6px;font-style:italic}.vocabulary-tooltip-popup .tooltip-header .tooltip-version{font-size:.8em;color:var(--rg-text-tertiary);font-style:italic}.vocabulary-tooltip-popup .tooltip-divider{height:1px;background:var(--rg-border-primary);margin:0}.vocabulary-tooltip-popup .tooltip-content{padding:12px 16px;white-space:pre-wrap}.vocabulary-tooltip-popup .tooltip-content .tooltip-number{color:var(--rg-text-secondary);opacity:.5;font-weight:400}.vocabulary-tooltip-popup .tooltip-tabs{display:flex;border-bottom:1px solid var(--rg-border-primary);background:var(--rg-bg-secondary);flex-shrink:0}.vocabulary-tooltip-popup .tooltip-tabs .tooltip-tab{flex:1;padding:8px 12px;font:inherit;font-size:.85em;font-weight:600;background:none;border:none;color:var(--rg-text-secondary);cursor:pointer;border-bottom:2px solid rgba(0,0,0,0);transition:color .15s,border-color .15s}.vocabulary-tooltip-popup .tooltip-tabs .tooltip-tab.active{color:var(--rg-text-primary);border-bottom-color:var(--rg-text-primary)}.vocabulary-tooltip-popup .tooltip-tabs .tooltip-tab:hover:not(.active){color:var(--rg-text-primary);background:var(--rg-bg-tertiary)}.vocabulary-tooltip-popup .tooltip-tabs .tooltip-tab .tooltip-tab-count{display:inline-block;font-size:.8em;background:var(--rg-border-primary);border-radius:8px;padding:0 5px;margin-left:3px}.vocabulary-tooltip-popup .tooltip-body{display:flex;flex-direction:row;overflow:hidden;flex:1;min-height:0}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane{overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:hsl(0,0%,35%) rgba(0,0,0,0)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane::-webkit-scrollbar{width:8px;height:8px}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane::-webkit-scrollbar-thumb{background-color:hsl(0,0%,35%);border-radius:3px}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane::-webkit-scrollbar-thumb:hover{background-color:hsl(0,0%,55%)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane::-webkit-scrollbar-thumb:active{background-color:hsl(0,0%,65%)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--content{flex:1 1 auto;min-width:0}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments{flex:0 0 260px;border-left:1px solid var(--rg-border-primary);background:var(--rg-bg-secondary)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment{padding:10px 14px;border-bottom:1px solid var(--rg-border-primary)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment:last-child{border-bottom:none}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-meta{display:flex;align-items:center;gap:6px;margin-bottom:5px;flex-wrap:wrap}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-meta .tooltip-comment-avatar{width:22px;height:22px;border-radius:.4rem}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-meta .tooltip-comment-author{font-weight:600;font-size:.85em;color:var(--rg-text-primary);text-decoration:none}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-meta .tooltip-comment-author:hover{text-decoration:underline}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-meta .tooltip-comment-date{font-size:.78em;color:var(--rg-text-tertiary);margin-left:auto}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text{font-size:.88em;line-height:1.45;word-break:break-word}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-comment-img{display:block;max-width:100%;height:auto;border-radius:4px;margin-top:6px}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text a{color:var(--rg-text-primary);text-decoration:underline;opacity:.75}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text a:hover{opacity:1}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler{margin-top:6px}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler summary{display:inline-flex;align-items:center;gap:5px;padding:.3em .7em;background:var(--rg-bg-card);color:hsla(38,80%,55%,.9);border:1px solid hsla(38,80%,55%,.5);border-radius:3px !important;font-size:.82em;font-weight:500;cursor:pointer;user-select:none;list-style:none;transition:background .15s,border-color .15s}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler summary::-webkit-details-marker{display:none}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler summary::before{content:"▶";font-size:.7em;transition:transform .15s}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler summary:hover{background:hsla(38,80%,55%,.15);border-color:hsla(38,80%,55%,.8)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler[open] summary::before{transform:rotate(90deg)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler[open] summary{margin-bottom:6px}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-spoiler .tooltip-spoiler-body{display:block;margin-top:4px;padding:6px 10px;background:hsla(38,80%,55%,.08);border-left:3px solid hsla(38,80%,55%,.55);border-radius:2px;color:var(--rg-text-secondary)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-quote-label{margin-top:6px;font-size:.8em;font-weight:600;font-style:italic;color:var(--rg-text-tertiary)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments .tooltip-comment .tooltip-comment-text .tooltip-quote{margin-top:2px;padding:6px 10px;background:hsla(var(--rg-popup-item-new)/0.08);border-left:3px solid hsla(var(--rg-popup-item-new)/0.6);border-radius:2px;color:var(--rg-text-secondary)}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane .tooltip-comments-all{display:block;padding:.4em .8em;margin:8px;font-size:.82em;font-weight:500;font-family:inherit;text-decoration:none;text-align:center;background:var(--rg-bg-card);color:hsl(var(--rg-popup-btn-copy));border:1px solid hsla(var(--rg-popup-btn-copy)/0.5);border-radius:3px !important;transition:background .15s,border-color .15s;cursor:pointer}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane .tooltip-comments-all:hover{background:hsla(var(--rg-popup-btn-copy)/0.15);border-color:hsl(var(--rg-popup-btn-copy))}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane .tooltip-comments-all:active{background:hsla(var(--rg-popup-btn-copy)/0.25)}@media(max-width: 899px){.vocabulary-tooltip-popup{max-height:75vh;display:flex;flex-direction:column}.vocabulary-tooltip-popup .tooltip-body{flex-direction:column;flex:1;min-height:0}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--content{display:block;flex:1}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments{display:none;border-left:none;border-top:1px solid var(--rg-border-primary)}.vocabulary-tooltip-popup[data-active-tab=comments] .tooltip-pane--content{display:none}.vocabulary-tooltip-popup[data-active-tab=comments] .tooltip-pane--comments{display:block;flex:1}}@media(min-width: 900px){.vocabulary-tooltip-popup{max-width:900px;max-height:80vh;display:flex;flex-direction:column}.vocabulary-tooltip-popup .tooltip-tabs{display:none}.vocabulary-tooltip-popup .tooltip-body{flex:1;min-height:0}.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--content,.vocabulary-tooltip-popup .tooltip-body .tooltip-pane--comments{display:block}}.vocabularies-manager-popup{position:fixed;background:var(--rg-bg-primary);color:var(--rg-text-primary);padding:1em;z-index:1200;font-size:.9em;font-family:"Montserrat","Noto Color Emoji",sans-serif !important;pointer-events:auto;white-space:nowrap;border:1px solid var(--rg-border-primary) !important;border-radius:4px !important;box-shadow:0 2px 5px rgba(0,0,0,.3) !important;min-width:300px;max-width:500px;overflow:hidden}.vocabularies-manager-popup .popup-header{font-weight:600 !important;color:var(--rg-text-primary) !important;margin-bottom:.8em !important;padding-bottom:.5em;border-bottom:1px solid var(--rg-border-primary);font-size:1.1em;position:relative}.vocabularies-manager-popup .popup-actions{display:flex;justify-content:flex-start;align-items:center;margin-bottom:.8em;padding-bottom:.5em;border-bottom:1px solid var(--rg-border-primary);gap:.5em;flex-wrap:wrap}.vocabularies-manager-popup .popup-actions .copy-all-btn,.vocabularies-manager-popup .popup-actions .remove-all-btn,.vocabularies-manager-popup .popup-actions .sort-all-btn,.vocabularies-manager-popup .popup-actions .force-fetch-btn,.vocabularies-manager-popup .popup-actions .save-btn,.vocabularies-manager-popup .popup-actions .revert-btn{background:var(--rg-bg-card);border-radius:3px !important;padding:.4em .8em;font-size:.85em;font-weight:500;cursor:pointer;transition:all .2s ease;font-family:inherit}.vocabularies-manager-popup .popup-actions .copy-all-btn:disabled,.vocabularies-manager-popup .popup-actions .remove-all-btn:disabled,.vocabularies-manager-popup .popup-actions .sort-all-btn:disabled,.vocabularies-manager-popup .popup-actions .force-fetch-btn:disabled,.vocabularies-manager-popup .popup-actions .save-btn:disabled,.vocabularies-manager-popup .popup-actions .revert-btn:disabled{opacity:.5;cursor:not-allowed}.vocabularies-manager-popup .popup-actions .copy-all-btn{color:hsl(var(--rg-popup-btn-copy));border:1px solid hsla(var(--rg-popup-btn-copy)/0.5)}.vocabularies-manager-popup .popup-actions .copy-all-btn:hover{background:hsla(var(--rg-popup-btn-copy)/0.15);border-color:hsl(var(--rg-popup-btn-copy))}.vocabularies-manager-popup .popup-actions .copy-all-btn:active{background:hsla(var(--rg-popup-btn-copy)/0.25)}.vocabularies-manager-popup .popup-actions .remove-all-btn{color:hsl(var(--rg-popup-btn-remove));border:1px solid hsla(var(--rg-popup-btn-remove)/0.5)}.vocabularies-manager-popup .popup-actions .remove-all-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-remove)/0.15);border-color:hsl(var(--rg-popup-btn-remove))}.vocabularies-manager-popup .popup-actions .remove-all-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-remove)/0.25)}.vocabularies-manager-popup .popup-actions .sort-all-btn{color:hsl(var(--rg-popup-btn-sort));border:1px solid hsla(var(--rg-popup-btn-sort)/0.5)}.vocabularies-manager-popup .popup-actions .sort-all-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-sort)/0.15);border-color:hsl(var(--rg-popup-btn-sort))}.vocabularies-manager-popup .popup-actions .sort-all-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-sort)/0.25)}.vocabularies-manager-popup .popup-actions .force-fetch-btn{color:hsl(var(--rg-popup-btn-fetch));border:1px solid hsla(var(--rg-popup-btn-fetch)/0.5)}.vocabularies-manager-popup .popup-actions .force-fetch-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-fetch)/0.15);border-color:hsl(var(--rg-popup-btn-fetch))}.vocabularies-manager-popup .popup-actions .force-fetch-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-fetch)/0.25)}.vocabularies-manager-popup .popup-actions .save-btn{color:hsl(var(--rg-popup-btn-save));border:1px solid hsla(var(--rg-popup-btn-save)/0.5);font-weight:600;box-shadow:0 0 8px hsla(var(--rg-popup-btn-save)/0.3)}.vocabularies-manager-popup .popup-actions .save-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-save)/0.15);border-color:hsl(var(--rg-popup-btn-save));box-shadow:0 0 12px hsla(var(--rg-popup-btn-save)/0.5)}.vocabularies-manager-popup .popup-actions .save-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-save)/0.25);box-shadow:0 0 6px hsla(var(--rg-popup-btn-save)/0.4)}.vocabularies-manager-popup .popup-actions .revert-btn{color:hsl(var(--rg-popup-btn-revert));border:1px solid hsla(var(--rg-popup-btn-revert)/0.5)}.vocabularies-manager-popup .popup-actions .revert-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-revert)/0.15);border-color:hsl(var(--rg-popup-btn-revert))}.vocabularies-manager-popup .popup-actions .revert-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-revert)/0.25)}.vocabularies-manager-popup .popup-search-filters{padding:.5em 0;margin-bottom:.5em;border-bottom:1px solid var(--rg-border-primary);display:flex;flex-direction:column;gap:.6em}.vocabularies-manager-popup .popup-search-filters .search-input{width:100%;background:var(--rg-bg-card);color:var(--rg-text-primary) !important;border:1px solid var(--rg-border-primary) !important;border-radius:3px !important;padding:.5em .7em;font-size:.85em;font-family:inherit;transition:all .2s ease}.vocabularies-manager-popup .popup-search-filters .search-input:focus{outline:none;border-color:var(--rg-border-hover);background:var(--rg-bg-hover)}.vocabularies-manager-popup .popup-search-filters .search-input::placeholder{color:var(--rg-text-tertiary);font-style:italic}.vocabularies-manager-popup .popup-search-filters .filter-buttons{display:flex;gap:.4em;justify-content:flex-start;flex-wrap:wrap}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn{background:var(--rg-bg-card);color:var(--rg-text-secondary);border:1px solid var(--rg-border-primary);border-radius:3px !important;padding:.35em .7em;font-size:.8em;font-weight:500;cursor:pointer;transition:all .2s ease;font-family:inherit;white-space:nowrap}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover);color:var(--rg-text-primary)}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn:active{background:var(--rg-bg-secondary);transform:translateY(1px)}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn.active{background:hsl(var(--rg-popup-btn-save)) !important;color:var(--rg-bg-primary) !important;border-color:hsl(var(--rg-popup-btn-save)) !important;box-shadow:0 1px 3px hsla(var(--rg-popup-btn-save)/0.3)}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn.active:hover{background:hsla(var(--rg-popup-btn-save)/0.9) !important;border-color:hsl(var(--rg-popup-btn-save)) !important}.vocabularies-manager-popup .popup-search-filters .filter-buttons .filter-btn.active:active{background:hsla(var(--rg-popup-btn-save)/0.8) !important;transform:translateY(1px)}.vocabularies-manager-popup .vocab-list{display:flex;flex-direction:column;gap:.3em;max-height:60vh;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:hsl(0,0%,35%) rgba(0,0,0,0)}.vocabularies-manager-popup .vocab-list::-webkit-scrollbar{width:8px;height:8px}.vocabularies-manager-popup .vocab-list::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.vocabularies-manager-popup .vocab-list::-webkit-scrollbar-thumb{background-color:hsl(0,0%,35%);border-radius:3px}.vocabularies-manager-popup .vocab-list::-webkit-scrollbar-thumb:hover{background-color:hsl(0,0%,55%)}.vocabularies-manager-popup .vocab-list::-webkit-scrollbar-thumb:active{background-color:hsl(0,0%,65%)}.vocabularies-manager-popup .vocab-list .vocab-labels-container{padding:.5em .7em;margin:.6em 0 .3em 0;background:hsl(var(--rg-popup-item-new));border-radius:2px;position:sticky;top:0;z-index:10;display:flex;justify-content:space-between;align-items:center;gap:1em;font-family:"Montserrat","Noto Color Emoji",sans-serif}.vocabularies-manager-popup .vocab-list .vocab-labels-container .vocab-date,.vocabularies-manager-popup .vocab-list .vocab-labels-container .vocab-count{font-weight:600;font-size:.85em;color:var(--rg-bg-primary)}.vocabularies-manager-popup .vocab-list .vocab-item{display:flex;justify-content:space-between;align-items:center;padding:.4em .6em;background:var(--rg-bg-card);border:1px solid var(--rg-border-primary);border-radius:3px !important;transition:all .2s ease;gap:.8em}.vocabularies-manager-popup .vocab-list .vocab-item:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover)}.vocabularies-manager-popup .vocab-list .vocab-item.vocab-item-new{background:hsla(var(--rg-popup-item-new)/0.15) !important;border:1px solid hsla(var(--rg-popup-item-new)/0.6) !important}.vocabularies-manager-popup .vocab-list .vocab-item.vocab-item-new:hover{background:hsla(var(--rg-popup-item-new)/0.25) !important;border-color:hsl(var(--rg-popup-item-new)) !important}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left{display:inline-flex;align-items:center;flex-shrink:0}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-play-count-badge{display:inline-flex;align-items:center;justify-content:center;margin-left:.5em;padding:4px 8px;background:var(--rg-vocab-badge-bg);color:var(--rg-vocab-badge-text);border-radius:6px;font-size:1em;font-weight:600;font-family:"Montserrat","Courier New",monospace}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-play-btn,.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-info-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin-right:.5em;padding:0;background:rgba(0,0,0,0);border:none;outline:none;appearance:none;cursor:pointer;border-radius:4px;transition:background .15s ease;color:var(--rg-text-secondary)}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-play-btn svg,.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-info-btn svg{width:16px;height:16px}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-play-btn:hover,.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-info-btn:hover{background:var(--rg-vocab-play-hover-bg);color:var(--rg-bg-primary)}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-left .vocab-id{color:var(--rg-text-primary);font-weight:500;font-family:"Montserrat","Courier New",monospace;font-size:.9em}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-right{flex:1;min-width:0;text-align:right}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-right .vocab-name{color:var(--rg-text-secondary);font-size:.85em;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-right .vocab-author,.vocabularies-manager-popup .vocab-list .vocab-item .vocab-right .vocab-type{color:var(--rg-text-tertiary);font-size:.75em;margin-top:.2em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vocabularies-manager-popup .vocab-list .vocab-item .vocab-right .vocab-loading{color:hsl(var(--rg-popup-btn-fetch));font-size:.8em;font-style:italic}.vocabularies-manager-popup .vocab-list .vocab-item .remove-btn{flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-popup-btn-remove));border:1px solid hsla(var(--rg-popup-btn-remove)/0.5);border-radius:3px !important;padding:.2em .5em;font-size:.8em;cursor:pointer;transition:all .2s ease;font-weight:500;font-family:inherit;min-width:60px}.vocabularies-manager-popup .vocab-list .vocab-item .remove-btn:hover{background:hsla(var(--rg-popup-btn-remove)/0.15);color:hsl(var(--rg-popup-btn-remove));border-color:hsl(var(--rg-popup-btn-remove))}.vocabularies-manager-popup .vocab-list .vocab-item .remove-btn:active{background:hsla(var(--rg-popup-btn-remove)/0.25)}.vocabularies-manager-popup .empty-state{text-align:center;color:var(--rg-text-tertiary);font-style:italic;padding:1em 0}.playlists-manager-popup .playlist-picker-game-row .gametype-voc.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-voc.playlist-entry-label{color:var(--rg-gametype-voc) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-normal.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-normal.playlist-entry-label{color:var(--rg-gametype-normal) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-abra.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-abra.playlist-entry-label{color:var(--rg-gametype-abra) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-noerror.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-noerror.playlist-entry-label{color:var(--rg-gametype-noerror) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-marathon.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-marathon.playlist-entry-label{color:var(--rg-gametype-marathon) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-chars.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-chars.playlist-entry-label{color:var(--rg-gametype-chars) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-digits.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-digits.playlist-entry-label{color:var(--rg-gametype-digits) !important}.playlists-manager-popup .playlist-picker-game-row .gametype-sprint.playlist-picker-game-name,.playlists-manager-popup .playlist-entry-row .gametype-sprint.playlist-entry-label{color:var(--rg-gametype-sprint) !important}.playlists-manager-popup{position:fixed;background:var(--rg-bg-primary);color:var(--rg-text-primary);padding:1em;z-index:1200;font-size:.9em;font-family:"Montserrat","Noto Color Emoji",sans-serif !important;pointer-events:auto;white-space:nowrap;border:1px solid var(--rg-border-primary) !important;border-radius:4px !important;box-shadow:0 2px 5px rgba(0,0,0,.3) !important;min-width:400px;max-width:500px;overflow:hidden}.playlists-manager-popup .popup-header{font-weight:600 !important;color:var(--rg-text-primary) !important;margin-bottom:.8em !important;padding-bottom:.5em;border-bottom:1px solid var(--rg-border-primary);font-size:1.1em;position:relative;display:flex;align-items:center;justify-content:space-between}.playlists-manager-popup .popup-header .popup-header-title{color:var(--rg-header-text)}.playlists-manager-popup .popup-header .playlists-header-actions{display:inline-flex;align-items:center;gap:.4em}.playlists-manager-popup .popup-header .playlists-random-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);border:none;outline:none;appearance:none;cursor:pointer;border-radius:4px;transition:background .15s ease,color .15s ease;color:hsl(var(--rg-popup-btn-sort))}.playlists-manager-popup .popup-header .playlists-random-btn svg{width:16px;height:16px;pointer-events:none}.playlists-manager-popup .popup-header .playlists-random-btn:hover{background:hsla(var(--rg-popup-btn-sort)/0.15)}.playlists-manager-popup .popup-header .playlists-add-btn{display:inline-flex;align-items:center;gap:4px;background:var(--rg-bg-card);color:hsl(var(--rg-popup-btn-save));border:1px solid hsla(var(--rg-popup-btn-save)/0.5);border-radius:3px !important;cursor:pointer;font-family:inherit;font-weight:500;transition:all .2s ease;padding:.4em .8em;font-size:.7727272727em}.playlists-manager-popup .popup-header .playlists-add-btn svg{width:12px;height:12px;flex-shrink:0;pointer-events:none}.playlists-manager-popup .popup-header .playlists-add-btn:hover{background:hsla(var(--rg-popup-btn-save)/0.15);border-color:hsl(var(--rg-popup-btn-save))}.playlists-manager-popup .popup-header .playlists-add-btn:active{background:hsla(var(--rg-popup-btn-save)/0.25)}.playlists-manager-popup .playlists-create-form{padding:.5em 0;border-bottom:1px solid var(--rg-border-primary);margin-bottom:.5em;display:flex;flex-direction:column;align-items:flex-start;gap:.4em}.playlists-manager-popup .playlists-create-name-row{display:flex;gap:.4em;align-items:center;width:100%}.playlists-manager-popup .playlists-create-name-row .playlists-create-input{width:100%;box-sizing:border-box;background:var(--rg-bg-card);color:var(--rg-text-primary) !important;border:1px solid var(--rg-border-primary) !important;border-radius:3px !important;height:24px;line-height:24px;padding:0 .6em;font-size:.82em;font-family:inherit;transition:border-color .2s ease,background .2s ease;outline:none;flex:1}.playlists-manager-popup .playlists-create-name-row .playlists-create-input:focus{border-color:var(--rg-border-hover) !important}.playlists-manager-popup .playlists-create-name-row .playlists-create-input::placeholder{color:var(--rg-text-tertiary);font-style:italic}.playlists-manager-popup .playlists-create-groups-toggle{display:inline-flex;align-items:center;gap:4px;background:var(--rg-bg-card);color:hsl(var(--rg-popup-btn-sort));border:1px solid hsla(var(--rg-popup-btn-sort)/0.5);border-radius:3px !important;cursor:pointer;font-family:inherit;font-weight:500;transition:all .2s ease;padding:.35em .7em;font-size:.8em;user-select:none}.playlists-manager-popup .playlists-create-groups-toggle svg{width:13px;height:13px;flex-shrink:0;pointer-events:none}.playlists-manager-popup .playlists-create-groups-toggle:hover{background:hsla(var(--rg-popup-btn-sort)/0.15);border-color:hsl(var(--rg-popup-btn-sort))}.playlists-manager-popup .playlists-create-groups-toggle:active{background:hsla(var(--rg-popup-btn-sort)/0.25)}.playlists-manager-popup .playlists-create-groups-row{display:flex;flex-wrap:wrap;gap:.3em}.playlists-manager-popup .playlists-create-groups-row .playlists-create-group-btn{display:inline-flex;align-items:center;gap:4px;background:var(--rg-bg-card);color:hsl(var(--rg-popup-btn-sort));border:1px solid hsla(var(--rg-popup-btn-sort)/0.5);border-radius:3px !important;cursor:pointer;font-family:inherit;font-weight:500;transition:all .2s ease;padding:.2em .6em;font-size:.78em;font-family:inherit;white-space:nowrap;max-width:140px;overflow:hidden;text-overflow:ellipsis;transition:filter .2s ease,opacity .2s ease}.playlists-manager-popup .playlists-create-groups-row .playlists-create-group-btn svg{width:0px;height:0px;flex-shrink:0;pointer-events:none}.playlists-manager-popup .playlists-create-groups-row .playlists-create-group-btn:hover{background:hsla(var(--rg-popup-btn-sort)/0.15);border-color:hsl(var(--rg-popup-btn-sort))}.playlists-manager-popup .playlists-create-groups-row .playlists-create-group-btn:active{background:hsla(var(--rg-popup-btn-sort)/0.25)}.playlists-manager-popup .playlists-create-groups-row .playlists-create-group-btn--done{filter:grayscale(1);opacity:.55;cursor:default}.playlists-manager-popup .playlists-empty{text-align:center;color:var(--rg-text-tertiary);font-style:italic;padding:1em 0}.playlists-manager-popup .playlists-list{display:flex;flex-direction:column;gap:.3em;max-height:80vh;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:hsl(0,0%,35%) rgba(0,0,0,0)}.playlists-manager-popup .playlists-list::-webkit-scrollbar{width:8px;height:8px}.playlists-manager-popup .playlists-list::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.playlists-manager-popup .playlists-list::-webkit-scrollbar-thumb{background-color:hsl(0,0%,35%);border-radius:3px}.playlists-manager-popup .playlists-list::-webkit-scrollbar-thumb:hover{background-color:hsl(0,0%,55%)}.playlists-manager-popup .playlists-list::-webkit-scrollbar-thumb:active{background-color:hsl(0,0%,65%)}.playlists-manager-popup .playlist-block{display:flex;flex-direction:column;gap:0}.playlists-manager-popup .playlist-block--dragging{position:relative;z-index:100;box-shadow:0 4px 12px rgba(0,0,0,.25) !important;opacity:.85}.playlists-manager-popup .playlist-header-row{display:flex;align-items:center;gap:.5em;padding:.5em .7em;margin:.6em 0 0;background:var(--rg-border-hover);border-radius:2px;position:sticky;top:0;z-index:10;cursor:pointer;user-select:none}.playlists-manager-popup .playlist-header-row:first-child{margin-top:0}.playlists-manager-popup .playlist-header-row--active{background:hsl(var(--rg-popup-item-new))}.playlists-manager-popup .playlist-header-row .playlist-title{flex:1;font-weight:600;font-size:.85em;color:var(--rg-bg-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:inline-flex;align-items:center;gap:.5em}.playlists-manager-popup .playlist-header-row .playlist-active-badge{display:inline-flex;align-items:center;gap:.4em;padding:.3em .5em;background:var(--rg-bg-secondary) !important;border-radius:10px !important;font-size:1em;font-variant-numeric:tabular-nums;white-space:nowrap;flex-shrink:0;line-height:1}.playlists-manager-popup .playlist-header-row .playlist-active-badge-position,.playlists-manager-popup .playlist-header-row .playlist-active-badge-reps,.playlists-manager-popup .playlist-header-row .playlist-active-badge-cycles,.playlists-manager-popup .playlist-header-row .playlist-active-badge-shuffle{display:inline-flex;align-items:center;gap:.25em;font-size:1em;font-weight:600}.playlists-manager-popup .playlist-header-row .playlist-active-badge-position{color:var(--rg-playlist-active-badge-position)}.playlists-manager-popup .playlist-header-row .playlist-active-badge-reps{color:var(--rg-playlist-active-badge-reps)}.playlists-manager-popup .playlist-header-row .playlist-active-badge-cycles{color:var(--rg-playlist-active-badge-cycles)}.playlists-manager-popup .playlist-header-row .playlist-active-badge-shuffle{color:var(--rg-playlist-active-badge-shuffle)}.playlists-manager-popup .playlist-header-row .playlist-active-badge-reps svg,.playlists-manager-popup .playlist-header-row .playlist-active-badge-cycles svg,.playlists-manager-popup .playlist-header-row .playlist-active-badge-shuffle svg{width:14px;height:14px;flex-shrink:0;pointer-events:none}.playlists-manager-popup .playlist-header-row .playlist-play-btn,.playlists-manager-popup .playlist-header-row .playlist-pause-btn,.playlists-manager-popup .playlist-header-row .playlist-play-shuffle-btn,.playlists-manager-popup .playlist-header-row .playlist-rename-btn,.playlists-manager-popup .playlist-header-row .playlist-duplicate-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);border:none;outline:none;appearance:none;cursor:pointer;border-radius:4px;transition:background .15s ease,color .15s ease;color:var(--rg-bg-primary)}.playlists-manager-popup .playlist-header-row .playlist-play-btn svg,.playlists-manager-popup .playlist-header-row .playlist-pause-btn svg,.playlists-manager-popup .playlist-header-row .playlist-play-shuffle-btn svg,.playlists-manager-popup .playlist-header-row .playlist-rename-btn svg,.playlists-manager-popup .playlist-header-row .playlist-duplicate-btn svg{width:16px;height:16px;pointer-events:none}.playlists-manager-popup .playlist-header-row .playlist-play-btn:hover,.playlists-manager-popup .playlist-header-row .playlist-pause-btn:hover,.playlists-manager-popup .playlist-header-row .playlist-play-shuffle-btn:hover,.playlists-manager-popup .playlist-header-row .playlist-rename-btn:hover,.playlists-manager-popup .playlist-header-row .playlist-duplicate-btn:hover{background:rgba(0,0,0,.15)}.playlists-manager-popup .playlist-header-row .playlist-play-shuffle-btn.active{background:hsla(var(--rg-popup-btn-sort)/0.25);color:hsl(var(--rg-popup-btn-sort))}.playlists-manager-popup .playlist-header-row .playlist-delete-btn,.playlists-manager-popup .playlist-header-row .playlist-cancel-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);border:none;outline:none;appearance:none;cursor:pointer;border-radius:4px;transition:background .15s ease,color .15s ease;color:var(--rg-bg-primary)}.playlists-manager-popup .playlist-header-row .playlist-delete-btn svg,.playlists-manager-popup .playlist-header-row .playlist-cancel-btn svg{width:16px;height:16px;pointer-events:none}.playlists-manager-popup .playlist-header-row .playlist-delete-btn:hover,.playlists-manager-popup .playlist-header-row .playlist-cancel-btn:hover{background:rgba(200,40,40,.35)}.playlists-manager-popup .playlist-header-row .playlist-header-stepper{display:inline-flex;align-items:center;gap:1px;flex-shrink:0;position:relative}.playlists-manager-popup .playlist-header-row .playlist-header-stepper .playlist-stepper-btn{width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;padding:0;flex-shrink:0;background:rgba(0,0,0,.15);color:var(--rg-bg-primary);border:1px solid rgba(0,0,0,0);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none}.playlists-manager-popup .playlist-header-row .playlist-header-stepper .playlist-stepper-btn svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-header-row .playlist-header-stepper .playlist-stepper-btn:hover{background:rgba(0,0,0,.28);border-color:rgba(0,0,0,0);color:var(--rg-bg-primary)}.playlists-manager-popup .playlist-header-row .playlist-header-stepper .playlist-stepper-btn:active{background:rgba(0,0,0,.28);transform:translateY(1px)}.playlists-manager-popup .playlist-header-row .playlist-header-stepper .playlist-stepper-count{min-width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;font-size:.8em;font-weight:600;font-variant-numeric:tabular-nums;color:var(--rg-bg-primary)}.playlists-manager-popup .playlist-header-row .playlist-header-stepper--default{opacity:.35}.playlists-manager-popup .playlist-header-row .playlist-block-drag-handle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;flex-shrink:0;cursor:grab;color:var(--rg-bg-primary)}.playlists-manager-popup .playlist-header-row .playlist-block-drag-handle svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-header-row .playlist-block-drag-handle:active{cursor:grabbing}.playlists-manager-popup .playlist-header-row:hover .playlist-header-stepper--default{opacity:.8}.playlists-manager-popup .playlist-body{display:flex;flex-direction:column;gap:0}.playlists-manager-popup .playlist-entries{display:flex;flex-direction:column;gap:0}.playlists-manager-popup .playlist-entries-empty{padding:.4em .6em;background:var(--rg-bg-card);border:1px solid var(--rg-border-primary);border-radius:3px !important;color:var(--rg-text-tertiary);font-style:italic;font-size:.8em;margin-top:.3em}.playlists-manager-popup .playlist-entry-row{position:relative;display:flex;justify-content:space-between;align-items:center;padding:.4em .6em;background:var(--rg-bg-card);border:1px solid var(--rg-border-primary);border-radius:3px !important;transition:background .2s ease,border-color .2s ease;gap:.8em;margin-top:.3em;overflow:hidden}.playlists-manager-popup .playlist-entry-row:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover)}.playlists-manager-popup .playlist-entry-row--active{background:hsla(var(--rg-popup-item-new)/0.15) !important;border:1px solid hsla(var(--rg-popup-item-new)/0.6) !important}.playlists-manager-popup .playlist-entry-row--active:hover{background:hsla(var(--rg-popup-item-new)/0.25) !important;border-color:hsl(var(--rg-popup-item-new)) !important}.playlists-manager-popup .playlist-entry-row--passed{background:var(--rg-bg-primary) !important;border-color:var(--rg-border-primary) !important;opacity:.5 !important}.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open{opacity:1 !important;background:hsla(var(--rg-playlist-params-color)/0.07) !important;border-color:hsla(var(--rg-playlist-params-color)/0.55) !important}.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open .playlist-entry-label,.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open .playlist-entry-play-btn,.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open .playlist-entry-drag-handle,.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open .playlist-entry-duplicate-btn,.playlists-manager-popup .playlist-entry-row--passed.playlist-entry-row--params-open .playlist-entry-params-btn{filter:none !important}.playlists-manager-popup .playlist-entry-row--passed .playlist-entry-label,.playlists-manager-popup .playlist-entry-row--passed .playlist-entry-play-btn,.playlists-manager-popup .playlist-entry-row--passed .playlist-entry-drag-handle,.playlists-manager-popup .playlist-entry-row--passed .playlist-entry-duplicate-btn,.playlists-manager-popup .playlist-entry-row--passed .playlist-entry-params-btn{filter:grayscale(70%) !important}.playlists-manager-popup .playlist-entry-row--passed .playlist-stepper-btn{background:rgba(0,0,0,0) !important}.playlists-manager-popup .playlist-entry-row--passed:hover{background:var(--rg-bg-card) !important;border-color:var(--rg-border-hover) !important;opacity:1 !important}.playlists-manager-popup .playlist-entry-row--passed:hover .playlist-entry-label,.playlists-manager-popup .playlist-entry-row--passed:hover .playlist-entry-play-btn,.playlists-manager-popup .playlist-entry-row--passed:hover .playlist-entry-drag-handle,.playlists-manager-popup .playlist-entry-row--passed:hover .playlist-entry-duplicate-btn,.playlists-manager-popup .playlist-entry-row--passed:hover .playlist-entry-params-btn{filter:none !important}.playlists-manager-popup .playlist-entry-row--progress::before{content:"";position:absolute;inset:0;width:var(--playlist-progress, 0%);background:hsla(var(--rg-popup-item-new)/0.18);pointer-events:none;transition:width .45s cubic-bezier(0.34, 1.56, 0.64, 1)}.playlists-manager-popup .playlist-entry-row--progress.playlist-entry-row--params-open::before{background:hsla(var(--rg-playlist-params-color)/0.18)}.playlists-manager-popup .playlist-entry-row .playlist-entry-play-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-playlist-entry-play));border:1px solid rgba(0,0,0,0);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-play-btn svg{width:14px;height:14px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-play-btn:hover{background:hsla(var(--rg-playlist-entry-play)/0.15);border-color:hsl(var(--rg-playlist-entry-play))}.playlists-manager-popup .playlist-entry-row .playlist-entry-play-btn:active{background:hsla(var(--rg-playlist-entry-play)/0.25)}.playlists-manager-popup .playlist-entry-row .playlist-entry-drag-handle{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;cursor:grab;color:var(--rg-text-tertiary);opacity:.5;transition:opacity .15s;position:relative}.playlists-manager-popup .playlist-entry-row .playlist-entry-drag-handle svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-drag-handle:hover{opacity:1}.playlists-manager-popup .playlist-entry-row .playlist-entry-drag-handle:active{cursor:grabbing}.playlists-manager-popup .playlist-entry-row .playlist-entry-duplicate-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-popup-btn-copy));border:1px solid rgba(0,0,0,0);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-duplicate-btn svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-duplicate-btn:hover{background:hsla(var(--rg-popup-btn-copy)/0.15);border-color:hsl(var(--rg-popup-btn-copy))}.playlists-manager-popup .playlist-entry-row .playlist-entry-duplicate-btn:active{background:hsla(var(--rg-popup-btn-copy)/0.25)}.playlists-manager-popup .playlist-entry-row .playlist-entry-label{position:relative;flex:1;font-size:.85em;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--rg-text-secondary)}.playlists-manager-popup .playlist-entry-row .playlist-entry-label.playlist-entry-missing{color:var(--rg-text-tertiary) !important;font-style:italic}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper{display:inline-flex;align-items:center;gap:2px;flex-shrink:0;position:relative}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper .playlist-stepper-btn{width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;padding:0;flex-shrink:0;background:var(--rg-bg-card);color:var(--rg-text-secondary);border:1px solid var(--rg-border-primary);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper .playlist-stepper-btn svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper .playlist-stepper-btn:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover);color:var(--rg-text-secondary)}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper .playlist-stepper-btn:active{background:var(--rg-bg-hover);transform:translateY(1px)}.playlists-manager-popup .playlist-entry-row .playlist-entry-stepper .playlist-stepper-count{min-width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;font-size:.8em;font-weight:600;font-variant-numeric:tabular-nums;color:var(--rg-text-primary)}.playlists-manager-popup .playlist-entry-row .playlist-entry-remove{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-popup-btn-remove));border:1px solid hsla(var(--rg-popup-btn-remove)/0.5);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none;position:relative;flex-shrink:0}.playlists-manager-popup .playlist-entry-row .playlist-entry-remove svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-remove:hover{background:hsla(var(--rg-popup-btn-remove)/0.15);border-color:hsl(var(--rg-popup-btn-remove))}.playlists-manager-popup .playlist-entry-row .playlist-entry-remove:active{background:hsla(var(--rg-popup-btn-remove)/0.25)}.playlists-manager-popup .playlist-entry-row--dragging{position:relative;z-index:100;box-shadow:0 4px 12px rgba(0,0,0,.25) !important;opacity:.85}.playlists-manager-popup .playlist-entry-row.playlist-entry-row--params-open{border-bottom-left-radius:0 !important;border-bottom-right-radius:0 !important;border-bottom:none !important;border-color:hsla(var(--rg-playlist-params-color)/0.55) !important;background:hsla(var(--rg-playlist-params-color)/0.07) !important}.playlists-manager-popup .playlist-entry-row.playlist-entry-row--params-open:hover,.playlists-manager-popup .playlist-entry-row.playlist-entry-row--params-open.playlist-entry-row--active:hover{background:hsla(var(--rg-playlist-params-color)/0.07) !important;border-bottom:none !important;border-color:hsla(var(--rg-playlist-params-color)/0.55) !important}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-playlist-params-color));border:1px solid rgba(0,0,0,0);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none;flex-shrink:0;color:var(--rg-text-tertiary)}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn:hover{background:hsla(var(--rg-playlist-params-color)/0.15);border-color:hsl(var(--rg-playlist-params-color))}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn:active{background:hsla(var(--rg-playlist-params-color)/0.25)}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn.has-overrides{color:hsl(var(--rg-playlist-params-color));border-color:hsla(var(--rg-playlist-params-color)/0.6);background:hsla(var(--rg-playlist-params-color)/0.12)}.playlists-manager-popup .playlist-entry-row .playlist-entry-params-btn.has-overrides:hover{background:hsla(var(--rg-playlist-params-color)/0.25);border-color:hsl(var(--rg-playlist-params-color))}.playlists-manager-popup .playlist-entry-params{display:flex;flex-direction:column;gap:.35em;padding:.5em .7em;margin-top:0;background:hsla(var(--rg-playlist-params-color)/0.07);border:1px solid hsla(var(--rg-playlist-params-color)/0.55);border-top:none;border-radius:0 0 3px 3px !important}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-group{display:flex;flex-wrap:wrap;align-items:center;gap:.3em}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-label{font-size:.72em;font-weight:600;color:hsl(var(--rg-playlist-params-color));min-width:2.5em;text-transform:uppercase;letter-spacing:.03em;flex-shrink:0}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-option{display:inline-flex;align-items:center;padding:2px 7px;font-size:.75em;font-weight:500;font-family:inherit;background:var(--rg-bg-card);color:var(--rg-text-secondary);border:1px solid var(--rg-border-primary);border-radius:3px !important;cursor:pointer;transition:all .15s ease}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-option:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover);color:var(--rg-text-primary)}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-option.active{color:hsl(var(--rg-playlist-params-color)) !important;background:hsla(var(--rg-playlist-params-color)/0.15) !important;border-color:hsla(var(--rg-playlist-params-color)/0.7) !important;font-weight:600}.playlists-manager-popup .playlist-entry-params .playlist-entry-params-option.playlist-entry-params-option--disabled,.playlists-manager-popup .playlist-entry-params .playlist-entry-params-option:disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.playlists-manager-popup .playlist-entry-placeholder{border:1px dashed var(--rg-border-hover);border-radius:3px !important;background:var(--rg-bg-hover);margin-top:.3em}.playlists-manager-popup .playlist-game-picker{margin-top:.5em}.playlists-manager-popup .playlist-picker-toggle{display:inline-flex;align-items:center;gap:4px;background:var(--rg-bg-card);color:hsl(var(--rg-popup-btn-sort));border:1px solid hsla(var(--rg-popup-btn-sort)/0.5);border-radius:3px !important;cursor:pointer;font-family:inherit;font-weight:500;transition:all .2s ease;padding:.35em .7em;font-size:.8em;user-select:none}.playlists-manager-popup .playlist-picker-toggle svg{width:13px;height:13px;flex-shrink:0;pointer-events:none}.playlists-manager-popup .playlist-picker-toggle:hover{background:hsla(var(--rg-popup-btn-sort)/0.15);border-color:hsl(var(--rg-popup-btn-sort))}.playlists-manager-popup .playlist-picker-toggle:active{background:hsla(var(--rg-popup-btn-sort)/0.25)}.playlists-manager-popup .playlist-picker-body{margin-top:.3em;max-height:40vh;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:hsl(0,0%,35%) rgba(0,0,0,0)}.playlists-manager-popup .playlist-picker-body::-webkit-scrollbar{width:8px;height:8px}.playlists-manager-popup .playlist-picker-body::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.playlists-manager-popup .playlist-picker-body::-webkit-scrollbar-thumb{background-color:hsl(0,0%,35%);border-radius:3px}.playlists-manager-popup .playlist-picker-body::-webkit-scrollbar-thumb:hover{background-color:hsl(0,0%,55%)}.playlists-manager-popup .playlist-picker-body::-webkit-scrollbar-thumb:active{background-color:hsl(0,0%,65%)}.playlists-manager-popup .playlist-picker-body--hidden{display:none}.playlists-manager-popup .playlist-picker-search-wrap{padding:.5em 0;position:sticky;top:0;background:var(--rg-bg-primary);z-index:3}.playlists-manager-popup .playlist-picker-search-wrap .playlist-search-input{width:100%;box-sizing:border-box;background:var(--rg-bg-card);color:var(--rg-text-primary) !important;border:1px solid var(--rg-border-primary) !important;border-radius:3px !important;height:24px;line-height:24px;padding:0 .6em;font-size:.82em;font-family:inherit;transition:border-color .2s ease,background .2s ease;outline:none}.playlists-manager-popup .playlist-picker-search-wrap .playlist-search-input:focus{border-color:var(--rg-border-hover) !important;background:var(--rg-bg-hover)}.playlists-manager-popup .playlist-picker-search-wrap .playlist-search-input::placeholder{color:var(--rg-text-tertiary);font-style:italic}.playlists-manager-popup .playlist-picker-group-header{padding:.5em .7em;margin:.6em 0 .3em 0;font-weight:600;font-size:.85em;color:var(--rg-bg-primary);background:hsl(var(--rg-popup-item-new));border-radius:2px;position:sticky;top:var(--picker-search-height, 34px);z-index:2;display:flex;align-items:center;font-family:"Montserrat","Noto Color Emoji",sans-serif}.playlists-manager-popup .playlist-picker-game-row{display:flex;justify-content:space-between;align-items:center;padding:.4em .6em;background:var(--rg-bg-card);border:1px solid var(--rg-border-primary);border-radius:3px !important;gap:.8em;transition:all .2s ease;margin-top:.3em}.playlists-manager-popup .playlist-picker-game-row:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover)}.playlists-manager-popup .playlist-picker-game-row.already-added{opacity:.45}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-game-name{flex:1;font-size:.85em;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--rg-text-secondary)}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-game-desc{font-size:.75em;color:var(--rg-text-tertiary);flex-shrink:0}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;flex-shrink:0;background:rgba(0,0,0,0);color:hsl(var(--rg-popup-btn-save));border:1px solid hsla(var(--rg-popup-btn-save)/0.5);border-radius:3px !important;cursor:pointer;transition:all .2s ease;outline:none;appearance:none;flex-shrink:0}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn svg{width:12px;height:12px;pointer-events:none}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn:hover{background:hsla(var(--rg-popup-btn-save)/0.15);border-color:hsl(var(--rg-popup-btn-save))}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn:active{background:hsla(var(--rg-popup-btn-save)/0.25)}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn:hover:not(:disabled){background:hsla(var(--rg-popup-btn-save)/0.15);border-color:hsl(var(--rg-popup-btn-save))}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn:active:not(:disabled){background:hsla(var(--rg-popup-btn-save)/0.25)}.playlists-manager-popup .playlist-picker-game-row .playlist-picker-add-btn:disabled{cursor:default;opacity:.5}.playlists-manager-popup .playlist-picker-empty{padding:.5em .6em;color:var(--rg-text-tertiary);font-style:italic;font-size:.8em}.rg-scanner-overlay{position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45);backdrop-filter:blur(2px);font-family:"Montserrat","Noto Color Emoji",sans-serif}.rg-scanner-card{background:var(--rg-bg-primary);color:var(--rg-text-primary);border:1px solid var(--rg-border-primary);border-radius:8px;box-shadow:2px 0 10px rgba(0,0,0,.15);padding:1.4em 1.6em 1.6em;width:min(460px,92vw);display:flex;flex-direction:column;gap:.9em}.rg-scanner-title{font-size:.95em;font-weight:700;color:var(--rg-header-text);display:flex;align-items:center;gap:.6em;flex-wrap:wrap;padding-bottom:.7em;border-bottom:1px solid var(--rg-border-primary)}.rg-scanner-btn-row{display:flex;align-items:center;gap:.5em;justify-content:flex-end}.rg-scanner-btn{border:1px solid var(--rg-border-primary);border-radius:4px;font-size:.82em;font-weight:600;font-family:inherit;cursor:pointer;transition:background .15s,border-color .15s,color .15s;background:var(--rg-bg-card);color:var(--rg-text-secondary);padding:.35em .9em}.rg-scanner-btn:hover{background:var(--rg-bg-hover);border-color:var(--rg-border-hover)}.rg-scanner-btn:active{transform:translateY(1px)}.rg-scanner-btn:disabled{opacity:.5;cursor:not-allowed}.rg-scanner-btn--select{color:hsl(var(--rg-popup-btn-sort));border-color:hsla(var(--rg-popup-btn-sort)/0.5)}.rg-scanner-btn--select:hover{background:hsla(var(--rg-popup-btn-sort)/0.15);border-color:hsl(var(--rg-popup-btn-sort))}.rg-scanner-btn--select:active{background:hsla(var(--rg-popup-btn-sort)/0.25)}.rg-scanner-btn--deselect{color:hsl(var(--rg-popup-btn-revert));border-color:hsla(var(--rg-popup-btn-revert)/0.5)}.rg-scanner-btn--deselect:hover{background:hsla(var(--rg-popup-btn-revert)/0.15);border-color:hsl(var(--rg-popup-btn-revert))}.rg-scanner-btn--deselect:active{background:hsla(var(--rg-popup-btn-revert)/0.25)}.rg-scanner-btn--close{color:hsl(var(--rg-popup-btn-revert));border-color:hsla(var(--rg-popup-btn-revert)/0.5)}.rg-scanner-btn--close:hover{background:hsla(var(--rg-popup-btn-revert)/0.15);border-color:hsl(var(--rg-popup-btn-revert))}.rg-scanner-btn--close:active{background:hsla(var(--rg-popup-btn-revert)/0.25)}.rg-scanner-btn--cancel{color:hsl(var(--rg-popup-btn-remove));border-color:hsla(var(--rg-popup-btn-remove)/0.5)}.rg-scanner-btn--cancel:hover{background:hsla(var(--rg-popup-btn-remove)/0.15);border-color:hsl(var(--rg-popup-btn-remove))}.rg-scanner-btn--cancel:active{background:hsla(var(--rg-popup-btn-remove)/0.25)}.rg-scanner-btn--scan{color:hsl(var(--rg-popup-btn-save));border-color:hsla(var(--rg-popup-btn-save)/0.5);font-weight:600}.rg-scanner-btn--scan:hover{background:hsla(var(--rg-popup-btn-save)/0.15);border-color:hsl(var(--rg-popup-btn-save))}.rg-scanner-btn--scan:active{background:hsla(var(--rg-popup-btn-save)/0.25)}.rg-scanner-group-list{display:flex;flex-direction:column;gap:4px;max-height:260px;overflow-y:auto;padding-right:4px;scrollbar-width:thin;scrollbar-color:var(--rg-border-hover) var(--rg-bg-primary);user-select:none}.rg-scanner-group-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:.88em;padding:3px 0}.rg-scanner-group-label-count{opacity:.6;font-size:.78em}.rg-scanner-progress-card{gap:.6em}.rg-scanner-progress-card .rg-scanner-progress-meta{display:flex;justify-content:space-between;align-items:baseline;font-size:.88em}.rg-scanner-progress-card .rg-scanner-progress-meta .rg-scanner-progress-group{font-weight:600;color:var(--rg-text-primary)}.rg-scanner-progress-card .rg-scanner-progress-meta .rg-scanner-progress-fraction{font-size:.84em;font-weight:700;font-variant-numeric:tabular-nums;color:var(--rg-text-tertiary)}.rg-scanner-progress-card .rg-scanner-progress-voc{display:flex;align-items:center;gap:.5em;font-size:.88em;min-height:1.2em}.rg-scanner-progress-card .rg-scanner-progress-voc .rg-scanner-progress-voc-id{font-size:.84em;font-weight:700;font-variant-numeric:tabular-nums;color:var(--rg-text-secondary);flex-shrink:0}.rg-scanner-progress-card .rg-scanner-progress-voc .rg-scanner-progress-voc-name{color:var(--rg-text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rg-scanner-progress-card .rg-scanner-bar-row{display:flex;align-items:center;gap:.6em}.rg-scanner-progress-card .rg-scanner-bar-wrap{flex:1;height:10px;background:var(--rg-rank-slider-track-bg);border:1px solid var(--rg-rank-slider-border);border-radius:6px;overflow:hidden}.rg-scanner-progress-card .rg-scanner-bar-wrap .rg-scanner-bar-fill{height:100%;background:var(--rg-border-pinned);border-radius:6px;transition:width .2s ease}.rg-scanner-progress-card .rg-scanner-progress-percent{font-size:.84em;font-weight:700;font-variant-numeric:tabular-nums;color:var(--rg-text-tertiary);min-width:3em;text-align:right;flex-shrink:0}.rg-scanner-results-card{width:min(520px,94vw);max-height:90vh;display:flex;flex-direction:column}.rg-scanner-results-card .rg-scanner-results-badge{display:inline-block;background:var(--rg-bg-card);color:var(--rg-text-secondary);border:1px solid var(--rg-border-primary);border-radius:20px;padding:.15em .65em;font-size:.78em;font-weight:600}.rg-scanner-results-card .rg-scanner-results-subtitle{font-size:.84em;color:var(--rg-text-secondary);line-height:1.5}.rg-scanner-results-card .rg-scanner-results-subtitle strong{color:var(--rg-text-primary);font-weight:700}.rg-scanner-results-card .rg-scanner-results-tree{flex:1;overflow-y:auto;overflow-x:hidden;max-height:calc(90vh - 210px);display:flex;flex-direction:column;gap:.4em;padding-right:2px;scrollbar-width:thin;scrollbar-color:var(--rg-border-hover) var(--rg-bg-primary)}.rg-scanner-results-card .rg-scanner-results-tree::-webkit-scrollbar{width:4px}.rg-scanner-results-card .rg-scanner-results-tree::-webkit-scrollbar-track{background:var(--rg-bg-primary)}.rg-scanner-results-card .rg-scanner-results-tree::-webkit-scrollbar-thumb{background-color:var(--rg-border-hover);border-radius:2px}.rg-scanner-results-card .rg-scanner-results-tree::-webkit-scrollbar-thumb:hover{background-color:var(--rg-text-tertiary)}.rg-scanner-results-card .rg-scanner-results-empty{text-align:center;color:var(--rg-text-tertiary);font-style:italic;padding:1.5em 0;font-size:.84em}.rg-scanner-results-card .rg-scanner-tree-group{border:1px solid var(--rg-border-primary);border-radius:4px}.rg-scanner-results-card .rg-scanner-tree-group-header{display:flex;align-items:center;gap:.5em;padding:.45em .8em;background:var(--rg-bg-secondary);border-bottom:1px solid var(--rg-border-primary);font-size:.88em;font-weight:700}.rg-scanner-results-card .rg-scanner-tree-group-header .rg-scanner-tree-group-icon{font-size:.95em;flex-shrink:0}.rg-scanner-results-card .rg-scanner-tree-group-header .rg-scanner-tree-group-title{flex:1;color:var(--rg-text-primary)}.rg-scanner-results-card .rg-scanner-tree-group-header .rg-scanner-tree-group-count{background:var(--rg-bg-card);color:var(--rg-text-secondary);border:1px solid var(--rg-border-primary);border-radius:10px;padding:.1em .5em;font-size:.78em;font-weight:600}.rg-scanner-results-card .rg-scanner-tree-items{list-style:none;margin:0;padding:.2em 0;background:var(--rg-bg-primary);display:flex;flex-direction:column;gap:0}.rg-scanner-results-card .rg-scanner-tree-item{display:flex;align-items:center;gap:.5em;padding:.35em .8em .35em 1.4em;font-size:.78em;border-bottom:1px solid var(--rg-border-primary);transition:background .12s}.rg-scanner-results-card .rg-scanner-tree-item:last-child{border-bottom:none}.rg-scanner-results-card .rg-scanner-tree-item:hover{background:var(--rg-bg-hover)}.rg-scanner-results-card .rg-scanner-tree-item .rg-scanner-tree-item-icon{flex-shrink:0;font-size:.84em;opacity:.6}.rg-scanner-results-card .rg-scanner-tree-item .rg-scanner-tree-item-link{font-weight:700;font-size:1em;color:var(--rg-text-secondary);text-decoration:none;flex-shrink:0}.rg-scanner-results-card .rg-scanner-tree-item .rg-scanner-tree-item-link:hover{text-decoration:underline;color:var(--rg-text-primary)}.rg-scanner-results-card .rg-scanner-tree-item .rg-scanner-tree-item-name{color:var(--rg-text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}:root.latest-games-light-theme{--rg-bg-primary:#fff;--rg-bg-secondary:hsl(0,0%,98%);--rg-bg-card:hsl(0,0%,98%);--rg-bg-card-pinned:hsl(120,50%,96%);--rg-bg-hover:hsl(0,0%,96%);--rg-hover-mix-color:rgba(0,0,0,.08);--rg-border-primary:hsl(0,0%,88%);--rg-border-hover:hsl(0,0%,74%);--rg-border-pinned:hsl(122,39%,49%);--rg-text-primary:hsl(0,0%,15%);--rg-text-secondary:#666;--rg-text-tertiary:hsl(0,0%,55%);--rg-text-options:hsl(0,0%,30%);--rg-enabled-yellow:#960;--rg-bg-enabled-yellow:rgba(204,136,0,.2);--rg-enabled-blue:hsl(215,75%,50%);--rg-bg-enabled-blue:hsla(215,75%,50%,.2);--rg-gametype-voc:hsl(215,75%,50%);--rg-gametype-normal:hsl(130,50%,30%);--rg-gametype-abra:hsl(215,20%,40%);--rg-gametype-noerror:hsl(200,45%,35%);--rg-gametype-marathon:hsl(340,65%,45%);--rg-gametype-chars:rgb(153,89.25,0);--rg-gametype-digits:hsl(0,0%,50%);--rg-gametype-sprint:hsl(5,40%,40%);--rg-icon-primary:currentColor;--rg-icon-delete:hsl(4,90%,58%);--rg-bg-hover-delete:hsla(4,90%,58%,.2);--rg-icon-pin:hsl(122,39%,49%);--rg-bg-hover-pin:hsla(122,39%,49%,.2);--rg-icon-info:hsl(0,0%,55%);--rg-bg-hover-info:hsla(0,0%,55%,.2);--rg-icon-edit:#c90;--rg-bg-hover-edit:rgba(204,153,0,.2);--rg-icon-theme-sun:hsl(48,100%,41%);--rg-icon-theme-moon:hsl(207,89%,76%);--rg-hover-control:hsl(0,0%,92%);--rg-hover-control-btn:hsl(213,77%,96%);--rg-bg-card-pinned-voc:hsl(215,80%,95%);--rg-border-pinned-voc:hsl(215,80%,80%);--rg-bg-card-pinned-normal:hsl(130,50%,90%);--rg-border-pinned-normal:hsl(130,50%,70%);--rg-bg-card-pinned-abra:hsl(215,20%,90%);--rg-border-pinned-abra:hsl(215,20%,70%);--rg-bg-card-pinned-noerror:hsl(200,45%,90%);--rg-border-pinned-noerror:hsl(200,45%,70%);--rg-bg-card-pinned-marathon:hsl(340,65%,90%);--rg-border-pinned-marathon:hsl(340,65%,70%);--rg-bg-card-pinned-chars:hsl(35,100%,90%);--rg-border-pinned-chars:hsl(35,100%,70%);--rg-bg-card-pinned-digits:hsl(0,0%,90%);--rg-border-pinned-digits:hsl(0,0%,70%);--rg-bg-card-pinned-sprint:hsl(5,40%,90%);--rg-border-pinned-sprint:hsl(5,40%,70%);--rg-bg-tab:hsl(0,0%,97%);--rg-bg-tab-hover:hsl(0,0%,94%);--rg-bg-tab-active:#fff;--rg-icon-accent:hsl(215,75%,50%);--rg-qualification-icon:hsl(48,100%,41%);--rg-panel-toggle-background:hsl(215,80%,95%);--rg-panel-toggle-stroke:hsl(215,75%,50%);--rg-panel-toggle-border:hsl(215,80%,80%);--rg-panel-toggle-bg-hover:hsl(215,80%,88%);--rg-header-text:hsl(77,100%,30%);--rg-rank-slider-track-bg:hsl(215,80%,95%);--rg-rank-slider-border:hsl(215,80%,80%);--rg-rank-slider-range:hsl(215,80%,80%);--rg-rank-slider-handle-bg:hsl(215,80%,95%);--rg-rank-slider-border-focus:hsl(215,80%,60%);--rg-popup-btn-copy:215 75% 45%;--rg-popup-btn-remove:4 90% 45%;--rg-popup-btn-sort:130 50% 35%;--rg-popup-btn-fetch:40 100% 35%;--rg-popup-btn-save:195 75% 40%;--rg-popup-btn-revert:30 100% 40%;--rg-popup-item-new:120 30% 50%;--rg-vocab-badge-bg:hsla(195,75%,40%,.9);--rg-vocab-badge-text:hsl(0,0%,95%);--rg-vocab-play-hover-bg:hsl(30,75%,50%);--rg-playlist-params-color:270 55% 50%;--rg-playlist-active-badge-position:hsl(140,40%,35%);--rg-playlist-active-badge-reps:hsl(40,40%,40%);--rg-playlist-active-badge-cycles:hsl(200,40%,35%);--rg-playlist-active-badge-shuffle:hsl(280,40%,45%);--rg-playlist-entry-play:120 40% 35%;--rg-playlist-entry-skip:30 40% 45%}:root.latest-games-dark-theme{--rg-bg-primary:hsl(210,10%,11%);--rg-bg-secondary:hsl(220,10%,15%);--rg-bg-card:hsl(220,10%,15%);--rg-bg-card-pinned:hsl(140,20%,15%);--rg-bg-hover:hsl(220,10%,15%);--rg-hover-mix-color:hsla(0,0%,100%,.08);--rg-border-primary:hsl(220,10%,15%);--rg-border-hover:hsl(0,0%,38%);--rg-border-pinned:hsl(133,43%,47%);--rg-text-primary:hsl(0,0%,88%);--rg-text-secondary:hsl(0,0%,88%);--rg-text-tertiary:hsl(0,0%,88%);--rg-text-options:hsl(0,0%,88%);--rg-enabled-yellow:#fc0;--rg-bg-enabled-yellow:rgba(255,204,0,.2);--rg-enabled-blue:hsl(207,89%,76%);--rg-bg-enabled-blue:hsla(207,89%,76%,.2);--rg-gametype-voc:hsl(215,80%,65%);--rg-gametype-normal:#6c7;--rg-gametype-abra:hsl(215,20%,60%);--rg-gametype-noerror:hsl(200,45%,65%);--rg-gametype-marathon:hsl(340,70%,55%);--rg-gametype-chars:hsl(35,100%,45%);--rg-gametype-digits:hsl(0,0%,50%);--rg-gametype-sprint:hsl(5,40%,60%);--rg-icon-primary:hsl(207,89%,76%);--rg-icon-delete:hsl(4,100%,75%);--rg-bg-hover-delete:hsla(4,100%,75%,.2);--rg-icon-pin:hsl(133,43%,47%);--rg-bg-hover-pin:hsla(133,43%,47%,.2);--rg-icon-info:hsl(0,0%,88%);--rg-bg-hover-info:hsla(0,0%,88%,.2);--rg-icon-edit:#fc3;--rg-bg-hover-edit:rgba(255,204,51,.2);--rg-icon-theme-sun:#fc0;--rg-icon-theme-moon:hsl(207,89%,76%);--rg-hover-control:hsl(0,0%,38%);--rg-hover-control-btn:hsl(213,81.6%,29.8%);--rg-bg-card-pinned-voc:hsl(215,80%,10%);--rg-border-pinned-voc:hsl(215,80%,30%);--rg-bg-card-pinned-normal:hsl(130,50%,10%);--rg-border-pinned-normal:hsl(130,50%,30%);--rg-bg-card-pinned-abra:hsl(215,20%,10%);--rg-border-pinned-abra:hsl(215,20%,30%);--rg-bg-card-pinned-noerror:hsl(200,45%,10%);--rg-border-pinned-noerror:hsl(200,45%,30%);--rg-bg-card-pinned-marathon:hsl(340,65%,10%);--rg-border-pinned-marathon:hsl(340,65%,30%);--rg-bg-card-pinned-chars:#320;--rg-border-pinned-chars:#960;--rg-bg-card-pinned-digits:hsl(0,0%,10%);--rg-border-pinned-digits:hsl(0,0%,30%);--rg-bg-card-pinned-sprint:hsl(5,40%,10%);--rg-border-pinned-sprint:hsl(5,40%,30%);--rg-bg-tab:hsl(220,10%,15%);--rg-bg-tab-hover:hsl(220,10%,18%);--rg-bg-tab-active:hsl(210,10%,11%);--rg-icon-accent:hsl(207,89%,76%);--rg-qualification-icon:#fc0;--rg-panel-toggle-background:hsl(215,80%,20%);--rg-panel-toggle-stroke:hsl(215,80%,65%);--rg-panel-toggle-border:hsl(215,80%,30%);--rg-panel-toggle-bg-hover:hsl(215,80%,25%);--rg-header-text:#fc0;--rg-rank-slider-track-bg:hsl(215,80%,10%);--rg-rank-slider-border:hsl(215,80%,30%);--rg-rank-slider-range:hsl(215,80%,30%);--rg-rank-slider-handle-bg:hsl(215,80%,10%);--rg-rank-slider-border-focus:hsl(215,80%,50%);--rg-popup-btn-copy:195 53% 79%;--rg-popup-btn-remove:0 90% 75%;--rg-popup-btn-sort:120 90% 70%;--rg-popup-btn-fetch:40 100% 70%;--rg-popup-btn-save:195 100% 70%;--rg-popup-btn-revert:30 100% 70%;--rg-popup-item-new:120 40% 40%;--rg-vocab-badge-bg:hsla(195,100%,70%,.9);--rg-vocab-badge-text:hsl(0,0%,11%);--rg-vocab-play-hover-bg:hsl(30,100%,70%);--rg-playlist-params-color:270 70% 70%;--rg-playlist-active-badge-position:hsl(140,40%,50%);--rg-playlist-active-badge-reps:hsl(40,40%,50%);--rg-playlist-active-badge-cycles:hsl(200,40%,50%);--rg-playlist-active-badge-shuffle:hsl(280,40%,60%);--rg-playlist-entry-play:120 40% 50%;--rg-playlist-entry-skip:30 40% 60%}#latest-games-container{display:flex;flex-direction:column;font-family:"Montserrat",sans-serif;position:fixed;top:50px;width:auto;min-width:200px;max-width:330px;background-color:var(--rg-bg-primary);border:1px solid var(--rg-border-primary);border-left:none;border-radius:0 8px 8px 0 !important;box-shadow:2px 0 10px rgba(0,0,0,.1) !important;z-index:1020;padding:10px 0;opacity:0;pointer-events:none;user-select:none;transition:left .3s ease,opacity .3s ease;overflow:hidden;color:var(--rg-text-primary)}#latest-games-container #latest-games-content{overflow-y:auto;overflow-x:hidden;scrollbar-width:none;height:calc(100% - 40px);width:100%}#latest-games-container.visible{left:0 !important;opacity:1;pointer-events:auto;user-select:auto}#latest-games-container.display-mode-wrap{max-width:none;width:95vw;display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-start;position:fixed}#latest-games-container.display-mode-wrap .latest-games-controls{flex-direction:row}#latest-games-container #latest-games{margin:0;position:relative;padding:0;list-style:none;display:flex;flex-direction:column;gap:5px}#latest-games-container #latest-games .group-header{display:inline-flex;padding:5px 15px;min-height:30px;max-width:300px;font:600 14px "Montserrat",sans-serif;border-radius:4px !important;background:var(--rg-bg-card);color:var(--rg-text-primary);border:2px solid var(--rg-border-primary);cursor:pointer;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:fit-content;transition:border .1s ease,background-color .1s ease;width:100%;margin:0 10px}#latest-games-container #latest-games .group-header:hover,#latest-games-container #latest-games .group-header:focus{border-color:var(--rg-border-hover);background:var(--rg-bg-hover);color:var(--rg-text-primary)}#latest-games-container #latest-games .group-header.active{color:var(--rg-gametype-normal) !important;background-color:var(--rg-bg-card-pinned-normal) !important;border:2px solid var(--rg-border-pinned-normal) !important}#latest-games-container #latest-games .group-header.warning{color:var(--rg-gametype-chars) !important;background-color:var(--rg-bg-card-pinned-chars) !important;border:2px solid var(--rg-border-pinned-chars) !important}#latest-games-container #latest-games .group-header.danger{color:var(--rg-gametype-marathon) !important;background-color:var(--rg-bg-card-pinned-marathon) !important;border:2px solid var(--rg-border-pinned-marathon) !important}#latest-games-container #latest-games.display-mode-wrap{display:flex;flex-direction:row;flex-wrap:wrap;max-height:none;margin:0 10px}#latest-games-container #latest-games.display-mode-wrap .latest-game,#latest-games-container #latest-games.display-mode-wrap .group-header{margin:0 !important;max-width:none}#latest-games-container #latest-games .latest-game{position:relative;margin:0 10px;border:2px solid var(--rg-border-primary);border-radius:4px !important;background-color:var(--rg-bg-card);transition:border .1s ease,background-color .1s ease;display:inline-flex;max-width:300px}#latest-games-container #latest-games .latest-game::after{content:"";position:absolute;inset:0;border-radius:2px;background-color:var(--rg-hover-mix-color);opacity:0;pointer-events:none;transition:opacity .15s ease}#latest-games-container #latest-games .latest-game.pin-game{cursor:move}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-voc{border:2px solid var(--rg-border-pinned-voc);background-color:var(--rg-bg-card-pinned-voc)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-normal{border:2px solid var(--rg-border-pinned-normal);background-color:var(--rg-bg-card-pinned-normal)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-abra{border:2px solid var(--rg-border-pinned-abra);background-color:var(--rg-bg-card-pinned-abra)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-noerror{border:2px solid var(--rg-border-pinned-noerror);background-color:var(--rg-bg-card-pinned-noerror)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-marathon{border:2px solid var(--rg-border-pinned-marathon);background-color:var(--rg-bg-card-pinned-marathon)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-chars{border:2px solid var(--rg-border-pinned-chars);background-color:var(--rg-bg-card-pinned-chars)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-digits{border:2px solid var(--rg-border-pinned-digits);background-color:var(--rg-bg-card-pinned-digits)}#latest-games-container #latest-games .latest-game.pin-game.pin-gametype-sprint{border:2px solid var(--rg-border-pinned-sprint);background-color:var(--rg-bg-card-pinned-sprint)}#latest-games-container #latest-games .latest-game:hover::after{opacity:1}#latest-games-container #latest-games .latest-game.dragging{opacity:.7;z-index:1021;transition:transform .1s ease}#latest-games-container #latest-games .latest-game.display-mode-wrap{margin:0}#latest-games-container #latest-games .latest-game a{display:block;width:100%;padding:5px 15px;text-decoration:none;color:inherit}#latest-games-container #latest-games .latest-game .latest-game-name{display:flex;font-weight:bold;font-size:12px;margin-bottom:2px;align-items:center}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-voc{color:var(--rg-gametype-voc) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-normal{color:var(--rg-gametype-normal) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-abra{color:var(--rg-gametype-abra) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-noerror{color:var(--rg-gametype-noerror) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-marathon{color:var(--rg-gametype-marathon) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-chars{color:var(--rg-gametype-chars) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-digits{color:var(--rg-gametype-digits) !important}#latest-games-container #latest-games .latest-game .latest-game-name.gametype-sprint{color:var(--rg-gametype-sprint) !important}#latest-games-container #latest-games .latest-game .latest-game-description{display:inline-flex;font-size:10px;color:var(--rg-text-secondary)}#latest-games-container #latest-games .latest-game .latest-game-qual,#latest-games-container #latest-games .latest-game .latest-game-state-icon{display:inline-flex;align-items:center;justify-content:center;margin-left:4px}#latest-games-container #latest-games .latest-game .latest-game-qual svg,#latest-games-container #latest-games .latest-game .latest-game-state-icon svg{width:14px;height:14px}#latest-games-container #latest-games .latest-game .latest-game-levels{display:block;font-size:9px;color:var(--rg-text-tertiary);margin-top:1px}#latest-games-container #latest-games .latest-game .latest-game-buttons{position:absolute;display:flex;flex-direction:row;justify-content:center;align-items:center;gap:2px;top:0;right:0;transform:translateY(-100%);background-color:var(--rg-bg-card);border-radius:4px !important;border:2px solid var(--rg-border-primary);box-shadow:0 1px 4px rgba(0,0,0,.2) !important;visibility:hidden}#latest-games-container #latest-games .latest-game:hover .latest-game-buttons{opacity:1}#latest-games-container #latest-games .latest-game .latest-game-pin{width:24px;height:24px;cursor:pointer;border-radius:2px !important;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;background-color:rgba(0,0,0,0)}#latest-games-container #latest-games .latest-game .latest-game-pin:hover{background-color:var(--rg-bg-hover-pin)}#latest-games-container #latest-games .latest-game .latest-game-pin svg{width:16px;height:16px;stroke:var(--rg-icon-pin);fill:none}#latest-games-container #latest-games .latest-game .latest-game-delete{width:24px;height:24px;cursor:pointer;border-radius:2px !important;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;background-color:rgba(0,0,0,0)}#latest-games-container #latest-games .latest-game .latest-game-delete:hover{background-color:var(--rg-bg-hover-delete)}#latest-games-container #latest-games .latest-game .latest-game-delete svg{width:16px;height:16px;stroke:var(--rg-icon-delete);fill:none}#latest-games-container #latest-games .latest-game .latest-game-info{width:24px;height:24px;cursor:pointer;border-radius:2px !important;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;background-color:rgba(0,0,0,0)}#latest-games-container #latest-games .latest-game .latest-game-info:hover{background-color:var(--rg-bg-hover-info)}#latest-games-container #latest-games .latest-game .latest-game-info svg{width:16px;height:16px;stroke:var(--rg-icon-info);fill:none}#latest-games-container #latest-games .latest-game .latest-game-edit{width:24px;height:24px;cursor:pointer;border-radius:2px !important;display:flex;align-items:center;justify-content:center;transition:background-color .2s ease;background-color:rgba(0,0,0,0)}#latest-games-container #latest-games .latest-game .latest-game-edit:hover{background-color:var(--rg-bg-hover-edit)}#latest-games-container #latest-games .latest-game .latest-game-edit svg{width:16px;height:16px;stroke:var(--rg-icon-edit);fill:none}#latest-games-container #latest-games .latest-game.previous-game{animation:tilt-n-move-shaking .3s ease 5}#latest-games-container #latest-games .latest-game.previous-game .latest-game-name,#latest-games-container #latest-games .latest-game.previous-game .latest-game-description{color:var(--rg-bg-card) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-voc){background-color:var(--rg-gametype-voc) !important;border-color:var(--rg-gametype-voc) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-normal){background-color:var(--rg-gametype-normal) !important;border-color:var(--rg-gametype-normal) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-abra){background-color:var(--rg-gametype-abra) !important;border-color:var(--rg-gametype-abra) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-noerror){background-color:var(--rg-gametype-noerror) !important;border-color:var(--rg-gametype-noerror) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-marathon){background-color:var(--rg-gametype-marathon) !important;border-color:var(--rg-gametype-marathon) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-chars){background-color:var(--rg-gametype-chars) !important;border-color:var(--rg-gametype-chars) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-digits){background-color:var(--rg-gametype-digits) !important;border-color:var(--rg-gametype-digits) !important}#latest-games-container #latest-games .latest-game.previous-game:has(.gametype-sprint){background-color:var(--rg-gametype-sprint) !important;border-color:var(--rg-gametype-sprint) !important}#latest-games-container #latest-games .latest-game.dragged-game{animation:tilt-n-move-shaking .3s ease 5}#latest-games-container #latest-games .latest-game.voc-private{border-color:var(--rg-border-pinned-digits) !important;background-color:var(--rg-bg-card-pinned-digits) !important}#latest-games-container #latest-games .latest-game.voc-private .latest-game-name{color:var(--rg-gametype-digits) !important}#latest-games-container #latest-games .latest-game.voc-removed{border-color:var(--rg-border-pinned-marathon) !important;background-color:var(--rg-bg-card-pinned-marathon) !important}#latest-games-container #latest-games .latest-game.voc-removed .latest-game-name{color:var(--rg-gametype-marathon) !important}#latest-games-container #latest-games .latest-game.voc-private.previous-game{background-color:var(--rg-gametype-digits) !important;border-color:var(--rg-gametype-digits) !important}#latest-games-container #latest-games .latest-game.voc-private.previous-game .latest-game-name,#latest-games-container #latest-games .latest-game.voc-private.previous-game .latest-game-description{color:var(--rg-bg-card) !important}#latest-games-container #latest-games .latest-game.voc-removed.previous-game{background-color:var(--rg-gametype-marathon) !important;border-color:var(--rg-gametype-marathon) !important}#latest-games-container #latest-games .latest-game.voc-removed.previous-game .latest-game-name,#latest-games-container #latest-games .latest-game.voc-removed.previous-game .latest-game-description{color:var(--rg-bg-card) !important}#latest-games-container .latest-games-controls{display:flex;flex-direction:column;align-items:flex-start;padding:0 10px 10px;top:0;position:sticky;width:100%;z-index:10;background-color:var(--rg-bg-primary);border-bottom:1px solid var(--rg-border-primary)}#latest-games-container .latest-games-controls .controls-buttons{gap:2px;display:flex;flex-wrap:wrap;position:relative}#latest-games-container .latest-games-controls .controls-buttons .controls-visible{display:flex;gap:6px;align-items:center;flex-basis:100%}#latest-games-container .latest-games-controls .controls-buttons .controls-limiter{width:100%;display:flex;justify-content:center;gap:8px;align-items:center;padding-bottom:6px;border-bottom:1px solid var(--rg-border-primary)}#latest-games-container .latest-games-controls .controls-buttons .controls-more{display:none;position:absolute;left:0;top:100%;margin-top:6px;background:var(--rg-bg-card);padding:8px;border-radius:8px !important;border:1px solid var(--rg-border-primary);box-shadow:0 6px 18px rgba(0,0,0,.15);flex-wrap:wrap;gap:6px;z-index:2000}#latest-games-container .latest-games-controls .controls-buttons .controls-more.open{display:flex}#latest-games-container .latest-games-controls .controls-buttons .latest-games-more-toggle{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:4px !important;background:rgba(0,0,0,0)}#latest-games-container .latest-games-controls .controls-buttons .latest-games-more-toggle.open{color:var(--rg-enabled-yellow)}#latest-games-container .latest-games-controls .controls-buttons .latest-games-replay.replay-next-game,#latest-games-container .latest-games-controls .controls-buttons .latest-games-random.random-global{background-color:var(--rg-bg-enabled-yellow)}#latest-games-container .latest-games-controls .controls-buttons .latest-games-replay.replay-next-game svg,#latest-games-container .latest-games-controls .controls-buttons .latest-games-random.random-global svg{stroke:var(--rg-enabled-yellow)}#latest-games-container #latest-games-options{display:flex;align-items:center;font-size:13px;gap:5px;color:var(--rg-text-options);user-select:none}#latest-games-container #latest-games-count{margin:0 6px;font-weight:bold;font-size:14px;min-width:18px;text-align:center;color:var(--rg-enabled-yellow);cursor:pointer}#latest-games-container #latest-games-count-inc,#latest-games-container #latest-games-count-dec{height:24px;width:24px;cursor:pointer;font-size:16px;border-radius:3px !important;transition:background .15s;user-select:none;display:flex;align-items:center;justify-content:center;color:var(--rg-icon-primary)}#latest-games-container #latest-games-count-inc:hover,#latest-games-container #latest-games-count-dec:hover{background:var(--rg-hover-control-btn)}#latest-games-container #latest-games-count-inc svg,#latest-games-container #latest-games-count-dec svg{width:16px;height:16px}#latest-games-container .theme-toggle,#latest-games-container .display-mode-toggle,#latest-games-container .control-button{cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:3px !important;width:24px;height:24px;background-color:rgba(0,0,0,0);border-radius:4px;transition:background .15s;user-select:none}#latest-games-container .theme-toggle svg,#latest-games-container .display-mode-toggle svg,#latest-games-container .control-button svg{width:16px;height:16px;display:block;transition:stroke .2s,fill .2s}#latest-games-container .theme-toggle svg.feather-sun,#latest-games-container .display-mode-toggle svg.feather-sun,#latest-games-container .control-button svg.feather-sun{stroke:var(--rg-icon-theme-sun);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}#latest-games-container .theme-toggle svg.feather-moon,#latest-games-container .display-mode-toggle svg.feather-moon,#latest-games-container .control-button svg.feather-moon{stroke:var(--rg-icon-theme-moon);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}#latest-games-container .control-button{box-sizing:border-box}#latest-games-container .control-button svg{pointer-events:none}#latest-games-container #latest-games-groups{display:flex;flex-direction:column;align-items:start;margin-bottom:0}#latest-games-container #latest-games-groups .tabs-container{display:inline-flex;flex-direction:row;gap:5px;flex-wrap:wrap;align-items:center;margin:0 10px 10px}#latest-games-container #latest-games-groups .group-tab{display:inline-flex;padding:5px 15px;min-height:30px;max-width:300px;font:600 14px "Montserrat",sans-serif;border-radius:4px !important;background:var(--rg-bg-card);color:var(--rg-text-primary);border:2px solid var(--rg-border-primary);cursor:pointer;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:fit-content;transition:border .1s ease,background-color .1s ease}#latest-games-container #latest-games-groups .group-tab:hover,#latest-games-container #latest-games-groups .group-tab:focus{border-color:var(--rg-border-hover);background:var(--rg-bg-hover);color:var(--rg-text-primary)}#latest-games-container #latest-games-groups .group-tab.active{color:var(--rg-gametype-normal) !important;background-color:var(--rg-bg-card-pinned-normal) !important;border:2px solid var(--rg-border-pinned-normal) !important}#latest-games-container #latest-games-groups .group-tab.warning{color:var(--rg-gametype-chars) !important;background-color:var(--rg-bg-card-pinned-chars) !important;border:2px solid var(--rg-border-pinned-chars) !important}#latest-games-container #latest-games-groups .group-tab.danger{color:var(--rg-gametype-marathon) !important;background-color:var(--rg-bg-card-pinned-marathon) !important;border:2px solid var(--rg-border-pinned-marathon) !important}#latest-games-container #latest-games-groups .group-controls{gap:2px;display:inline-flex;align-items:center;padding:10px}#latest-games-container .group-tab.previous-game-group,#latest-games-container .group-header.previous-game-group{color:var(--rg-gametype-chars) !important;background-color:var(--rg-bg-card-pinned-chars) !important;border:2px solid var(--rg-border-pinned-chars) !important}#latest-games-container .resize-handle-horizontal{position:absolute;top:0;bottom:0;right:0;width:4px;height:100%;cursor:ew-resize;background:rgba(0,0,0,0);z-index:1021;border-radius:4px 0 0 4px;transition:background .2s}#latest-games-container .resize-handle-horizontal:hover{background-color:rgba(0,0,0,.18)}#latest-games-container .resize-handle-vertical{position:absolute;left:0;right:0;width:100%;height:4px;cursor:ns-resize;background-color:rgba(0,0,0,0);z-index:1021;border-radius:0 0 4px 4px;transition:background .2s}#latest-games-container .resize-handle-vertical:hover{background-color:rgba(0,0,0,.18)}#latest-games-container .resize-handle-vertical-top{top:0}#latest-games-container .resize-handle-vertical-bottom{bottom:0}#latest-games-container #latest-games.display-mode-wrap .drop-indicator{border-left:2px solid var(--rg-gametype-voc)}#latest-games-hover-area{position:fixed;left:0;top:0;width:4px;height:100vh;z-index:1023;background-color:rgba(0,0,0,0);pointer-events:auto}.latest-games-panel-toggle{position:fixed;left:0;top:50%;transform:translateY(-50%);z-index:1024;background:var(--rg-panel-toggle-background);border:2px solid var(--rg-panel-toggle-border);border-radius:0 .5em .5em 0 !important;box-shadow:0 2px 8px rgba(0,0,0,.15) !important;width:40px;height:40px;display:flex;justify-content:center;align-items:center;cursor:pointer;transition:background .2s;outline:none}.latest-games-panel-toggle:hover,.latest-games-panel-toggle:focus{background:var(--rg-panel-toggle-bg-hover)}.latest-games-panel-toggle svg{stroke:var(--rg-panel-toggle-stroke);width:1.5em;height:1.5em;display:block;pointer-events:none}.custom-tooltip-popup{position:fixed;background:#161616;color:#dedede;padding:.5em;z-index:2010 !important;font-size:.9em;font-family:"Montserrat","Noto Color Emoji",sans-serif !important;pointer-events:none;white-space:nowrap;opacity:0;transition:opacity .1s;display:none;flex-direction:column;left:0;top:0;border:1px solid #3c3c3c !important;border-radius:4px !important;box-shadow:0 2px 5px rgba(0,0,0,.3) !important}.custom-tooltip-popup .tooltip-item{display:inline-flex !important;align-items:center !important}.custom-tooltip-popup .tooltip-header{font-weight:500 !important;color:gray !important;margin:.5em !important}.custom-tooltip-popup .tooltip-action{font-weight:500 !important;color:#add8e6 !important}.custom-tooltip-popup .tooltip-state--on{color:#4caf50;font-weight:600}.custom-tooltip-popup .tooltip-state--off{color:#f44336;font-weight:600}.latest-games-disabled{background-color:rgba(0,0,0,0) !important;filter:grayscale(1);opacity:.5}.latest-games-hidden{display:none !important}@keyframes tilt-n-move-shaking{0%{transform:translate(0, 0) rotate(0deg)}25%{transform:translate(4px, 0) rotate(2deg)}50%{transform:translate(0, 0) rotate(0eg)}75%{transform:translate(-4px, 0) rotate(-2deg)}100%{transform:translate(0, 0) rotate(0deg)}}',""]);const i=s}},t={};function a(r){var o=t[r];if(void 0!==o)return o.exports;var n=t[r]={id:r,exports:{}};return e[r](n,n.exports,a),n.exports}a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.nc=void 0;var r=a(72),o=a.n(r),n=a(825),s=a.n(n),i=a(659),l=a.n(i),p=a(56),c=a.n(p),d=a(540),g=a.n(d),u=a(113),m=a.n(u),h=a(911),y={};y.styleTagTransform=m(),y.setAttributes=c(),y.insert=l().bind(null,"head"),y.domAPI=s(),y.insertStyleElement=g();o()(h.A,y);h.A&&h.A.locals&&h.A.locals;const v={montserrat:{id:"kg-latest-games-montserrat-font",url:"https://fonts.googleapis.com/css2?family=Montserrat&display=swap"},notoColorEmoji:{id:"kg-latest-games-noto-emoji-font",url:"https://fonts.googleapis.com/css2?family=Montserrat&family=Noto+Color+Emoji&display=swap"}};const b="☀️",f="📅",x="📋",w="📜",k="💬",C="⚡",M={normal:"Oбычный",abra:"Абракадабра",noerror:"Безошибочный",marathon:"Марафон",chars:"Буквы",digits:"Цифры",sprint:"Спринт",voc:"Словарь"},S={words:"Слова",phrases:"Фразы",texts:"Тексты",book:"Книги"},L={Слова:"words",Фразы:"phrases",Тексты:"texts",Книга:"books",Генератор:"generator"},E={normal:"открытый",practice:"одиночный",private:"дружеский"},I=["новички","любители","таксисты","профи","гонщики","маньяки","супермены","кибергонщики","экстракиберы"],G={новичков:1,любителей:2,таксистов:3,профи:4,гонщиков:5,маньяков:6,суперменов:7,кибергонщиков:8,экстракиберов:9},T={immediate:"#typeblock #bookinfo",normal:"#status-inner #finished"},N={noError:".player.you img.noerror-fail"},$=[5,10,20,30,45,60],D=[0,5,10,15,20,30,45,60,120,180,300],P={maxGameCount:5,currentTheme:"light",displayMode:"scroll",previousScrollPosition:0,panelWidth:"70vw",panelHeight:"40vh",panelWidths:{},panelHeights:{},hoverTimeout:null,isHovered:!1,enableDragging:!0,wasDragging:!1,shouldAutoSave:!0,hidePanelDelay:1e3,shouldStart:!1,startDelay:1e3,shouldReplay:!1,replayDelay:1e3,replayNextGame:!0,shouldReplayMore:!1,replayNextGameCount:1,remainingReplayCount:null,replayWithoutWaiting:!0,randomGameId:!1,randomVocabulariesType:{words:!0,phrases:!0,texts:!0,books:!0,generator:!0},showSearchBox:!1,randomLocalExcludePlayed:!0,randomLocalByActiveGroup:!1,randomLocalIncludeStandardModes:!1,showButtonDescriptions:!0,showHelpTooltips:!0,qualificationEnabled:!1,saveModeEnabled:!0,showVocabularyData:!0,rankRange:[1,9],playlistPanelAutoOpen:0,panelYPosition:{main:0,gamelist:0,profile:0,chatlogs:0,rating:0,vocabularies:0,about:0,donation:0,forum:0,game:0},alwaysVisiblePanel:{main:!1,gamelist:!1,profile:!1,chatlogs:!1,rating:!1,vocabularies:!1,about:!1,donation:!1,forum:!1,game:!1}},A="http://www.w3.org/2000/svg",H={sun:`\n \n \n \n \n \n \n \n \n \n \n \n `,moon:`\n \n \n \n `,delete:`\n \n \n \n \n `,chevronLeft:`\n \n \n \n `,chevronRight:`\n \n \n \n `,chevronsRight:`\n \n \n \n \n `,play:`\n \n \n \n `,replay:`\n \n \n \n \n `,replayImmediately:`\n \n \n \n \n \n `,replayMore:`\n \n \n \n \n `,pin:`\n \n \n \n \n `,unpin:`\n \n \n \n \n `,sort:`\n \n \n \n \n \n `,import:`\n \n \n \n \n \n `,export:`\n \n \n \n \n \n `,trashNothing:`\n \n \n \n \n `,trashSomething:`\n \n \n \n \n \n \n `,wrap:`\n \n \n \n \n \n \n `,scroll:`\n \n \n \n \n \n `,rename:`\n \n \n \n `,qualification:`\n \n \n \n \n `,panelToggleClosed:`\n \n \n \n \n `,panelToggleOpened:`\n \n \n \n \n `,moreHorizontal:`\n \n \n \n \n \n `,broom:`\n \n \n \n \n \n `,checkmark:`\n \n \n \n `,drag:`\n \n \n \n \n \n \n \n \n `,dragable:`\n \n \n \n `,search:`\n \n \n \n \n `,info:`\n \n \n \n \n \n `,help:`\n \n \n \n \n \n `,save:`\n \n \n \n \n \n `,parameters:`\n \n \n \n \n \n \n \n \n \n \n \n `,refresh:`\n \n \n \n \n \n `,reset:`\n \n \n \n \n \n `,copy:`\n \n \n \n \n `,paused:`\n \n \n \n `,playing:`\n \n \n \n `,start:`\n \n \n \n `,pause:`\n \n \n \n \n \n `,stop:`\n \n \n \n `,random:`\n \n \n \n \n \n \n \n `,slash:`\n \n \n \n \n `,book:`\n \n \n \n \n `,vocabularyData:`\n \n \n \n \n \n \n \n `,playlists:`\n \n \n \n `,plus:`\n \n \n \n \n `,minus:`\n \n \n \n `,x:`\n \n \n \n \n `,arrowGoBack:`\n \n \n \n `};let q=null,_=null,B=null,V=!1,R=!1,j=null,O=null;const z=e=>{if("info"===e){return!0===(()=>{if(null===O)try{const e=localStorage.getItem("latestGamesSettings");O=e?JSON.parse(e):{}}catch(e){console.warn("Failed to parse latestGamesSettings from localStorage:",e),O={}}return O})().showHelpTooltips}return!0},Y=(e,t)=>{if(!q)return;let a=e+10;const r=q.offsetWidth,o=window.innerWidth;a=Math.min(Math.max(a,10),o-r-10),q.style.left=`${a}px`,q.style.top=`${t+18}px`},W=e=>q&&Y(e.clientX,e.clientY);function K(){V=!1,j=null,clearTimeout(B),clearTimeout(_),_=setTimeout((()=>{q&&(q.style.opacity="0",R=!1,setTimeout((()=>{!V&&q&&(q.style.display="none",q.textContent="",document.removeEventListener("mousemove",W))}),50))}),100)}function F(e,t,a="info"){null!=t&&z(a)&&(e._tooltipContent=t,e._tooltipType=a,j===e&&V&&q&&(clearTimeout(B),q.innerHTML=Z(t),q.style.display="flex",q.style.opacity="1",R=!0),e._tooltipInitialized||(e._tooltipInitialized=!0,q||=(()=>{const e=document.createElement("div");return e.classList.add("custom-tooltip-popup"),e.style.display="none",e.style.opacity="0",document.body.appendChild(e),e})(),e.addEventListener("mouseenter",(t=>{if(!z(e._tooltipType||"info"))return;V=!0,j=e,clearTimeout(_),clearTimeout(B),q.innerHTML=Z(e._tooltipContent),q.style.display="flex",Y(t.clientX,t.clientY),document.addEventListener("mousemove",W);const a=!!e.closest(".latest-game")&&!e.closest(".latest-game-buttons");if(R&&!a)q.style.opacity="1";else{const e=a?1200:150;q.style.opacity="0",q.offsetHeight,B=setTimeout((()=>{q.style.opacity="1",R=!0}),e)}})),e.addEventListener("mouseleave",(()=>{K(),document.removeEventListener("mousemove",W)}))))}function X(e,t,a="info"){e._tooltipInitialized?z(a)&&(e._tooltipContent=t,e._tooltipType=a,j===e&&V&&q&&(q.innerHTML=Z(t),R||"stats"!==a||(clearTimeout(B),q.style.opacity="1",R=!0))):F(e,t,a)}new MutationObserver((()=>{j&&!document.contains(j)&&K()})).observe(document,{childList:!0,subtree:!0});const J=[{prefixes:["Включен","Активн"],className:"tooltip-state--on"},{prefixes:["Отключен","Неактивн"],className:"tooltip-state--off"}];function U(e){let t=e;return J.forEach((({prefixes:e,className:a})=>{e.forEach((e=>{const r=new RegExp(`(?`${o} ${e}`))}))})),t}function Z(e){let t="";const a=/\[([^\]]+)\]([^\[]*)(?:\[\]([^\[]*))?/g;return e.split(/(## [^[]*)/g).forEach((e=>{if(e.startsWith("## ")){const a=e.slice(3).trim();t+=`
${a}
`}else{a.lastIndex=0;const r=[...e.matchAll(a)];r.length?r.forEach((e=>{const a=e[1],[r,...o]=e[2].trim().split("||").map((e=>e.trim()));t+=`\n
\n ${a} \n ${U(r)}\n
\n ${o.map((e=>`
${U(e)}
`)).join("")}`})):e.trim()&&(t+=`\n
\n ${U(e.trim())}\n
`)}})),t}function Q(){return Array.from(crypto.getRandomValues(new Uint8Array(32))).map((e=>(e%36).toString(36))).join("")}function ee(e){const t=new Set([...e.map((e=>e.id)),...e.flatMap((e=>e.games.map((e=>e.id))))]);let a;do{a=Q()}while(t.has(a));return a}function te(e){let t,a,r=Date.now(),o=e,n=!1;const s=new Promise((r=>{a=r,t=setTimeout(r,e)}));return s.cancel=()=>{t&&(clearTimeout(t),t=null)},s.pause=()=>{!n&&t&&(n=!0,clearTimeout(t),t=null,o=Math.max(0,o-(Date.now()-r)))},s.resume=()=>{n&&(n=!1,r=Date.now(),t=setTimeout(a,o))},s.getRemainingMs=()=>n?o:Math.max(0,o-(Date.now()-r)),s}function ae(){const e=window.location.pathname;return"/"===e?"main":"/gamelist/"===e?"gamelist":"/u/"===e?"profile":e.startsWith("/chatlogs/")?"chatlogs":e.startsWith("/top/")?"rating":e.startsWith("/vocs/")?"vocabularies":"/about/"===e?"about":"/fuel/"===e?"donation":e.startsWith("/forum/")?"forum":"/g/"===e?"game":"unknown"}function re(e,t={}){const a=document.createElement(e);return t.className&&(a.className=t.className),t.id&&(a.id=t.id),t.innerHTML&&(a.innerHTML=t.innerHTML),void 0!==t.textContent&&null!==t.textContent&&(a.textContent=t.textContent),t.href&&(a.href=t.href),t.title&&(a.title=t.title),t.src&&(a.src=t.src),t.style&&Object.assign(a.style,t.style),t.attributes&&Object.entries(t.attributes).forEach((([e,t])=>{a.setAttribute(e,t)})),a}function oe(){const e=ae();return"vocabularies"===e?".columns.voclist":"profile"===e?".profile-root, .dlg-profile-vocs .vocs":"forum"===e?"#posts-list .list":"gamelist"===e?"#gamelist":"game"===e?"#gamedesc":null}function ne(e){const t=e.getAttribute("href");if(/\/create\//.test(t)){const e=t.match(/[?&]voc=(\d+)/);return e?e[1]:null}try{const e=new URL(t,window.location.origin),a=e.pathname.match(/^\/vocs\/(\d+)\/?$/);return a?a[1]:null}catch(e){return null}}function se(){const e=document.querySelector("#gamedesc");if(!e)return{category:"default",subtype:"Unknown"};const t=e.textContent.toLowerCase(),a=e.querySelector("span");if(!a)return{category:"default",subtype:"Unknown"};const r=a.className.match(/gametype-(\w+)/),o=r?r[1]:null,n=o&&M[o]||"Unknown";if(t.includes("соревнование"))return{category:"competition",subtype:n};if(t.includes("квалификация"))return{category:"qualification",subtype:n};if("voc"===o){if(e.querySelector('a[href*="/vocs/"]'))return{category:"vocabulary",subtype:n}}return{category:"default",subtype:n}}function ie(e,t){return 403===e.status||t.includes("Словарь не найден")}class le{constructor(e){this.main=e}applyTheme(){document.documentElement.classList.remove("latest-games-light-theme","latest-games-dark-theme"),document.documentElement.classList.add("light"===this.main.currentTheme?"latest-games-light-theme":"latest-games-dark-theme"),this.updateThemeIcon()}updateThemeIcon(){const e=document.querySelector("#latest-games-container .theme-toggle");e&&(e.innerHTML="light"===this.main.currentTheme?H.sun:H.moon)}toggleTheme(e){this.main.currentTheme="light"===this.main.currentTheme?"dark":"light",F(e,"Изменить тему на "+("light"===this.main.currentTheme?"тёмную":"светлую")),this.main.settingsManager.saveSettings(),this.applyTheme()}createThemeToggle(){const e=re("div",{className:"theme-toggle control-button"});return e.innerHTML="light"===this.main.currentTheme?H.sun:H.moon,e.addEventListener("click",(()=>this.toggleTheme(e))),F(e,"Изменить тему на "+("light"===this.main.currentTheme?"тёмную":"светлую")),e}}class pe{constructor(e){this.main=e}loadSettings(){try{const e=JSON.parse(localStorage.getItem("latestGamesSettings")||"{}");this.main.maxGameCount=e.maxGameCount??this.main.maxGameCount,this.main.currentTheme=e.currentTheme??this.main.currentTheme,this.main.displayMode=e.displayMode??this.main.displayMode,this.main.groupsManager.groupViewMode=e.groupViewMode??this.main.groupsManager.groupViewMode,this.main.previousScrollPosition=e.previousScrollPosition??this.main.previousScrollPosition,this.main.enableDragging=e.enableDragging??this.main.enableDragging,this.main.shouldAutoSave=e.shouldAutoSave??this.main.shouldAutoSave,this.main.hidePanelDelay=e.hidePanelDelay??this.main.hidePanelDelay,this.main.shouldStart=e.shouldStart??this.main.shouldStart,this.main.startDelay=e.startDelay??this.main.startDelay,this.main.shouldReplay=e.shouldReplay??this.main.shouldReplay,this.main.replayDelay=e.replayDelay??this.main.replayDelay,this.main.replayNextGame=e.replayNextGame??this.main.replayNextGame,this.main.shouldReplayMore=e.shouldReplayMore??this.main.shouldReplayMore,this.main.replayNextGameCount=e.replayNextGameCount??this.main.replayNextGameCount,this.main.remainingReplayCount=null!=e.remainingReplayCount?e.remainingReplayCount:this.main.replayNextGameCount,this.main.replayWithoutWaiting=e.replayWithoutWaiting??this.main.replayWithoutWaiting,this.main.showSearchBox=e.showSearchBox??this.main.showSearchBox,this.main.showButtonDescriptions=e.showButtonDescriptions??this.main.showButtonDescriptions,this.main.showHelpTooltips=e.showHelpTooltips??this.main.showHelpTooltips,this.main.randomGameId=e.randomGameId??this.main.randomGameId,this.main.randomLocalExcludePlayed=e.randomLocalExcludePlayed??this.main.randomLocalExcludePlayed,this.main.randomLocalByActiveGroup=e.randomLocalByActiveGroup??this.main.randomLocalByActiveGroup,this.main.randomLocalIncludeStandardModes=e.randomLocalIncludeStandardModes??this.main.randomLocalIncludeStandardModes,this.main.qualificationEnabled=e.qualificationEnabled??this.main.qualificationEnabled,this.main.saveModeEnabled=e.saveModeEnabled??this.main.saveModeEnabled,this.main.rankRange=e.rankRange??this.main.rankRange,this.main.showVocabularyData=e.showVocabularyData??this.main.showVocabularyData,this.main.playlistPanelAutoOpen=e.playlistPanelAutoOpen??this.main.playlistPanelAutoOpen,this.loadValidVocabularies(),e.randomVocabulariesType&&"object"==typeof e.randomVocabulariesType&&(this.main.randomVocabulariesType={...this.main.randomVocabulariesType,...e.randomVocabulariesType}),e.panelYPosition&&"object"==typeof e.panelYPosition&&(this.main.panelYPosition={...this.main.panelYPosition,...e.panelYPosition}),e.panelWidths&&"object"==typeof e.panelWidths&&(this.main.panelWidths={...this.main.panelWidths,...e.panelWidths}),e.panelHeights&&"object"==typeof e.panelHeights&&(this.main.panelHeights={...this.main.panelHeights,...e.panelHeights}),e.alwaysVisiblePanel&&"object"==typeof e.alwaysVisiblePanel&&(this.main.alwaysVisiblePanel={...this.main.alwaysVisiblePanel,...e.alwaysVisiblePanel})}catch(e){console.warn("Could not load settings from localStorage:",e)}}loadValidVocabularies(){try{const e=localStorage.getItem("validVocabularies");if(e){const t=JSON.parse(e);if(!t||"object"!=typeof t||Array.isArray(t))return void(this.main.validVocabularies={});const a={};for(const[e,r]of Object.entries(t))Array.isArray(r)&&(a[e]=this._normalizeVocabList(r));try{const e=localStorage.getItem("bannedVocabularies"),t=localStorage.getItem("playedVocabularies"),r=e?JSON.parse(e):[],o=t?JSON.parse(t):[];if(Array.isArray(r)||Array.isArray(o)){const e=Array.isArray(r)?r.map((e=>"string"==typeof e?e:"object"==typeof e&&null!==e&&e.id||String(e))):[],t=Array.isArray(o)?o.map((e=>"string"==typeof e?e:"object"==typeof e&&null!==e&&e.id||String(e))):[],n=new Set(e.map((e=>String(e)))),s=new Set(t.map((e=>String(e)))),i=new Set([...n,...s]),l={};for(const[e,t]of Object.entries(a))l[e]=t.filter((e=>!i.has(String(e))));const p=Object.values(l).flat().length,c=Object.values(a).flat().length;if(0===p&&c>0){if(confirm("Все доступные словари уже были проиграны. Очистить данные о проигранных словарях и начать заново?")){localStorage.removeItem("playedVocabularies");const e={};for(const[t,r]of Object.entries(a))e[t]=r.filter((e=>!n.has(String(e))));this.main.validVocabularies=e}else this.main.validVocabularies={};return}return void(this.main.validVocabularies=l)}}catch(e){console.warn("Could not parse banned/played vocabularies from localStorage",e)}return void(this.main.validVocabularies=a)}}catch(e){console.warn("Could not parse validVocabularies from localStorage",e)}this.main.validVocabularies={}}saveValidVocabularies(e){try{let t;if(Array.isArray(e))t={all:this._normalizeVocabList(e)};else if(e&&"object"==typeof e){t={};for(const[a,r]of Object.entries(e))Array.isArray(r)&&(t[a]=this._normalizeVocabList(r))}else t={};return localStorage.setItem("validVocabularies",JSON.stringify(t)),this.main.validVocabularies=t,this.main.uiManager&&"function"==typeof this.main.uiManager.refreshContainer&&this.main.uiManager.refreshContainer(),t}catch(e){return console.warn("Could not save validVocabularies to localStorage",e),{}}}_normalizeVocabList(e){const t=new Set,a=[];for(let r of e){if(null==r)continue;if("string"==typeof r&&(r=r.trim()),""===r||null==r)continue;if(!/^\d+$/.test(String(r)))continue;const e=String(r);t.has(e)||(t.add(e),a.push(r))}return a}saveSettings(){try{const e={maxGameCount:this.main.maxGameCount,currentTheme:this.main.currentTheme,displayMode:this.main.displayMode,groupViewMode:this.main.groupsManager.groupViewMode,previousScrollPosition:this.main.previousScrollPosition,panelWidths:this.main.panelWidths,panelHeights:this.main.panelHeights,panelYPosition:this.main.panelYPosition,enableDragging:this.main.enableDragging,shouldAutoSave:this.main.shouldAutoSave,hidePanelDelay:this.main.hidePanelDelay,shouldStart:this.main.shouldStart,startDelay:this.main.startDelay,shouldReplay:this.main.shouldReplay,replayDelay:this.main.replayDelay,replayNextGame:this.main.replayNextGame,shouldReplayMore:this.main.shouldReplayMore,replayNextGameCount:this.main.replayNextGameCount,remainingReplayCount:this.main.remainingReplayCount,replayWithoutWaiting:this.main.replayWithoutWaiting,showSearchBox:this.main.showSearchBox,showButtonDescriptions:this.main.showButtonDescriptions,showHelpTooltips:this.main.showHelpTooltips,randomLocalExcludePlayed:this.main.randomLocalExcludePlayed,randomLocalByActiveGroup:this.main.randomLocalByActiveGroup,randomLocalIncludeStandardModes:this.main.randomLocalIncludeStandardModes,qualificationEnabled:this.main.qualificationEnabled,saveModeEnabled:this.main.saveModeEnabled,showVocabularyData:this.main.showVocabularyData,rankRange:this.main.rankRange,randomGameId:this.main.randomGameId,randomVocabulariesType:this.main.randomVocabulariesType,alwaysVisiblePanel:this.main.alwaysVisiblePanel,playlistPanelAutoOpen:this.main.playlistPanelAutoOpen};localStorage.setItem("latestGamesSettings",JSON.stringify(e))}catch(e){console.warn("Could not save settings to localStorage:",e)}}async importSettings(e){const t=document.createElement("input");t.type="file",t.accept=".json,application/json",t.style.display="none",t.onchange=async t=>{const a=t.target.files[0];if(a)try{const t=await a.text(),r=JSON.parse(t);"object"==typeof r&&null!==r?(r.validVocabularies&&localStorage.setItem("validVocabularies",JSON.stringify(r.validVocabularies)),r.bannedVocabularies&&localStorage.setItem("bannedVocabularies",JSON.stringify(r.bannedVocabularies)),r.playedVocabularies&&localStorage.setItem("playedVocabularies",JSON.stringify(r.playedVocabularies)),r.latestGamesSettings&&localStorage.setItem("latestGamesSettings",JSON.stringify(r.latestGamesSettings)),r.latestGamesData&&localStorage.setItem("latestGamesData",JSON.stringify(r.latestGamesData)),r.latestGamesPlaylists&&localStorage.setItem("latestGamesPlaylists",JSON.stringify(r.latestGamesPlaylists)),e.settingsManager.loadSettings(),e.gamesManager.loadGameData(),e.uiManager.refreshContainer(),e.themeManager.applyTheme()):alert("Файл не содержит валидный JSON настроек.")}catch(e){alert("Ошибка при импорте: "+e)}},document.body.appendChild(t),t.click(),setTimeout((()=>t.remove()),1e3)}exportSettings(e){const t={latestGamesSettings:JSON.parse(localStorage.getItem("latestGamesSettings")||"{}"),latestGamesData:{groups:e.groupsManager.groups,currentGroupId:e.groupsManager.currentGroupId},latestGamesPlaylists:JSON.parse(localStorage.getItem("latestGamesPlaylists")||"[]"),validVocabularies:JSON.parse(localStorage.getItem("validVocabularies")||"[]"),bannedVocabularies:JSON.parse(localStorage.getItem("bannedVocabularies")||"[]"),playedVocabularies:JSON.parse(localStorage.getItem("playedVocabularies")||"[]")},a=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),r=URL.createObjectURL(a),o=document.createElement("a");o.href=r,o.download="kg-latest-games-settings.json",document.body.appendChild(o),o.click(),setTimeout((()=>{URL.revokeObjectURL(r),o.remove()}),1e3)}removeAllSettings(e){localStorage.removeItem("latestGamesSettings"),localStorage.removeItem("latestGamesData"),e.groupsManager.groups=[e.groupsManager.createGroup("Группа-1")],e.groupsManager.currentGroupId=e.groupsManager.groups[0].id,e.gamesManager.saveGameData(),e.uiManager.refreshContainer()}}class ce{constructor(e){this.main=e,this.groups=[],this.currentGroupId=null,this.groupViewMode="tabs"}createGroup(e){let t;if(e&&e.trim())t=e.trim();else{let e,a=1;do{e="Группа-"+a++}while(this.groups.some((t=>t.title===e)));t=e}return{id:ee(this.groups),title:t,games:[]}}renameGroup(e,t){const a=this.groups.find((t=>t.id===e));a&&(a.title=t)}removeGroup(e){const t=this.groups.findIndex((t=>t.id===e));return-1!==t&&this.groups.splice(t,1),this.groups}initializeGroups(){if(0===this.groups.length){const e=this.createGroup();this.groups=[e],this.currentGroupId=e.id}else this.currentGroupId&&this.groups.some((e=>e.id===this.currentGroupId))||(this.currentGroupId=this.groups[0].id)}getCurrentGroup(){return this.groups.find((e=>e.id===this.currentGroupId))||null}setGroups(e,t){this.groups=e,this.currentGroupId=t}setGroupViewMode(e){this.groupViewMode=e}getGroupViewMode(){return this.groupViewMode}createGroupViewToggle(){const e=re("div",{className:"group-view-toggle control-button"});return e.innerHTML="tabs"===this.groupViewMode?H.wrap:H.scroll,F(e,"tabs"===this.groupViewMode?"Переключить в единый вид со всеми играми":"Переключить в режим вкладок по группам"),e.addEventListener("click",(()=>{this.groupViewMode="tabs"===this.groupViewMode?"unified":"tabs",this.main.settingsManager.saveSettings(),this.updateGroupViewToggle(e),this.main.uiManager.refreshContainer()})),e}updateGroupViewToggle(e){e.innerHTML="tabs"===this.groupViewMode?H.wrap:H.scroll,F(e,"tabs"===this.groupViewMode?"Переключить в единый вид со всеми играми":"Переключить в режим вкладок по группам")}moveGroup(e){const t=this.groups.findIndex((e=>e.id===this.currentGroupId));if(-1===t)return;const a=t+e;if(a<0||a>=this.groups.length)return;const r=this.groups[t];this.groups[t]=this.groups[a],this.groups[a]=r,this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer()}updateGroupControlStates(){const e=document.querySelector(".move-group-left"),t=document.querySelector(".move-group-right");if(e&&t){const a=this.groups.findIndex((e=>e.id===this.currentGroupId)),r=0===a,o=a===this.groups.length-1;e.classList.toggle("latest-games-disabled",r),t.classList.toggle("latest-games-disabled",o)}}createGroupHeader(e){const t=re("div",{className:this.getGroupClass(e,"group-header"),textContent:e.title,dataset:{groupId:e.id}});return t.addEventListener("click",(()=>this.selectGroup(e.id))),t.className.includes("previous-game-group")&&F(t,"В этой группе находится последняя сыгранная игра"),t}createGroupTab(e){const t=re("span",{className:this.getGroupClass(e,"group-tab"),textContent:e.title,dataset:{groupId:e.id}});return t.addEventListener("click",(()=>this.selectGroup(e.id))),t.className.includes("previous-game-group")&&F(t,"В этой группе находится последняя сыгранная игра"),t}getGroupClass(e,t=""){const a=e.id===this.currentGroupId,r=this.main.gamesManager.latestGamesData?.previousGameId;return`${t}${a?" active":""}${e.games.some((e=>e.id===r))&&!a?" previous-game-group":""}`.trim()}createGroupsContainer(){const e=re("div",{id:"latest-games-groups"}),t=re("div",{className:"group-controls"+("unified"===this.groupViewMode?" unified-controls":"")}),a=re("span",{className:"add-group control-button",innerHTML:H.plus});F(a,"Добавить группу"),a.addEventListener("click",(()=>this.addGroup()));const r=re("span",{className:"rename-group control-button",innerHTML:H.rename});F(r,"Переименовать группу"),r.addEventListener("click",(()=>this.renameActiveGroup()));const o=re("span",{className:"remove-group control-button",innerHTML:H.trashNothing});F(o,"\n [Клик] Удалить группу и сделать предыдущую активной\n [Shift + Клик] Удалить группу и сделать следующую активной\n "),o.addEventListener("click",(e=>this.removeActiveGroup(e)));const n=this.createGroupViewToggle(),s=re("span",{className:"move-group-left control-button",innerHTML:H.chevronLeft});F(s,"Переместить вкладку назад"),s.addEventListener("click",(()=>{s.classList.contains("latest-games-disabled")||this.moveGroup(-1)}));const i=re("span",{className:"move-group-right control-button",innerHTML:H.chevronRight});F(i,"Переместить вкладку вперёд"),i.addEventListener("click",(()=>{i.classList.contains("latest-games-disabled")||this.moveGroup(1)})),t.append(a,r,o,n,s,i),e.appendChild(t);const l=re("div",{className:"tabs-container"});return this.groups.forEach((e=>{const t=this.createGroupTab(e);l.appendChild(t)})),"unified"===this.groupViewMode&&l.classList.add("latest-games-hidden"),e.appendChild(l),e}selectGroup(e){this.groups.some((t=>t.id===e))&&(this.currentGroupId=e,this.main.gamesManager.saveGameData(),this.updateActiveGroup(),this.main.uiManager.refreshContainer())}updateActiveGroup(){document.querySelectorAll(".group-header").forEach((e=>e.classList.toggle("active",e.dataset.groupId===this.currentGroupId))),document.querySelectorAll(".group-tab").forEach((e=>e.classList.toggle("active",e.dataset.groupId===this.currentGroupId)))}addGroup(){const e=prompt("Введите название группы:");if(null===e)return;const t=this.createGroup(e?.trim()||null);this.groups.push(t),this.currentGroupId=t.id,this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer()}renameActiveGroup(){const e=this.getCurrentGroup(),t=prompt("Введите новое название группы:",e?.title)?.trim();t&&(this.renameGroup(this.currentGroupId,t),this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer())}removeActiveGroup(e){if(this.groups.length<=1)return void alert("Нельзя удалить последнюю группу.");const t=this.groups.findIndex((e=>e.id===this.currentGroupId));let a;this.removeGroup(this.currentGroupId),e&&e.shiftKey?a=t>=this.groups.length?this.groups.length-1:t:(a=t-1,a<0&&(a=0)),this.currentGroupId=this.groups[a].id,this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer()}refreshGroupsContainer(){const e=document.getElementById("latest-games-groups");if(e){const t=e.querySelector(".group-controls");t&&(t.className="group-controls"+("unified"===this.groupViewMode?" unified-controls":""));const a=e.querySelector(".tabs-container");a&&(a.innerHTML="","tabs"===this.groupViewMode?(this.groups.forEach((e=>{const t=this.createGroupTab(e);a.appendChild(t)})),a.classList.remove("latest-games-hidden")):a.classList.add("latest-games-hidden"))}this.updateGroupControlStates()}isCyrillic(e){const t=e.charCodeAt(0);return t>=1040&&t<=1103||1025===t||1105===t}compareGameNames(e,t){const a=this.main.gamesManager.generateGameName(e).toLowerCase(),r=this.main.gamesManager.generateGameName(t).toLowerCase(),o=this.isCyrillic(a[0]),n=this.isCyrillic(r[0]);return o&&!n?-1:!o&&n?1:a.localeCompare(r,"ru")}sortActiveGroupGames(){const e=this.getCurrentGroup();if(!e)return;const t=e.games.filter((e=>e.pin)),a=e.games.filter((e=>!e.pin));t.sort(((e,t)=>this.compareGameNames(e,t))),a.sort(((e,t)=>this.compareGameNames(e,t))),e.games=[...t,...a],this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer()}getPinnedGameCount(){const e=this.getCurrentGroup();return e?e.games.filter((e=>e.pin)).length:0}}class de{constructor(e){this.main=e}getDisplayMode(){return this.main.displayMode}setDisplayMode(e){this.main.displayMode=e,this.main.settingsManager.saveSettings()}createDisplayModeToggle(){const e=re("div",{className:"display-mode-toggle control-button"});return e.innerHTML="wrap"===this.getDisplayMode()?H.wrap:H.scroll,F(e,"wrap"===this.getDisplayMode()?"Переключить режим отображения в вертикальный вид":"Переключить режим отображения в горизонтальный вид"),e.addEventListener("click",(()=>{const t="scroll"===this.getDisplayMode()?"wrap":"scroll";if(this.setDisplayMode(t),e.innerHTML="wrap"===t?H.wrap:H.scroll,this.updateDisplayModeClass(),F(e,"wrap"===t?"Переключить режим отображения в вертикальный вид":"Переключить режим отображения в горизонтальный вид"),"scroll"===t){const e=document.getElementById("latest-games-container");e&&setTimeout((()=>e.scrollTop=e.scrollHeight),0)}})),e}updateDisplayModeClass(){const e=document.getElementById("latest-games-container"),t=document.getElementById("latest-games");if(!e||!t)return;const a=this.getDisplayMode();e.classList.toggle("display-mode-wrap","wrap"===a),t.classList.toggle("display-mode-wrap","wrap"===a),this.updateContainerLeftOffset()}updateContainerLeftOffset(){const e=document.getElementById("latest-games-container");if(!e)return;if("wrap"===this.getDisplayMode()){const t=this.main.panelWidth||P.panelWidth;e.style.left=`calc(-1 * (${t} - 100px))`}else e.style.left="-330px"}}let ge=new Map,ue=null;const me='a[href*="/vocs/"], a[href*="/create/"]',he=["#latest-games-container",".game-popup",".userpanel","#head","#footer"];function ye(e){for(const t of he)if(e.closest(t))return!1;return!0}function ve(e){const t=ne(e);if(!t)return;const a=e.parentNode,r=a.querySelector(".kg-voc-checkmark");if(r&&r.remove(),ge.has(t)){const e=document.createElement("span");e.className="kg-voc-checkmark",e.innerHTML=H.checkmark,F(e,"Словарь уже существует в группе: "+ge.get(t).join(", "));const r=window.location.pathname.startsWith("/vocs/"),o=a.querySelector(".desc");r&&o?a.insertBefore(e,o):a.insertBefore(e,a.firstChild)}}function be(e){e.forEach((e=>{if(e.addedNodes.forEach((e=>{if(e.nodeType===Node.ELEMENT_NODE&&ye(e)){e.matches&&e.matches(me)&&ve(e);const t=e.querySelectorAll&&e.querySelectorAll(me);t&&t.forEach((e=>{ye(e)&&ve(e)}))}})),"attributes"===e.type&&"href"===e.attributeName){const t=e.target;ye(t)&&t.matches&&t.matches("a")&&ve(t)}}))}function fe(e){const t=ae();["profile","forum","vocabularies","gamelist","game"].includes(t)&&(ge.clear(),e.forEach((e=>{e.games.forEach((t=>{if(t.params&&t.params.vocId){const a=String(t.params.vocId);ge.has(a)||ge.set(a,[]),ge.get(a).push(e.name||e.title||"Группа")}}))})),document.querySelectorAll(me).forEach((e=>{ye(e)&&ve(e)})),ue&&ue.disconnect(),ue=new MutationObserver(be),ue.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["href"]}))}function xe(e,t,a="popup",r,o=!1){const n=document.querySelector(`.${a}`);n&&n.remove();const s=re("div",{className:a});if(r){const e=re("div",{className:"popup-header"}),t=re("span",{className:"popup-header-title",textContent:r});e.appendChild(t),s.appendChild(e)}e.forEach((e=>{const t=re("button",{className:e.className||"popup-button",textContent:e.text,...e.dataset&&{dataset:e.dataset}});e.onClick&&t.addEventListener("click",(()=>{e.onClick(t),o||s.remove()})),s.appendChild(t)})),s.style.visibility="hidden",document.body.appendChild(s),s.querySelectorAll("button").forEach((e=>{e.scrollWidth>e.clientWidth&&F(e,e.textContent)}));const i=s.getBoundingClientRect(),l=window.innerWidth,p=window.innerHeight;let c=Math.max(10,Math.min(t.clientX,l-i.width-10)),d=Math.max(10,Math.min(t.clientY,p-i.height-10));s.style.left=`${c}px`,s.style.top=`${d}px`,s.style.visibility="visible";const g=e=>{e&&"keydown"===e.type&&"Escape"!==e.key||(s.remove(),document.removeEventListener("click",u),document.removeEventListener("keydown",m))},u=e=>{s.contains(e.target)||g(e)},m=e=>{"Escape"===e.key&&g(e)};return requestAnimationFrame((()=>{document.addEventListener("click",u),document.addEventListener("keydown",m)})),s}let we=null,ke=null,Ce=null,Me=null;async function Se(e){try{const t=await fetch(`https://klavogonki.ru/vocs/${e}/`),a=await t.text();if(ie(t,a))return{removed:!0,content:"Словарь не найден",metadata:null};const r=(new DOMParser).parseFromString(a,"text/html");let o="Данные отсутствуют";const n=r.querySelector(".words");if(n){const e=n.querySelectorAll("tr");e.length>0&&(o=Array.from(e).map(((e,t)=>{const a=e.querySelector("td.num"),r=e.querySelector("td.text");if(!r)return null;const o=r.innerHTML.replace(//gi,"\n").replace(/<[^>]*>/g,"").trim();if(""===o||"…"===o)return null;if(a){const e=a.textContent.trim();return""===e||"…"===e?null:`${e}. ${o}`}return`${t+1}. ${o}`})).filter((e=>null!==e)).join("\n\n"))}const s={},i=r.querySelector(".user-title .title");if(i){const e=Array.from(i.childNodes).find((e=>e.nodeType===Node.TEXT_NODE&&e.textContent.trim()));s.title=e?e.textContent.trim():"Без названия"}const l=r.querySelector(".rating_stars");if(l){const e=l.className.match(/rating_stars(\d+)/);e&&(s.rating=parseInt(e[1]))}const p=r.querySelector("#rating_cnt");p&&(s.ratingCount=p.textContent.trim());const c=r.querySelector("#fav_cnt");c&&(s.usersCount=c.textContent.trim());for(const e of r.querySelectorAll(".user-content dl")){const t="DT"===e.children[0]?.tagName?e.children[0]:null,a=Array.from(e.children).find((e=>"DD"===e.tagName))??null;if(!t||!a)continue;if("Автор:"!==t.textContent.trim())continue;const r=a.querySelector('a[href^="/profile/"]');if(r){s.authorName=r.textContent.trim();const e=r.getAttribute("href").match(/\/profile\/(\d+)/);e&&(s.authorId=e[1])}const o=(a.getAttribute("style")||"").match(/url\s*\(\s*['"]?([^'")\s]+)['"]?\s*\)/);s.authorAvatar=o?o[1].replace(/"/g,""):null;break}const d=r.querySelectorAll(".user-content dl");for(const e of d){const t=e.querySelector("dt"),a=e.querySelector("dd");if(!t||!a)continue;const r=t.textContent;if(r.includes("Создан:")){const e=Array.from(a.childNodes).find((e=>e.nodeType===Node.TEXT_NODE&&e.textContent.trim()));e&&(s.createdDate=e.textContent.trim());const t=a.querySelector(".note");t&&(s.versionDate=t.textContent.trim())}else r.includes("Тип словаря:")?s.vocabularyType=a.textContent.trim().split("\n")[0].trim():r.includes("Публичный:")?s.isPublic=a.textContent.trim():r.includes("Описание:")?s.description=a.textContent.trim():r.includes("Содержание:")&&(s.contentStats=a.textContent.trim().split("\n")[0].trim())}s.vocId=e;const g=new Set(["B","I","EM","STRONG","U","S"]),u=e=>{if(e.nodeType===Node.TEXT_NODE)return e.textContent;if("BR"===e.nodeName)return"
";if("IMG"===e.nodeName)return``;if("A"===e.nodeName){return`${e.textContent}`}if(g.has(e.nodeName)){const t=e.nodeName.toLowerCase();return`<${t}>${Array.from(e.childNodes).map(u).join("")}`}if(e.classList?.contains("hidemain")){const t=e.querySelector(".hidecont");return`
Скрытый текст
${t?Array.from(t.childNodes).map(u).join(""):""}
`}return e.classList?.contains("hidetop")?"":e.classList?.contains("quotetop")?`
${e.textContent.trim()}
`:e.classList?.contains("quotemain")?`
${Array.from(e.childNodes).map(u).join("")}
`:Array.from(e.childNodes).map(u).join("")};return s.comments=Array.from(r.querySelectorAll(".comment")).reduce(((e,t)=>{const a=t.querySelector(".info"),r=a?.querySelector(".author .name"),o=Array.from(t.childNodes).filter((e=>e!==a)).map(u).join("").replace(/(
\s*){2,}/gi,"
").trim();if(!o)return e;const n=(a?.getAttribute("style")||"").match(/url\s*\(\s*['"]?([^'")\s]+)['"]?\s*\)/);return e.push({author:r?.textContent.trim()??null,authorId:r?.getAttribute("href")?.match(/\/profile\/(\d+)/)?.[1]??null,avatar:n?n[1].replace(/"/g,""):null,date:a?.querySelector(".date")?.textContent.trim()??null,text:o}),e}),[]),{content:o,metadata:s}}catch(t){return console.error(`Error fetching vocabulary data for vocId ${e}:`,t),{content:"Ошибка загрузки словаря",metadata:null}}}function Le(e,t){const a=document.createElement("div");a.className="vocabulary-tooltip-popup";let r=e,o=t;e&&"object"==typeof e&&"content"in e&&(r=e.content,o=e.metadata||t),r=String(r||"Данные отсутствуют");const n=e=>e.replace(/>\s+<").trim(),s=o?.comments??[],i=o?n((o.authorName?'
'+(o.authorAvatar?``:"")+(o.authorId?`${o.authorName}`:`${o.authorName}`)+"
":"")+(o.title?`
${o.title}
`:"")+(void 0!==o.rating?`
⭐️⭐️⭐️⭐️⭐️
⭐️⭐️⭐️⭐️⭐️
`+(o.ratingCount?`(${o.ratingCount})`:"")+"
":"")+(o.usersCount?`
Использует ${o.usersCount} ${(e=>{const t=Math.abs(e)%100,a=t%10;return t>10&&t<20?"человек":a>1&&a<5?"человека":"человек"})(parseInt(o.usersCount))}
`:"")+(o.vocabularyType?`
Тип: ${o.vocabularyType}
`:"")+(void 0!==o.isPublic?`
Публичный: ${o.isPublic}
`:"")+(o.createdDate?`
Создан: ${o.createdDate}`+(o.versionDate?`${o.versionDate}`:"")+"
":"")+(o.description?`
${o.description}
`:"")):"",l=n((i?`
${i}
`:"")+'
'+r.replace(/^(\d+)\.\s/gm,'$1. ')+"
");if(!s.length)return a.innerHTML=l,document.body.appendChild(a),a;const p=s.map((e=>n('
'+(e.avatar?``:"")+(e.author?`${e.author}`:"")+(e.date?`${e.date}`:"")+"
"+`
${e.text}
`))).join(""),c=o?.vocId?`Все комментарии`:"";return a.innerHTML=n(`
${l}
${p}
`+c+"
"),a.querySelectorAll(".tooltip-tab").forEach((e=>{e.addEventListener("click",(()=>{a.querySelectorAll(".tooltip-tab").forEach((e=>e.classList.remove("active"))),e.classList.add("active"),a.dataset.activeTab=e.dataset.tab}))})),document.body.appendChild(a),a}function Ee(e,t,a=null){if(ke&&clearTimeout(ke),Ce&&clearTimeout(Ce),!we||Me!==e){if(we&&Ie(),!e)return Me=null,we=Le(t,a),Ne(null,we),we.addEventListener("mouseenter",(()=>{ke&&clearTimeout(ke)})),void we.addEventListener("mouseleave",Ge);Ce=setTimeout((()=>{Me=e,we=Le(t,a),Ne(e,we),we.addEventListener("mouseenter",(()=>{ke&&clearTimeout(ke)})),we.addEventListener("mouseleave",Ge)}),400)}}function Ie(){we&&(we.remove(),we=null,Me=null),ke&&clearTimeout(ke),Ce&&clearTimeout(Ce)}function Ge(){ke&&clearTimeout(ke);try{if(we&&we.matches(":hover"))return}catch(e){}ke=setTimeout(Ie,300)}function Te(){try{const e=document.querySelector('#status #gamedesc a, #status a[href*="/vocs/"]');if(e){const t=(e.getAttribute("href")||"").match(/\/vocs\/(\d+)(?:\/|$)/);if(t&&t[1])return String(t[1])}const t=sessionStorage.getItem("latestGames_pendingVocId");if(!t)return null;return(JSON.parse(t)||{}).vocId||null}catch(e){return console.warn("Could not determine session voc id:",e),null}}function Ne(e,t){const a=window.innerWidth,r=window.innerHeight,o=10,n=t.getBoundingClientRect();let s,i;if(e){const t=e.getBoundingClientRect();if(s=t.left,i=t.bottom+5,s+n.width>a-o&&(s=a-n.width-o),sr-o){const e=t.top-n.height-5;i=e>=o?e:o}i"))continue;const p=(new DOMParser).parseFromString(s,"text/html");if(ie(r,s))return t.abort(),{removed:!0};const c=p.querySelector(".user-title");if(!c)continue;const d=c.querySelector("td.title"),g=d?.querySelector("#rating_cnt"),u=d?.querySelector("#fav_cnt");d&&g&&u&&(i={vocId:e,vocabularyName:d.childNodes[0]?.textContent?.trim()??"",ratingCount:parseInt(g.textContent.trim(),10),fansCount:parseInt(u.textContent.trim(),10)})}const l="Тип словаря:";for(;!s.includes(l);){const{done:e,value:t}=await o.read();if(e)break;s+=n.decode(t,{stream:!0})}const p=function(e){let t="",a=null,r=null,o=null,n=null;for(const s of e.querySelectorAll(".user-content dl")){const e=s.querySelector("dt"),i=s.querySelector("dd");if(!e||!i)continue;const l=e.textContent.trim();if("Автор:"===l){const e=i.querySelector('a[href^="/profile/"]');e&&(t=e.textContent.trim())}if("Тип словаря:"===l){const e=i.childNodes[0]?.textContent?.trim();e&&L[e]&&(a=L[e])}if("Публичный:"===l&&(r=i.textContent.trim()),"Создан:"===l){const e=Array.from(i.childNodes).find((e=>e.nodeType===Node.TEXT_NODE&&e.textContent.trim()));e&&(o=e.textContent.trim());const t=i.querySelector(".note");t&&(n=t.textContent.trim())}}return{vocabularyAuthor:t,vocabularyType:a,vocabularyIsPublic:r,createdDate:o,versionDate:n}}((new DOMParser).parseFromString(s,"text/html"));return t.abort(),{...i,...p}}catch(e){return"AbortError"===e.name||console.error("Error fetching/parsing vocabulary basic data:",e),null}}function De(e,t,a,r,o,n){if(e.games.some((e=>String(e.params?.vocId)===String(t))))return void alert(`Этот словарь уже добавлен в ${e.title}`);const s={id:ee(o),params:{gametype:"voc",vocName:a,vocId:t,vocType:r||null,type:"normal",level_from:1,level_to:9,timeout:10,idletime:0,qual:0,premium_abra:0},pin:1};e.games.push(s);let i=n.gamesManager.latestGamesData||{};i={...i,latestGroupAddedGameId:e.id},n.gamesManager.latestGamesData=i,n.gamesManager.saveGameData(),n.uiManager.refreshContainer(),fe(o)}!async function(){const e=localStorage.getItem("latestGamesSettings");if((e?JSON.parse(e):{}).showVocabularyData&&(await new Promise((e=>setTimeout(e,500))),"game"===ae()))try{const e=Te();if(!e)return;if("vocabulary"!==se().category)return;const t=await Se(e);Ee(null,t.content,t.metadata),setTimeout((()=>{try{Ge()}catch(e){}}),5e3)}catch(e){}}();const Pe=new WeakSet;function Ae(e,t,a){async function r(e){const t=await $e(e);return t&&t.vocabularyName?{success:!0,vocName:t.vocabularyName,vocType:t.vocabularyType||null}:(alert("⚠️ Не удалось получить данные словаря. Добавление отменено."),{success:!1})}Pe.has(e)||(Pe.add(e),e.addEventListener("contextmenu",(async e=>{const o=e.target.closest("a");if(!o)return;const n=o.getAttribute("href");if(!n||!n.includes("/vocs/")&&!n.includes("/create/"))return;const s=ne(o);if(!s)return void console.warn("Invalid vocabulary link (extra path segments present), ignoring:",n);let i=a.gamesManager.latestGamesData||{};if(e.ctrlKey){const o=i.latestGroupAddedGameId;if(o){const n=t.find((e=>e.id===o));if(n){e.preventDefault(),e.stopPropagation();const o=await r(s);if(!o.success)return;return void De(n,s,o.vocName,o.vocType,t,a)}}return}e.preventDefault(),e.stopPropagation();const l=await r(s);l.success&&function(e,t,a,r,o,n){Ie(),xe(e.map((t=>{const s=t.games.some((e=>String(e.params?.vocId)===String(a)));return{text:t.title,className:"group-tab"+(s?" active":""),dataset:{groupId:t.id},onClick:()=>{De(t,a,r,o,e,n)}}})),t,"vocabulary-creation-popup","Добавить")}(t,e,s,l.vocName,l.vocType,a)})))}function He(e,t){const a=oe();if(!a)return void console.warn("Vocabulary creation is not supported on this page.");a.split(",").map((e=>e.trim())).forEach((a=>{const r=document.querySelector(a);r&&Ae(r,e,t),function(e,t){const a=new MutationObserver((a=>{a.forEach((a=>{"childList"===a.type&&a.addedNodes.forEach((a=>{a.nodeType===Node.ELEMENT_NODE&&(a.matches(e)&&t(a),a.querySelectorAll(e).forEach((e=>t(e))))}))}))}));a.observe(document.body,{childList:!0,subtree:!0})}(a,(a=>Ae(a,e,t)))}))}const qe="latestGamesPlaylists",_e="latestGames_activePlaylist",Be="latestGames_randomShuffleBag";function Ve(){try{const e=localStorage.getItem(_e);return e?JSON.parse(e):null}catch{return null}}function Re(e){try{e?localStorage.setItem(_e,JSON.stringify(e)):localStorage.removeItem(_e)}catch{}}{const e=Ve();e&&!e.paused&&"game"!==ae()&&Re({...e,paused:!0})}function je(){Ve()&&Re(null)}function Oe(e){const t=Ve();if(!t)return null;try{const a=Fe(at.load().find((e=>e.id===t.playlistId)),t),r=a&&e.gamesManager.findGameById(a.gameId);return r?et(e,r,a):null}catch{return null}}function ze(e){const t=Ve();if(!t)return!1;if(t.paused)return"paused";const a=at.load().find((e=>e.id===t.playlistId));if(!a||!a.entries.length)return Ye(e,a),!1;const r=Array.isArray(t.shuffleOrder)&&t.shuffleOrder.length===a.entries.length?t.shuffleOrder:null,o=r?r.length:a.entries.length;let{entryIndex:n,remainingRepeats:s}=t;if(s--,s>0)Re({...t,remainingRepeats:s});else if(n++,n>=o){const o=(t.remainingCycles??1)-1;if(!(o>0))return Ye(e,a),!1;{const e=r?Ke(a.entries.length):null,n=e?e[0]:0,s=a.entries[n];Re({...t,entryIndex:0,remainingRepeats:s.repeatCount,remainingCycles:o,shuffleOrder:e})}}else{const e=r?r[n]:n,o=a.entries[e];Re({...t,entryIndex:n,remainingRepeats:o.repeatCount})}const i=Fe(a,Ve()),l=i&&e.gamesManager.findGameById(i.gameId);return l?{url:et(e,l,i)}:ze(e)}function Ye(e,t){je();try{e?.pageHandler?.gamesDataContainer?.updatePlaylistIndicator()}catch(e){}try{at.refresh()}catch(e){}const a=t?.title||"Плейлист";setTimeout((()=>alert(`✅ Плейлист «${a}» завершён!`)),300)}function We(e){const t=[...e];for(let e=t.length-1;e>0;e--){const a=Math.floor(Math.random()*(e+1));[t[e],t[a]]=[t[a],t[e]]}return t}function Ke(e){return We([...Array(e).keys()])}function Fe(e,t){return e&&t?e.entries[Xe(e,t)]??null:null}function Xe(e,t){if(!e||!t)return 0;const a=Array.isArray(t.shuffleOrder)&&t.shuffleOrder.length===e.entries.length?t.shuffleOrder:null,r=t.entryIndex??0;return a?a[r]??0:r}function Je(e){return!(!e||!("type"in e||"timeout"in e||"idletime"in e))}const Ue={paramsBtn:{default:{click:"Переопределить параметры (режим, TM, AFK)"},override:{click:"Изменить переопределённые параметры",ctrl:"Сбросить все переопределения"}}};function Ze(e,t){const a=Je(t);e.classList.toggle("has-overrides",a),F(e,function(e,t="default"){const a=Ue[e]?.[t];if(!a)return"";const r=[];return a.click&&r.push(`[Клик] ${a.click}`),a.shift&&r.push(`[Shift + Клик] ${a.shift}`),a.ctrl&&r.push(`[Ctrl + Клик] ${a.ctrl}`),a.alt&&r.push(`[Alt + Клик] ${a.alt}`),a.shiftAlt&&r.push(`[Shift + Alt + Клик] ${a.shiftAlt}`),a.ctrlShift&&r.push(`[Ctrl + Shift + Клик] ${a.ctrlShift}`),r.join(" ")}("paramsBtn",a?"override":"default"))}function Qe(e,t,a,r=null){const o=E[a.type??t.params.type]||(a.type??t.params.type),n=a.timeout??t.params.timeout,s=a.idletime??t.params.idletime;let i="";Je(a)&&(i+="[Параметры] переопределены"),i+=`[Режим] ${o}[TM] ${n}`,s&&(i+=`[AFK] ${s}`),r&&(i+=`[Пройдено] ${r.played} из ${r.total}`),F(e,i)}function et(e,t,a){const r=a?.params,o={...t.params,...Je(r)?{..."type"in r?{type:r.type}:{},..."timeout"in r?{timeout:r.timeout}:{},..."idletime"in r?{idletime:r.idletime}:{}}:{}};return"normal"===o.type&&5===o.timeout&&(o.timeout=10),Je(r)?e.gamesManager.generateGameLink({...t,params:o}):e.gamesManager.generateGameLink(t)}function tt(e,t,a){t.params||(t.params={});const r=t.params,o=nt("div","playlist-entry-params");function n(){const a="normal"===(r.type??null);o.querySelectorAll('.playlist-entry-params-option[data-group="timeout"]').forEach((e=>{const t=a&&5===Number(e.dataset.val);e.disabled=t,e.classList.toggle("playlist-entry-params-option--disabled",t)})),a&&5===r.timeout&&(r.timeout=10,o.querySelectorAll('.playlist-entry-params-option[data-group="timeout"]').forEach((e=>{e.classList.toggle("active",Number(e.dataset.val)===r.timeout)})),at.setEntryParams(e.id,t.id,r))}function s(o,s,i,l,p){const c=nt("div","playlist-entry-params-group");return c.append(nt("span","playlist-entry-params-label",o)),i.forEach((([o,i])=>{const d=nt("button","playlist-entry-params-option");d.textContent=i,d.dataset.val=o,d.dataset.group=s,l()===o&&d.classList.add("active"),d.addEventListener("click",(s=>{if(s.stopPropagation(),d.disabled)return;const i=l()===o;p(i?null:o),c.querySelectorAll(".playlist-entry-params-option").forEach((e=>e.classList.remove("active"))),i||d.classList.add("active"),function(){at.setEntryParams(e.id,t.id,r),n(),Ze(a,r);const o=a.closest(".playlist-entry-row");if(o){const e=o.querySelector(".playlist-entry-label"),a=at.main?.gamesManager?.findGameById(t.gameId);e&&a&&Qe(e,a,r)}}()})),c.append(d)})),c}return o.append(s("Вид","type",Object.entries(E),(()=>r.type??null),(e=>{null==e?delete r.type:r.type=e})),s("TM","timeout",$.map((e=>[e,e])),(()=>r.timeout??null),(e=>{null==e?delete r.timeout:r.timeout=e})),s("AFK","idletime",D.map((e=>[e,e])),(()=>r.idletime??null),(e=>{null==e?delete r.idletime:r.idletime=e}))),n(),o}const at={popup:null,isDragging:!1,offsetX:0,offsetY:0,main:null,expandedPlaylistId:null,_intendedX:null,_intendedY:null,load(){try{return JSON.parse(localStorage.getItem(qe)||"[]")}catch{return[]}},save(e){try{localStorage.setItem(qe,JSON.stringify(e))}catch{}},createPlaylist(e){const t=this.load();let a=(e||"").trim();if(!a){let e=1;for(;t.some((t=>t.title===`Плейлист-${e}`));)e++;a=`Плейлист-${e}`}const r={id:Q(),title:a,entries:[],shuffle:!1};return t.push(r),this.save(t),r},renamePlaylist(e,t){const a=this.load(),r=a.find((t=>t.id===e));r&&t.trim()&&(r.title=t.trim(),this.save(a))},deletePlaylist(e){this.save(this.load().filter((t=>t.id!==e))),this.expandedPlaylistId===e&&(this.expandedPlaylistId=null)},duplicatePlaylist(e){const t=this.load(),a=t.find((t=>t.id===e));if(!a)return null;const r=a.title.replace(/ \(копия(?: \d+)?\)$/,"");let o,n=1;do{o=`${r} (копия ${n++})`}while(t.some((e=>e.title===o)));const s={id:Q(),title:o,entries:a.entries.map((e=>({id:Q(),gameId:e.gameId,repeatCount:e.repeatCount,params:e.params?{...e.params}:{}}))),shuffle:a.shuffle,repeatCount:a.repeatCount};return t.push(s),this.save(t),s},addEntry(e,t,a=1){const r=this.load(),o=r.find((t=>t.id===e));o&&(o.entries.some((e=>e.gameId===t))||(o.entries.push({id:Q(),gameId:t,repeatCount:Math.max(1,a),params:{}}),this.save(r)))},removeEntry(e,t){const a=this.load(),r=a.find((t=>t.id===e));r&&(r.entries=r.entries.filter((e=>e.id!==t)),this.save(a))},duplicateEntry(e,t){const a=this.load(),r=a.find((t=>t.id===e));if(!r)return null;const o=r.entries.find((e=>e.id===t));if(!o)return null;const n={id:Q(),gameId:o.gameId,repeatCount:o.repeatCount,params:o.params?{...o.params}:{}};return r.entries.push(n),this.save(a),n},setRepeat(e,t,a){const r=this.load(),o=r.find((t=>t.id===e));if(!o)return;const n=o.entries.find((e=>e.id===t));if(!n)return;const s=n.repeatCount,i=Math.max(1,a);n.repeatCount=i,this.save(r);const l=Ve();if(l&&l.playlistId===e){const a=this.load().find((t=>t.id===e));if(a){if(a.entries.findIndex((e=>e.id===t))===Xe(a,l)){const e=i-s,t=Math.min(i,Math.max(1,l.remainingRepeats+e));Re({...l,remainingRepeats:t})}}}},setPlaylistCycles(e,t){const a=this.load(),r=a.find((t=>t.id===e));if(!r)return;const o=Math.max(1,t);r.repeatCount=o,this.save(a);const n=Ve();if(n&&n.playlistId===e&&o>1){const e=Math.min(o,n.remainingCycles??o);Re({...n,remainingCycles:e})}},setEntryParams(e,t,a){const r=this.load(),o=r.find((t=>t.id===e));if(!o)return;const n=o.entries.find((e=>e.id===t));n&&(n.params={...a},this.save(r))},reorderPlaylists(e,t){if(e===t)return;const a=this.load(),[r]=a.splice(e,1);a.splice(t,0,r),this.save(a)},reorderEntries(e,t,a){if(t===a)return;const r=this.load(),o=r.find((t=>t.id===e));if(!o)return;const[n]=o.entries.splice(t,1);o.entries.splice(a,0,n),this.save(r);const s=Ve();if(s&&s.playlistId===e){let e=s.entryIndex;e===t?e=a:tt&&e<=a?e--:t>a&&e>=a&&et.id===e));if(!r||!r.entries.length)return void alert("⚠️ Плейлист пуст. Добавьте игры перед запуском.");const o=Ve();if(o&&o.playlistId!==e){const e=a.find((e=>e.id===o.playlistId));if(!confirm(`Запущен плейлист «${e?.title||"Неизвестный плейлист"}». Остановить его и запустить «${r.title}»?`))return}const n=void 0!==t.shuffle?t.shuffle:!!r.shuffle,s=n?Ke(r.entries.length):null,i=n?s[0]:0,l=r.entries[i],p=this.main.gamesManager.findGameById(l.gameId);p?(Re({playlistId:e,entryIndex:0,remainingRepeats:l.repeatCount,remainingCycles:r.repeatCount??1,shuffleOrder:s,shuffleActive:n}),window.location.href=et(this.main,p,l)):alert("⚠️ Первая игра плейлиста не найдена.")},startRandomPlaylist(){if(!this.main)return;const e=this.load().filter((e=>e.entries.length>0));if(!e.length)return void alert("⚠️ Нет плейлистов с играми.");const t=e.map((e=>e.id));let a=[];try{a=JSON.parse(localStorage.getItem(Be)||"[]")}catch{}if(a=a.filter((e=>t.includes(e))),!a.length){const e=We(t);let r=null;try{r=localStorage.getItem(Be+"_last")}catch{}e.length>1&&e[0]===r&&e.push(e.shift()),a=e}const r=a.shift();try{localStorage.setItem(Be,JSON.stringify(a)),localStorage.setItem(Be+"_last",r)}catch{}this.startPlaylist(r)},show(e=100,t=100){this.popup&&this.hide();const a=Ve();a&&!this.expandedPlaylistId&&(this.expandedPlaylistId=a.playlistId),this.popup=this._buildPanel(),document.body.appendChild(this.popup),this._intendedX=e+20,this._intendedY=t+20,this.popup.style.left=this._intendedX+"px",this.popup.style.top=this._intendedY+"px",this._constrain(),a&&requestAnimationFrame((()=>this._scrollToActiveEntry())),setTimeout((()=>{document.addEventListener("click",this._outside),document.addEventListener("keydown",this._keydown)}),100),window.addEventListener("resize",this._onResize)},hide(){this.popup&&(document.body.removeChild(this.popup),this.popup=null,this.isDragging=!1,document.removeEventListener("click",this._outside),document.removeEventListener("keydown",this._keydown),document.removeEventListener("mousemove",this._drag),document.removeEventListener("mouseup",this._stopDrag),window.removeEventListener("resize",this._onResize))},toggle(e,t){this.popup?this.hide():this.show(e,t)},refresh(){if(!this.popup)return;const e=this._buildPanel(),t=null!==this._intendedX?this._intendedX:this.popup.getBoundingClientRect().left,a=null!==this._intendedY?this._intendedY:this.popup.getBoundingClientRect().top;e.style.left=t+"px",e.style.top=a+"px",this.popup.parentNode.replaceChild(e,this.popup),this.popup=e,this._constrain(),document.removeEventListener("click",this._outside),document.removeEventListener("keydown",this._keydown),setTimeout((()=>{document.addEventListener("click",this._outside),document.addEventListener("keydown",this._keydown)}),100);Ve()&&requestAnimationFrame((()=>this._scrollToActiveEntry()))},_isPinned:()=>2===at.main?.playlistPanelAutoOpen&&"game"===ae(),_outside:e=>{at.popup&&(at.popup.contains(e.target)||at._isPinned()||e.target.closest("button, input, select, textarea")||at.hide())},_keydown:e=>{at._isPinned()||"Escape"===e.key&&at.hide()},_startDrag(e){if(0!==e.button)return;if(this._isPinned())return;this.isDragging=!0;const t=this.popup.getBoundingClientRect();this.offsetX=e.clientX-t.left,this.offsetY=e.clientY-t.top,document.addEventListener("mousemove",this._drag),document.addEventListener("mouseup",this._stopDrag)},_drag:e=>{if(!at.isDragging||!at.popup)return;const t=e.clientX-at.offsetX,a=e.clientY-at.offsetY;at._intendedX=t,at._intendedY=a,at.popup.style.left=t+"px",at.popup.style.top=a+"px",at._constrain()},_stopDrag:()=>{at.isDragging=!1,document.removeEventListener("mousemove",at._drag),document.removeEventListener("mouseup",at._stopDrag)},_constrain(){if(!this.popup)return;const e=this.popup.getBoundingClientRect(),t=window.innerWidth-e.width,a=window.innerHeight-e.height;e.left<0&&(this.popup.style.left="0px"),e.top<0&&(this.popup.style.top="0px"),e.left>t&&(this.popup.style.left=t+"px"),e.top>a&&(this.popup.style.top=a+"px")},_onResize:()=>{at.popup&&(null!==at._intendedX&&(at.popup.style.left=at._intendedX+"px"),null!==at._intendedY&&(at.popup.style.top=at._intendedY+"px"),at._constrain())},updateActiveEntryProgress(){if(!this.popup)return;const e=Ve();if(!e)return;const t=this.popup.querySelector(".playlist-entry-row--active");if(t)try{const a=this.load().find((t=>t.id===e.playlistId));if(!a)return;const r=Fe(a,e);if(!r||r.repeatCount<=1)return t.style.removeProperty("--playlist-progress"),void t.classList.remove("playlist-entry-row--progress");const o=r.repeatCount-e.remainingRepeats;if(o<=0)return t.style.removeProperty("--playlist-progress"),void t.classList.remove("playlist-entry-row--progress");const n=Math.min(100,Math.round(o/r.repeatCount*100));t.classList.add("playlist-entry-row--progress"),t.style.setProperty("--playlist-progress",`${n}%`)}catch{}},_scrollToActiveEntry(){const e=Ve();if(!e||!this.popup)return;const t=this.popup.querySelector(".playlists-list"),a=this.popup.querySelector(".playlist-entry-row--active"),r=this.popup.querySelector(`.playlist-block[data-playlist-id="${e.playlistId}"]`);if(a&&t){const e=t.getBoundingClientRect(),r=a.getBoundingClientRect(),o=r.top-e.top-e.height/2+r.height/2;t.scrollBy({top:o,behavior:"smooth"})}else r&&t&&r.scrollIntoView({block:"center",behavior:"smooth"})},_buildPanel(){const e=this.load(),t=Ve(),a=nt("div","playlists-manager-popup"),r=nt("div","popup-header");this._isPinned()||(r.style.cursor="move"),r.addEventListener("mousedown",(e=>this._startDrag(e)));const o=nt("span","popup-header-title","Плейлисты"),n=nt("button","playlists-random-btn");n.innerHTML=H.random,F(n,"Запустить случайный плейлист"),n.addEventListener("click",(e=>{e.stopPropagation(),this.startRandomPlaylist()}));const s=nt("button","playlists-add-btn");s.innerHTML=`${H.plus}Новый`,F(s,"Создать новый плейлист"),s.addEventListener("click",(e=>{e.stopPropagation();const t=a.querySelector(".playlists-create-form");if(t)return void t.remove();const o=this._buildCreateForm((()=>{a.querySelector(".playlists-create-form")?.remove(),this.refresh()}));r.insertAdjacentElement("afterend",o),o.querySelector(".playlists-create-input")?.focus()}));const i=nt("div","playlists-header-actions");if(i.append(n,s),r.append(o,i),a.appendChild(r),!e.length)return a.appendChild(nt("div","playlists-empty","Нет плейлистов. Создайте первый!")),a;const l=nt("div","playlists-list");return e.forEach((e=>l.appendChild(this._buildPlaylistBlock(e,t)))),this._attachSortableDrag(l,{itemSelector:".playlist-block",handleSelector:".playlist-block-drag-handle",draggingClass:"playlist-block--dragging",onReorder:(e,t)=>this.reorderPlaylists(e,t),onStart:e=>{const t=e.querySelector(".playlist-body");t&&(e.dataset.dragBodyHidden="1",t.style.display="none")},onEnd:e=>{if(e.dataset.dragBodyHidden){const t=e.querySelector(".playlist-body");t&&(t.style.display=""),delete e.dataset.dragBodyHidden}}}),a.appendChild(l),a},_buildPlaylistBlock(e,t){const a=!(!t||t.playlistId!==e.id),r=a||this.expandedPlaylistId===e.id,o=nt("div","playlist-block");o.dataset.playlistId=e.id;const n=nt("div","playlist-header-row"+(a?" playlist-header-row--active":""));if(a){const a=!(!t||!t.paused),r=nt("button","playlist-pause-btn");r.innerHTML=a?H.start:H.pause,F(r,a?`Возобновить плейлист «${e.title}»`:`Приостановить плейлист «${e.title}»`),r.addEventListener("click",(e=>{e.stopPropagation();const t=Ve();if(t)if(t.paused){Re({...t,paused:!1}),rt();const e=this.load().find((e=>e.id===t.playlistId)),a=e?Fe(e,Ve()):null,r=a?this.main.gamesManager.findGameById(a.gameId):null;r?window.location.href=this.main.gamesManager.generateGameLink(r):this.refresh()}else{Re({...t,paused:!0});try{this.main.pageHandler?.cancelReplay(!0)}catch(e){}rt(),this.refresh()}}));const o=nt("button","playlist-cancel-btn");o.innerHTML=H.stop,F(o,`Остановить плейлист «${e.title}»`),o.addEventListener("click",(e=>{e.stopPropagation(),je(),rt(),this.refresh()}));const s=nt("span","playlist-title",e.title),i=Fe(e,t);if(i){const a=e.repeatCount??1,r=t.remainingCycles??1,o=nt("div","playlist-active-badge"),n=a>1?`${H.refresh}${a-r+1}/${a}`:"",l=i.repeatCount>1?`${H.x}${t.remainingRepeats}`:"",p=t.shuffleActive??!!e.shuffle,c=p?`${H.random}`:"";o.innerHTML=`\n ${t.entryIndex+1}/${e.entries.length}\n ${l}\n ${n}\n ${c}\n `;let d=`[Плейлист] ${e.title}[Позиция] ${t.entryIndex+1} из ${e.entries.length}`;i.repeatCount>1&&(d+=`[Осталось повторов] ${t.remainingRepeats}`),a>1&&(d+=`[Цикл] ${a-r+1} из ${a}`),p&&(d+="[Порядок] случайный"),F(o,d),s.appendChild(o)}const l=nt("span","playlist-block-drag-handle");l.innerHTML=H.dragable,n.append(r,o,l,s)}else{const t=nt("button","playlist-play-btn");t.innerHTML=H.start,F(t,`Запустить плейлист «${e.title}»`),t.addEventListener("click",(t=>{t.stopPropagation(),this.startPlaylist(e.id)}));const a=nt("span","playlist-title",e.title),r=e.repeatCount??1,o=nt("div","playlist-header-stepper"),s=nt("button","playlist-stepper-btn");s.innerHTML=H.chevronLeft;const i=nt("span","playlist-stepper-count",String(r)),l=nt("button","playlist-stepper-btn");l.innerHTML=H.chevronRight,o.append(s,i,l),F(o,"Количество повторов всего плейлиста"),r<=1&&o.classList.add("playlist-header-stepper--default"),s.addEventListener("click",(t=>{t.stopPropagation();const a=Math.max(1,(e.repeatCount??1)-1);this.setPlaylistCycles(e.id,a),e.repeatCount=a,i.textContent=String(a),o.classList.toggle("playlist-header-stepper--default",a<=1)})),l.addEventListener("click",(t=>{t.stopPropagation();const a=(e.repeatCount??1)+1;this.setPlaylistCycles(e.id,a),e.repeatCount=a,i.textContent=String(a),o.classList.remove("playlist-header-stepper--default")}));const p=nt("button","playlist-play-shuffle-btn");p.innerHTML=H.random;const c=t=>{p.classList.toggle("active",t),F(p,t?`Отключить случайный порядок для «${e.title}»`:`Включить случайный порядок для «${e.title}»`)};c(!!e.shuffle),p.addEventListener("click",(t=>{t.stopPropagation();const a=this.load(),r=a.find((t=>t.id===e.id));r&&(r.shuffle=!r.shuffle,this.save(a),c(r.shuffle))}));const d=nt("button","playlist-rename-btn");d.innerHTML=H.rename,F(d,"Переименовать"),d.addEventListener("click",(t=>{t.stopPropagation();const a=prompt("Новое название:",e.title);a&&a.trim()&&(this.renamePlaylist(e.id,a),this.refresh())}));const g=nt("button","playlist-duplicate-btn");g.innerHTML=H.copy,F(g,"Дублировать плейлист"),g.addEventListener("click",(t=>{t.stopPropagation();this.duplicatePlaylist(e.id)&&(this.expandedPlaylistId=null,this.refresh())}));const u=nt("button","playlist-delete-btn");u.innerHTML=H.trashNothing,F(u,"Удалить плейлист"),u.addEventListener("click",(t=>{t.stopPropagation(),confirm(`Удалить плейлист «${e.title}»?`)&&(this.deletePlaylist(e.id),this.refresh())}));const m=nt("span","playlist-block-drag-handle");m.innerHTML=H.dragable,n.append(t,m,a,o,p,d,g,u)}if(n.addEventListener("click",(t=>{t.target.closest("button")||(this.expandedPlaylistId=r&&!a?null:e.id,this.refresh())})),o.appendChild(n),!r)return o;const s=nt("div","playlist-body"),i=nt("div","playlist-entries");if(e.entries.length){const r=a?Xe(e,t):-1;e.entries.forEach(((o,n)=>{const s=a&&n===r;let l=!1;if(a&&!s){const a=Array.isArray(t.shuffleOrder)&&t.shuffleOrder.length===e.entries.length?t.shuffleOrder:null;if(a){const e=a.indexOf(n);l=e>=0&&ethis.reorderEntries(e.id,t,a)})}else i.appendChild(nt("div","playlist-entries-empty","Нет игр. Добавьте из групп ниже."));return s.appendChild(i),s.appendChild(this._buildGamePicker(e)),o.appendChild(s),o},_buildEntryRow(e,t,a,r,o,n=!1){const s=this.main?.gamesManager?.findGameById(t.gameId)??null,i=nt("div",["playlist-entry-row",r?"playlist-entry-row--active":"",n?"playlist-entry-row--passed":""].filter(Boolean).join(" "));if(i.dataset.entryId=t.id,i.dataset.entryIndex=o,r&&t.repeatCount>1){const e=t.repeatCount-a.remainingRepeats,r=Math.round(e/t.repeatCount*100);i.style.setProperty("--playlist-progress",`${r}%`),i.classList.add("playlist-entry-row--progress")}const l=nt("span","playlist-entry-drag-handle");l.innerHTML=H.dragable;const p=nt("span","playlist-entry-label");if(s){const e=M[s.params.gametype]||s.params.gametype,o=s.params.vocName?`«${s.params.vocName}»`:e;p.textContent=o,p.classList.add(`gametype-${s.params.gametype}`);const n=r&&a?{played:t.repeatCount-a.remainingRepeats,total:t.repeatCount}:null;Qe(p,s,t.params??{},n)}else p.textContent=`#${t.gameId} (удалена)`,p.classList.add("playlist-entry-missing");const c=nt("div","playlist-entry-stepper"),d=nt("button","playlist-stepper-btn");d.innerHTML=H.chevronLeft;const g=nt("span","playlist-stepper-count",String(t.repeatCount)),u=nt("button","playlist-stepper-btn");u.innerHTML=H.chevronRight,F(c,"Количество повторов этой игры");const m=r&&a?Ve():null;let h=r&&m?Math.max(0,t.repeatCount-m.remainingRepeats):0;d.addEventListener("click",(a=>{a.stopPropagation();const o=Math.max(1,t.repeatCount-1);this.setRepeat(e.id,t.id,o),g.textContent=String(o),t.repeatCount=o,rt(),ot(i,t,h,r)})),u.addEventListener("click",(a=>{a.stopPropagation();const o=t.repeatCount+1;this.setRepeat(e.id,t.id,o),g.textContent=String(o),t.repeatCount=o,rt(),ot(i,t,h,r)})),c.append(d,g,u);const y=nt("button","playlist-entry-remove");y.innerHTML=H.delete,F(y,"Убрать из плейлиста"),y.addEventListener("click",(a=>{a.stopPropagation(),this.removeEntry(e.id,t.id),i.remove();const r=i.closest(".playlist-entries");r&&!r.querySelector(".playlist-entry-row")&&(r.innerHTML="",r.appendChild(nt("div","playlist-entries-empty","Нет игр. Добавьте из групп ниже.")))}));const v=nt("button","playlist-entry-duplicate-btn");v.innerHTML=H.copy,F(v,"Дублировать в конец плейлиста"),v.addEventListener("click",(a=>{a.stopPropagation();const r=this.duplicateEntry(e.id,t.id);if(!r)return;const o=this.load().find((t=>t.id===e.id));if(!o)return;const n=i.closest(".playlist-entries");if(!n)return;const s=n.querySelector(".playlist-entries-empty");s&&s.remove();const l=this._buildEntryRow(o,r,null,!1,o.entries.length-1);n.appendChild(l)}));const b=nt("button","playlist-entry-play-btn");b.innerHTML=H.start,F(b,"Начать плейлист с этой игры"),b.addEventListener("click",(t=>{t.stopPropagation();const a=this.load().find((t=>t.id===e.id));if(!a||o>=a.entries.length)return;const r=a.entries[o],n=this.main.gamesManager.findGameById(r.gameId);n?(Re({playlistId:e.id,entryIndex:o,remainingRepeats:r.repeatCount,remainingCycles:a.repeatCount??1}),window.location.href=et(this.main,n,r)):alert("⚠️ Игра не найдена.")}));const f=nt("button","playlist-entry-params-btn");return f.innerHTML=H.parameters,Ze(f,t.params),f.addEventListener("click",(a=>{if(a.stopPropagation(),a.ctrlKey){if(!Je(t.params))return;t.params={},at.setEntryParams(e.id,t.id,{}),Ze(f,t.params);const a=i.nextElementSibling?.classList.contains("playlist-entry-params")?i.nextElementSibling:null;a&&(a.remove(),i.classList.remove("playlist-entry-row--params-open"));const r=at.main?.gamesManager?.findGameById(t.gameId);if(r){const e=i.querySelector(".playlist-entry-label");e&&Qe(e,r,t.params)}return}const r=i.nextElementSibling?.classList.contains("playlist-entry-params")?i.nextElementSibling:null;if(r)return r.remove(),void i.classList.remove("playlist-entry-row--params-open");const o=i.closest(".playlist-entries");o&&o.querySelectorAll(".playlist-entry-params").forEach((e=>{const t=e.previousElementSibling;t&&t.classList.remove("playlist-entry-row--params-open"),e.remove()})),t.params||(t.params={});const n=tt(e,t,f);i.parentNode.insertBefore(n,i.nextSibling),i.classList.add("playlist-entry-row--params-open")})),i.append(b,l,v,p,c,f,y),i},_attachSortableDrag(e,{itemSelector:t,handleSelector:a,draggingClass:r,onReorder:o,onStart:n,onEnd:s}){if(e.dataset.dragAttached)return;e.dataset.dragAttached="1";let i=null,l=null,p=0,c=0;const d=()=>Array.from(e.querySelectorAll(t));e.addEventListener("mousedown",(o=>{const s=o.target.closest(a);if(!s)return;const m=s.closest(t);if(!m||m.parentNode!==e)return;o.preventDefault(),e.querySelectorAll(".playlist-entry-placeholder").forEach((e=>e.remove())),i=m,c=d().indexOf(i),p=o.clientY;const h=i.getBoundingClientRect();i.style.width=h.width+"px",i.classList.add(r),n&&n(i);const y=i.getBoundingClientRect().height;l=nt("div","playlist-entry-placeholder"),l.style.height=y+"px",i.parentNode.insertBefore(l,i),document.addEventListener("mousemove",g),document.addEventListener("mouseup",u)}));const g=t=>{if(!i)return;i.style.transform=`translateY(${t.clientY-p}px)`;const a=d().filter((e=>e!==i));let r=null;for(const e of a){const a=e.getBoundingClientRect();if(t.clientY{if(!i)return;document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",u),i.classList.remove(r),i.style.transform="",i.style.width="",l.replaceWith(i);const e=d().indexOf(i);e!==c&&o(c,e),s&&s(i),document.addEventListener("click",(e=>e.stopPropagation()),{capture:!0,once:!0}),i=null,l=null}},_buildCreateForm(e){const t=nt("div","playlists-create-form"),a=nt("div","playlists-create-name-row"),r=nt("input","playlists-create-input");r.type="text",r.placeholder="Название плейлиста...";const o=()=>{const t=r.value.trim(),a=this.createPlaylist(t);this.expandedPlaylistId=a.id,e()};if(r.addEventListener("keydown",(e=>{"Enter"===e.key&&o()})),a.append(r),t.appendChild(a),this.main){const a=this.main.groupsManager.groups.filter((e=>e.games.length>0));if(a.length){const r=nt("button","playlists-create-groups-toggle");r.innerHTML=`${H.plus}Из группы`,t.appendChild(r);const o=nt("div","playlists-create-groups-row latest-games-hidden"),n=e=>{const t=e.games.map((e=>e.id)),a=this.load().find((t=>t.title===e.title));if(!a)return!1;const r=new Set(a.entries.map((e=>e.gameId)));return r.size===t.length&&t.every((e=>r.has(e)))};a.forEach((t=>{const a=nt("button","playlists-create-group-btn");a.textContent=t.title;const r=n(t);r&&a.classList.add("playlists-create-group-btn--done"),F(a,r?`Плейлист «${t.title}» уже создан из этой группы`:`Создать плейлист «${t.title}» из ${t.games.length} игр группы`),a.addEventListener("click",(r=>{if(r.stopPropagation(),n(t))return void alert(`Плейлист «${t.title}» уже существует и содержит те же самые игры. Новый плейлист не создан.`);const o=t.games.map((e=>e.id));if(this.load().find((e=>e.title===t.title))&&!confirm(`Плейлист «${t.title}» уже существует, но содержит другие игры. Создать новый?`))return;const s=this.createPlaylist(t.title);o.forEach((e=>this.addEntry(s.id,e,1))),this.expandedPlaylistId=s.id,a.classList.add("playlists-create-group-btn--done"),F(a,`Плейлист «${t.title}» уже создан из этой группы`),e()})),o.appendChild(a)})),r.addEventListener("click",(e=>{e.stopPropagation();const t=o.classList.toggle("latest-games-hidden");r.innerHTML=t?`${H.plus}Из группы`:`${H.chevronLeft}Свернуть`})),t.appendChild(o)}}return t},_buildGamePicker(e){const t=nt("div","playlist-game-picker"),a=nt("button","playlist-picker-toggle");a.innerHTML=`${H.plus}Добавить игры`;const r=nt("div","playlist-picker-body playlist-picker-body--hidden");if(a.addEventListener("click",(e=>{e.stopPropagation();const t=r.classList.toggle("playlist-picker-body--hidden");(e=>{a.innerHTML=e?`${H.plus}Добавить игры`:`${H.chevronLeft}Свернуть`})(t),requestAnimationFrame((()=>{t&&at.popup&&(null!==at._intendedX&&(at.popup.style.left=at._intendedX+"px"),null!==at._intendedY&&(at.popup.style.top=at._intendedY+"px")),at._constrain()}))})),!this.main)return t.append(a,r),t;const o=nt("div","playlist-picker-search-wrap"),n=nt("input","playlist-search-input");n.type="text",n.placeholder="Поиск по названию...",o.appendChild(n),r.appendChild(o),requestAnimationFrame((()=>{const e=o.offsetHeight;e&&r.style.setProperty("--picker-search-height",`${e}px`)})),n.addEventListener("click",(e=>e.stopPropagation()));const s=[];return this.main.groupsManager.groups.forEach((t=>{if(!t.games.length)return;const a=nt("div","playlist-picker-group-header",t.title);r.appendChild(a),t.games.forEach((t=>{const o=e.entries.some((e=>e.gameId===t.id)),n=M[t.params.gametype]||t.params.gametype,i=t.params.vocName?`«${t.params.vocName}»`:n,l=nt("div","playlist-picker-game-row"+(o?" already-added":"")),p=nt("span",`playlist-picker-game-name gametype-${t.params.gametype}`,i),c=nt("span","playlist-picker-game-desc",`${E[t.params.type]||t.params.type} · TM ${t.params.timeout}`),d=nt("button","playlist-picker-add-btn");d.innerHTML=o?H.checkmark:H.plus,F(d,o?"Уже в плейлисте":"Добавить в плейлист"),o?d.disabled=!0:d.addEventListener("click",(a=>{a.stopPropagation(),this.addEntry(e.id,t.id,1),d.innerHTML=H.checkmark,d.disabled=!0,l.classList.add("already-added");const r=d.closest(".playlist-block");if(r){const t=r.querySelector(".playlist-entries");if(t){t.querySelector(".playlist-entries-empty")?.remove();const a=this.load().find((t=>t.id===e.id)),r=a?.entries[a.entries.length-1];if(a&&r){e.entries.push(r);const o=this._buildEntryRow(a,r,null,!1,a.entries.length-1);t.appendChild(o),this._attachSortableDrag(t,{itemSelector:".playlist-entry-row",handleSelector:".playlist-entry-drag-handle",draggingClass:"playlist-entry-row--dragging",onReorder:(t,a)=>this.reorderEntries(e.id,t,a)})}}}})),l.append(p,c,d),r.appendChild(l),s.push({gameRow:l,groupHeader:a,name:i.toLowerCase()})}))})),s.length||r.appendChild(nt("div","playlist-picker-empty","Нет доступных игр")),n.addEventListener("input",(e=>{const t=e.target.value.toLowerCase().trim(),a=new Set;s.forEach((({gameRow:e,groupHeader:r,name:o})=>{const n=!t||o.includes(t);e.style.display=n?"":"none",n&&a.add(r)})),r.querySelectorAll(".playlist-picker-group-header").forEach((e=>{e.style.display=a.has(e)?"":"none"}))})),t.append(a,r),t}};function rt(){try{at.main?.pageHandler?.gamesDataContainer?.updatePlaylistIndicator()}catch{}}function ot(e,t,a,r){if(!r||t.repeatCount<=1||a<=0)return e.style.removeProperty("--playlist-progress"),void e.classList.remove("playlist-entry-row--progress");const o=Math.min(100,Math.round(a/t.repeatCount*100));e.classList.add("playlist-entry-row--progress"),e.style.setProperty("--playlist-progress",`${o}%`)}function nt(e,t,a){const r=document.createElement(e);return t&&(r.className=t),void 0!==a&&(r.textContent=a),r}class st{constructor(e){this.main=e,this.container=null,this.startIndicator=null,this.replayIndicator=null,this.startTimer=null,this.replayTimer=null,this.playCountIndicators={day:null,week:null,month:null,year:null}}ensureContainer(){if(this.container)return;const e=document.createElement("div");e.className="games-data-container",document.body.appendChild(e),this.container=e}createIndicator(e,t,a=null,r=null){this.ensureContainer();const o=document.createElement("div");return o.className=`indicator ${e}`,o.textContent=t,a&&F(o,a),(r||this.container).appendChild(o),o}getPlayCount(e){try{const t=JSON.parse(localStorage.getItem("playedVocabularies")||"[]"),a=new Date,r=new Date(a.getFullYear(),a.getMonth(),a.getDate()).getTime(),o=(a.getDay()+6)%7,n=new Date(a.getFullYear(),a.getMonth(),a.getDate()-o).getTime(),s=new Date(a.getFullYear(),a.getMonth(),1).getTime(),i=new Date(a.getFullYear(),0,1).getTime();let l=0,p=0;return t.forEach((t=>{if(!t.playHistory)return;let a=!1;t.playHistory.forEach((t=>{const o=new Date(t.date),l=new Date(o.getFullYear(),o.getMonth(),o.getDate()).getTime();("day"===e&&l===r||"week"===e&&l>=n&&l<=r||"month"===e&&l>=s&&l<=r||"year"===e&&l>=i&&l<=r)&&(a=!0,p+=t.count||0)})),a&&l++})),{uniqueVocabs:l,totalGames:p}}catch(t){return console.error(`Error calculating ${e} play count:`,t),{uniqueVocabs:0,totalGames:0}}}createGamesDataContainer(){this.ensureContainer(),this.createPlayCountIndicators(),this.createRemainingCountIndicator(),this.createPlaylistIndicator()}createPausedPlaylistIndicator(){const e=Ve();e?.paused&&(this.ensureContainer(),this.createPlaylistIndicator())}createPlayCountIndicators(){const e=document.createElement("div");e.className="period-indicators-container",this.container.appendChild(e);let t=0;[{period:"day",class:"today-play-count-indicator",description:"День",tooltipSuffix:"сегодня"},{period:"week",class:"week-play-count-indicator",description:"Неделя",tooltipSuffix:"неделю"},{period:"month",class:"month-play-count-indicator",description:"Месяц",tooltipSuffix:"месяц"},{period:"year",class:"year-play-count-indicator",description:"Год",tooltipSuffix:"год"}].forEach((({period:a,class:r,description:o,tooltipSuffix:n})=>{const{uniqueVocabs:s,totalGames:i}=this.getPlayCount(a);if(0===i&&"day"!==a)return;const l=this.createIndicator(r,"",`Количество словарей / Количество заездов за ${n}`,e);this.playCountIndicators[a]=l;const p=document.createElement("span");p.className="period-indicator-description",p.textContent=o,p.style.display="none";const c=document.createTextNode(`${s}/${i}`);l.appendChild(p),l.appendChild(c),l._descSpan=p,"day"!==a&&(l.classList.add("period-indicator"),l.style.setProperty("--fall-delay",90*t+++"ms"))})),e.addEventListener("mouseenter",(()=>this.toggleExtendedIndicators(!0))),e.addEventListener("mouseleave",(()=>this.toggleExtendedIndicators(!1)))}toggleExtendedIndicators(e){["day","week","month","year"].forEach((t=>{const a=this.playCountIndicators[t];a&&("day"!==t&&a.classList.toggle("show",e),a._descSpan.style.display=e?"":"none")}))}createRemainingCountIndicator(){!this.main.shouldReplayMore||Ve()&&!Ve().paused||this.createIndicator("remaining-count-indicator",`${this.main.remainingReplayCount}`,"Колличество оставшихся повторов текущего словаря")}updateRemainingCountIndicator(){if(!this.container)return;if(Ve()&&!Ve().paused){const e=this.container.querySelector(".remaining-count-indicator");return void(e&&e.remove())}const e=this.container.querySelector(".remaining-count-indicator");e&&(e.textContent=`${this.main.remainingReplayCount}`)}updateTodayIndicator(){const e=this.playCountIndicators.day;if(!e)return;const{uniqueVocabs:t,totalGames:a}=this.getPlayCount("day"),r=Array.from(e.childNodes).find((e=>e.nodeType===Node.TEXT_NODE));r&&(r.textContent=`${t}/${a}`)}_getPlaylistIndicatorData(){const e=Ve();if(!e)return null;try{const t=JSON.parse(localStorage.getItem("latestGamesPlaylists")||"[]").find((t=>t.id===e.playlistId));if(!t)return null;const a=Array.isArray(e.shuffleOrder)&&e.shuffleOrder.length===t.entries.length?e.shuffleOrder:null,r=a?a[e.entryIndex]??0:e.entryIndex,o=t.entries[r];if(!o)return null;const n=t.repeatCount??1;return{session:e,playlist:t,total:t.entries.length,position:e.entryIndex+1,remainingRepeats:e.remainingRepeats,repeatCount:o.repeatCount??1,totalCycles:n,remainingCycles:n>1?e.remainingCycles??n:1,shuffleActive:e.shuffleActive??!!t.shuffle}}catch{return null}}createPlaylistIndicator(){const e=this._getPlaylistIndicatorData();if(!e)return;const{playlist:t,position:a,total:r,remainingRepeats:o,repeatCount:n,session:s,totalCycles:i,remainingCycles:l}=e;this.ensureContainer();const p=document.createElement("div");p.className="indicator playlist-progress-indicator",this._renderPlaylistIndicator(p,t,a,r,o,n,s,i,l,!!e.shuffleActive),this.container.appendChild(p),this.main.playlistPanelAutoOpen>=1&&!at.popup&&requestAnimationFrame((()=>{const e=p.getBoundingClientRect();at.show(e.left,e.bottom)}))}_renderPlaylistIndicator(e,t,a,r,o,n,s,i=1,l=1,p=!1){const c=!!s?.paused;e.classList.toggle("playlist-progress-indicator--paused",c),e.innerHTML=this._playlistIndicatorHTML(a,r,o,n,c,i,l,p);const d=e.querySelector(".playlist-hud-data");let g=`[Плейлист] ${t.title}[Позиция] ${a} из ${r}`;n>1&&(g+=`[Осталось повторов] ${o}`),i>1&&(g+=`[Цикл] ${i-l+1} из ${i}`),p&&(g+="[Порядок] случайный"),F(d,g),d.addEventListener("click",(()=>{const t=e.getBoundingClientRect();2===this.main.playlistPanelAutoOpen&&"game"===ae()?at.popup||at.show(t.left,t.bottom):at.toggle(t.left,t.bottom)}));const u=e.querySelector(".playlist-hud-pause");u&&(F(u,`Приостановить плейлист «${t.title}»`),u.addEventListener("click",(e=>{e.stopPropagation();const t=Ve();if(t){Re({...t,paused:!0});try{this.main.pageHandler?.cancelReplay(!0)}catch(e){}this.updatePlaylistIndicator(),at.refresh()}})));const m=e.querySelector(".playlist-hud-resume");m&&(F(m,`Возобновить плейлист «${t.title}»`),m.addEventListener("click",(e=>{e.stopPropagation();const t=Ve();if(!t)return;Re({...t,paused:!1});const a=Oe(this.main);a?window.location.href=a:this.updatePlaylistIndicator()})));const h=e.querySelector(".playlist-hud-stop");h&&(F(h,`Остановить плейлист «${t.title}»`),h.addEventListener("click",(t=>{t.stopPropagation(),je(),e.remove(),at.refresh()})))}_playlistIndicatorHTML(e,t,a,r,o=!1,n=1,s=1,i=!1){return`\n ${o?``:``}\n
\n ${e}/${t}\n ${r>1?`${H.x}${a}`:""}\n ${n>1?`${H.refresh}${n-s+1}/${n}`:""}\n ${i?`${H.random}`:""}\n
\n \n `}updatePlaylistIndicator(){if(!this.container)return;const e=this.container.querySelector(".playlist-progress-indicator");if(!e)return;const t=this._getPlaylistIndicatorData();if(!t)return void e.remove();const{playlist:a,position:r,total:o,remainingRepeats:n,repeatCount:s,session:i,totalCycles:l,remainingCycles:p,shuffleActive:c}=t;this._renderPlaylistIndicator(e,a,r,o,n,s,i,l,p,c)}createSleepIndicator(e,t,a=null,r=null){this.ensureContainer();const o=document.createElement("div");o.className="indicator "+("start"===e?"sleep-start-indicator":"sleep-replay-indicator"),this.container.insertBefore(o,this.container.firstChild);F(o,"start"===e?"[Наведение] Заморозить таймер [Клик] Отменить автоматический старт игры":"[Наведение] Заморозить таймер [Клик] Отменить автоматический повтор игры"),o.addEventListener("click",(()=>{o.classList.add("sleep-indicator-dismissing"),setTimeout((()=>{r&&r()}),300)}),{once:!0}),"start"===e?this.startIndicator=o:this.replayIndicator=o;let n=null,s=!1;const i=()=>{if(s)return;const t=a?.getRemainingMs?.()??0;o.textContent=(e=>{const t=Math.floor(e/1e3),a=Math.floor(e%1e3/10);return`${t.toString().padStart(2,"0")}:${a.toString().padStart(2,"0")}`})(t),t>0&&(n=requestAnimationFrame(i),"start"===e?this.startTimer=n:this.replayTimer=n)};o.addEventListener("mouseenter",(()=>{s=!0,cancelAnimationFrame(n),n=null,a?.pause?.(),o.classList.add("sleep-indicator-paused")})),o.addEventListener("mouseleave",(()=>{s=!1,o.classList.remove("sleep-indicator-paused"),a?.resume?.(),i()})),i()}removeSleepIndicator(e,t=!1){const a=(e,a,r)=>{if(this[a]&&(cancelAnimationFrame(this[a]),this[a]=null),!e)return Promise.resolve();this[r]=null;const o=e.classList.contains("sleep-indicator-dismissing");return t&&!o&&e.classList.add("sleep-indicator-dismissing"),t||o?new Promise((t=>setTimeout((()=>{e.remove(),t()}),300))):(e.remove(),Promise.resolve())};return"start"===e?a(this.startIndicator,"startTimer","startIndicator"):"replay"===e?a(this.replayIndicator,"replayTimer","replayIndicator"):Promise.resolve()}}class it{constructor(e){this.main=e,this.gamesDataContainer=new st(e),this.replaySleep=null,this.startSleep=null,this.isHoveringInteractivePanel=!1,this.remainingReplayCount=this.main.replayNextGameCount}handlePageSpecificLogic(){const{href:e}=location;if(/https?:\/\/klavogonki\.ru\/create\//.test(e)){const e=()=>{const e=document.querySelector('#content p[align="center"]');return!!e&&(this.handleVocabularyError(e.innerText||""),!0)};if(!e()){const t=new MutationObserver((()=>{e()&&t.disconnect()}));t.observe(document.body,{childList:!0,subtree:!0})}}if(/https?:\/\/klavogonki\.ru\/g\/\?gmid=/.test(e)||this.gamesDataContainer.createPausedPlaylistIndicator(),/https?:\/\/klavogonki\.ru\/g\/\?gmid=/.test(e)){this.gamesDataContainer.createGamesDataContainer(),this.setupHoverListeners();const e=new MutationObserver((()=>{const t=document.querySelector("#gamedesc");t&&t.textContent&&(e.disconnect(),this.saveCurrentGameParams(),this.handleStartAction())}));e.observe(document.body,{childList:!0,subtree:!0});const t=this.main.replayWithoutWaiting?document.querySelector(T.immediate):document.querySelector(T.normal);if(t){const e=new MutationObserver((()=>{e.disconnect();if(!this._isGameFailed()){try{const e=Te();if(e)try{if("vocabulary"===se().category){try{this.main.gamesManager.markVocabAsPlayed(e)}catch(e){}try{this.gamesDataContainer.updateTodayIndicator()}catch(e){}}}catch(e){}}catch(e){}if(Ve()&&!Ve().paused){const e=ze(this.main);try{this.gamesDataContainer.updatePlaylistIndicator()}catch{}try{at.updateActiveEntryProgress()}catch{}if("paused"===e)return;if(e&&e.url)return void this.handlePlaylistReplay(e.url)}}this.handleReplayAction()}));e.observe(t,{attributes:!0})}}null!==oe()&&(fe(this.main.groupsManager.groups),He(this.main.groupsManager.groups,this.main),function(){const e=[".columns.voclist","#gamelist","#gamedesc"].map((e=>document.querySelector(e))).filter((e=>e));if(0===e.length)return void console.warn("No supported containers found.");const t=async e=>{if(!e.shiftKey)return;const t=e.target.closest('a[href*="/vocs/"]');if(t){const e=t.getAttribute("href"),a=e.match(/\/vocs\/(\d+)(?:\/|$)/);if(!a)return void console.warn(`Invalid vocabulary href: ${e}`);const r=a[1];if(t._tooltipData)Ee(t,t._tooltipData.content,t._tooltipData.metadata);else{const e=await Se(r);t._tooltipData=e,Ee(t,e.content,e.metadata)}}},a=e=>{const t=e.target.closest('a[href*="/vocs/"]');t&&Me===t&&Ge(),Ce&&clearTimeout(Ce)};e.forEach((e=>{e.addEventListener("mouseenter",t,{capture:!0}),e.addEventListener("mouseleave",a,{capture:!0})}))}())}handleVocabularyError(e){const t=e.includes("Открытые заезды можно создавать только по публичным словарям"),a=e.includes("Словарь не найден");if(!t&&!a)return;let r=null;try{r=JSON.parse(sessionStorage.getItem("latestGames_pendingVocId"))?.vocId||null}catch(e){}if(!r)return;const o=this.main.gamesManager.findGamesByVocId(r);if(!o.length)return;const n=o[0].params.vocName||`#${r}`;if(a){if(o.every((e=>!0===e.params.vocIsRemoved)))return;return o.forEach((e=>{e.params.vocIsRemoved=!0})),this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer(),void alert(`🗑️ Словарь «${n}» недоступен.\n\nСловарь был удалён модераторами. Все игры с этим словарём помечены как удалённые.`)}!o.some((e=>"normal"===e.params.type))&&o.every((e=>!1===e.params.vocIsPublic))||(o.forEach((e=>{e.params.vocIsPublic=!1,"normal"===e.params.type&&(e.params.type="practice",e.params.timeout=5)})),this.main.gamesManager.saveGameData(),this.main.uiManager.refreshContainer(),confirm(`🔒 Словарь «${n}» стал непубличным.\n\nПараметры открытых игр с этим словарём были автоматически обновлены:\n• Режим изменён с «Обычного» на «Одиночный» (practice)\n• Таймаут изменён на 5 секунд\nОдиночные и дружеские игры оставлены без изменений.\n\nХотите запустить одиночную игру по этому словарю прямо сейчас?`)&&(window.location.href=this.main.gamesManager.generateGameLink(o[0])))}setupHoverListeners(){const e=["#latest-games-container",".playlists-manager-popup","#errors_text","#params","#wts-side-panel","#wts-draggable-window"],t=t=>e.some((e=>t.closest(e)));let a=null;document.addEventListener("mouseover",(e=>{t(e.target)&&(this.isHoveringInteractivePanel||(this.isHoveringInteractivePanel=!0,clearTimeout(a),this.replaySleep&&"function"==typeof this.replaySleep.cancel&&this.cancelReplay(!0)))})),document.addEventListener("mouseout",(e=>{if(!this.isHoveringInteractivePanel)return;const r=e.relatedTarget;r&&t(r)||(this.isHoveringInteractivePanel=!1,a=setTimeout((()=>this.handleReplayAction()),350))}))}saveCurrentGameParams(){const e=document.querySelector("#gamedesc");if(!e)throw new Error("#gamedesc element not found.");const t=e.querySelector("span");if(!t)throw new Error("#gamedesc span element not found.");const a=e.textContent;if(/соревнование/.test(a)||!this.main.maxGameCount||!1===this.main.shouldAutoSave)return!1;const r=this.main.gamesManager.parseGameParams(t,a),o=JSON.stringify(r);let n=this.main.groupsManager.groups.find((e=>"Сохранённые"===e.title));n||(n=this.main.groupsManager.createGroup("Сохранённые"),this.main.groupsManager.groups.push(n));if(n.games.some((e=>JSON.stringify(e.params)===o)))return;const s={params:r,id:ee(this.main.groupsManager.groups),pin:0},i=n.games.filter((e=>e.pin)).length;n.games.splice(i,0,s);const l=i+this.main.maxGameCount;n.games.length>l&&n.games.splice(l,n.games.length-l),this.main.gamesManager.assignGameIds(),this.main.gamesManager.saveGameData()}cancelStart(){this.startSleep&&(this.startSleep.cancel(),this.startSleep=null),this.gamesDataContainer.removeSleepIndicator("start")}cancelReplay(e=!1){this.replaySleep&&(this.replaySleep.cancel(),this.replaySleep=null),this.gamesDataContainer.removeSleepIndicator("replay",e)}_isGameFailed(){const e=document.querySelector(N.noError);if(!e)return!1;const t=getComputedStyle(e);return"none"!==t.display&&"hidden"!==t.visibility}handleStartAction(){if(this.main.shouldStart){const e=document.querySelector("#status-inner #paused");e&&"none"!==e.style.display&&"undefined"!=typeof game&&game.hostStart&&(this.cancelStart(),this.startSleep=te(this.main.startDelay),this.gamesDataContainer.createSleepIndicator("start",this.main.startDelay,this.startSleep,(()=>this.cancelStart())),this.startSleep.then((()=>{this.gamesDataContainer.removeSleepIndicator("start",!0),game.hostStart()})).catch((()=>{this.gamesDataContainer.removeSleepIndicator("start"),this.startSleep=null})))}}replayNextGame(){const e=this.main.groupsManager,t=this.main.gamesManager;let a=null,r=null,o=null,n=null;if(this.main.randomGameId){const s=t.getRandomGameId();if(!s)return;if("global"===s.mode)return void(async()=>{const e=await t.getValidRandomGameId();if(!e)return alert("Максимальное количество попыток поиска подходящей игры исчерпано. Попробуйте ещё раз.");if(a=e.id,n=e.url,a)try{t.registerPendingPlayed(a)}catch(e){}window.location.href=n})();if("local"===s.mode){const i=e.groups.find((e=>e.games.some((e=>e.id===s.id))));if(i&&e.selectGroup(i.id),t.latestGamesData=t.latestGamesData||{},t.latestGamesData.previousGameId=s.id,t.saveGameData(),a=String(s.game?.params?.vocId||""),r=s.game?.params?.vocName||null,o=s.game?.params?.vocType||null,n=s.game?t.generateGameLink(s.game):s.url,a)try{t.registerPendingPlayed(a,r||null,o||null)}catch(e){}n&&(window.location.href=n)}return}const s=e.getCurrentGroup(e.groups,e.currentGroupId);if(!s||!Array.isArray(s.games)||0===s.games.length)return;const i=t.latestGamesData?.previousGameId;let l=s.games.findIndex((e=>e.id===i));l=-1===l?0:(l+1)%s.games.length;const p=s.games[l];if(p){if(t.latestGamesData.previousGameId=p.id,t.saveGameData(),a=String(p.params.vocId||""),r=p.params.vocName||null,o=p.params.vocType||null,n=t.generateGameLink(p),a)try{t.registerPendingPlayed(a,r||null,o||null)}catch(e){}window.location.href=n}}_startReplaySleep(e){this.cancelReplay(),this.replaySleep=te(this.main.replayDelay),this.gamesDataContainer.createSleepIndicator("replay",this.main.replayDelay,this.replaySleep,(()=>this.cancelReplay())),this.replaySleep.then((()=>{this.gamesDataContainer.removeSleepIndicator("replay",!0).then((()=>{const t=e();t&&(window.location.href=t)}))})).catch((()=>{this.gamesDataContainer.removeSleepIndicator("replay"),this.replaySleep=null}))}handlePlaylistReplay(e){this.main.shouldReplay&&this._startReplaySleep((()=>e))}handleReplayAction(){if(!["competition","qualification"].includes(se().category)&&this.main.shouldReplay){const e=this.main.replayWithoutWaiting?document.querySelector(T.immediate):document.querySelector(T.normal);if(e&&"none"!==e.style.display){const e=!Ve()?.paused&&Oe(this.main);if(e)return void this._startReplaySleep((()=>e));const t=location.href.match(/gmid=(\d+)/);if(t){const e=t[1];this.isHoveringInteractivePanel||(this.main.shouldReplayMore&&(this.main.remainingReplayCount--,this.gamesDataContainer.updateRemainingCountIndicator(),this.main.settingsManager.saveSettings()),this._startReplaySleep((()=>{if(this.main.shouldReplayMore&&this.main.remainingReplayCount<=0)this.main.remainingReplayCount=this.main.replayNextGameCount,this.main.settingsManager.saveSettings(),this.replayNextGame();else{if(this.main.shouldReplayMore||!this.main.replayNextGame)return`https://klavogonki.ru/g/${e}.replay`;this.replayNextGame()}})))}}}}}function lt(e,t,a,r,o){K();const n=t.filter((e=>e.id!==a)).map((t=>({text:t.title,className:"group-tab",dataset:{groupId:t.id},onClick:()=>{!function(e,t,a){const r=e.groupsManager.groups.find((e=>e.games.some((e=>e.id===t)))),o=e.groupsManager.groups.find((e=>e.id===a));if(!r||!o)return;if(r.id===o.id)return;const n=r.games.findIndex((e=>e.id===t));if(-1===n)return;const[s]=r.games.splice(n,1);o.games.push(s),e.gamesManager.saveGameData(),e.uiManager.refreshContainer()}(e,o,t.id)}})));xe(n,r,"game-migration-popup","Переместить")}const pt=10;const ct=Object.keys(E),dt=1,gt=6,ut=6,mt=9,ht=[".popup-header",".popup-header-title",".popup-header-badge",".popup-subheader",".rank-slider-display",".idle-times-container",".timeouts-container"],yt=[".game-popup-button",".rank-slider-handle",".rank-slider-track",".rank-slider-range",".popup-header-qualification",".popup-header-save"];function vt(e,t){return t?Math.max(dt,Math.min(gt,e)):Math.max(ut,Math.min(mt,e))}function bt(e,t,a,r="game-popup"){K();const o=document.querySelector(`.${r}`);o&&o.remove();const n=re("div",{className:r}),s=re("div",{className:"popup-header"}),i=re("div",{className:"popup-header-title",textContent:a.saveModeEnabled?"Сохранить":"Создать"}),l=re("div",{className:"popup-header-badge"}),p=re("div",{className:"popup-header-controls"}),c=re("span",{className:"popup-header-qualification",innerHTML:H.qualification}),d=re("span",{className:"popup-header-save",innerHTML:H.save});let g=a.saveModeEnabled??!1,u=g?1===e.params.qual:a.qualificationEnabled??!1,[m,h]=g?[vt(e.params.level_from||1,!0),vt(e.params.level_to||9,!1)]:a.rankRange||[dt,mt];m>h&&(m=h),h{const o=M[f]||f,n=E[t]||t;l.className=`popup-header-badge popup-header-badge--${f}`,l.textContent=o,l.querySelectorAll(".popup-header-badge-chip").forEach((e=>e.remove()));const s=(e,t="")=>{const a=re("span",{className:"popup-header-badge-chip"+(t?" "+t:""),textContent:e});l.appendChild(a)};s(n),s(`TM ${a}`),r>0&&s(`AFK ${r}`),!0===e.params.vocIsRemoved?s("удалён","popup-header-badge-chip--removed"):!1===e.params.vocIsPublic&&s("непубличный","popup-header-badge-chip--private")},w=()=>{e.params.level_from=m,e.params.level_to=h,e.params.qual=u?1:0,e.params.idletime=v,a.gamesManager.saveGameData(),a.uiManager?.refreshContainer?.(),x(e.params.type,e.params.timeout,e.params.idletime),d.classList.remove("rg-rotate"),d.offsetWidth,d.classList.add("rg-rotate")},k=()=>{g&&(clearTimeout(y),y=setTimeout(w,500))},C=()=>{c.classList.toggle("latest-games-disabled",!u),F(c,"Квалификация: "+(u?"Включена":"Отключена"))},S=()=>{d.classList.toggle("latest-games-disabled",!g),i.textContent=g?"Сохранить":"Создать",F(d,"Сохранение: "+(g?"Включено":"Отключено")),x(e.params.type,e.params.timeout,e.params.idletime)};C(),S(),c.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),u=!u,g||(a.qualificationEnabled=u,a.settingsManager.saveSettings()),C(),q(),k()}));const L=re("div",{className:"rank-slider-container"}),G=re("div",{className:"rank-slider-track"}),T=re("div",{className:"rank-slider-range"}),N=[re("div",{className:"rank-slider-handle",tabIndex:0}),re("div",{className:"rank-slider-handle",tabIndex:0})],P=re("div",{className:"rank-slider-display"});function A(){m=vt(m,!0),h=vt(h,!1),m>h&&(m=h),h{r[t].forEach((t=>e.classList.toggle(t,a)))})),q()}function q(){0!==b.length&&b.forEach((({btn:t,type:r,timeout:o})=>{const n={...e,params:{...e.params,type:r,timeout:o,level_from:m,level_to:h,qual:u?1:0,idletime:v}},s=a.gamesManager.generateGameLink(n);t.setAttribute("href",s),t.onclick=t=>{if(t.preventDefault(),t.stopPropagation(),g)clearTimeout(y),e.params.type=r,e.params.timeout=o,e.params.level_from=m,e.params.level_to=h,e.params.qual=u?1:0,e.params.idletime=v,"normal"===r&&(!1===e.params.vocIsPublic&&(e.params.vocIsPublic=!0),e.params.timeout<10&&(e.params.timeout=10)),w();else{try{const t=JSON.parse(localStorage.getItem("latestGamesData"))||{};t.previousGameId=e.id,localStorage.setItem("latestGamesData",JSON.stringify(t))}catch(e){}window.location.href=s}}}))}function _(){g||(a.rankRange=[m,h],a.settingsManager.saveSettings()),k()}d.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation(),g=!g,a.saveModeEnabled=g,a.settingsManager.saveSettings(),S(),g?(u=1===e.params.qual,m=vt(e.params.level_from||1,!0),h=vt(e.params.level_to||9,!1)):(u=a.qualificationEnabled??!1,[m,h]=a.rankRange||[dt,mt]),m>h&&(m=h),h{const t=G.getBoundingClientRect(),a=(e.clientX-t.left)/t.width;let r=Math.round(a*(I.length-1))+1;Math.abs(r-m){e.addEventListener("mousedown",(e=>{e.preventDefault();let a=0===t?m:h;const r=({clientX:e})=>{const{left:r,width:o}=G.getBoundingClientRect();let n=Math.round((e-r)/o*(I.length-1))+1;n=vt(n,0===t);const s=0===t?Math.min(n,h):Math.max(n,m);s!==a&&(a=s,0===t?m=s:h=s,A())},o=()=>{_(),document.removeEventListener("mousemove",r),document.removeEventListener("mouseup",o)};document.addEventListener("mousemove",r),document.addEventListener("mouseup",o)}))})),G.appendChild(T),N.forEach((e=>G.appendChild(e))),L.appendChild(P),L.appendChild(G),n.appendChild(L);const B=re("div",{className:"popup-subheader",textContent:"AFK"});n.appendChild(B);const V=re("div",{className:"idle-times-container"});return D.forEach((t=>{const a=re("a",{href:"#",className:"game-popup-button",textContent:t});t===v&&a.classList.add("active"),a.onclick=r=>{r.preventDefault(),r.stopPropagation(),V.querySelectorAll(".game-popup-button").forEach((e=>{e.classList.remove("active")})),a.classList.add("active"),v=t,x(e.params.type,e.params.timeout,v),q(),k()},V.appendChild(a)})),n.appendChild(V),ct.forEach((t=>{const r=re("div",{className:"popup-subheader",textContent:E[t]});n.appendChild(r);const o=re("div",{className:"timeouts-container"});$.forEach((r=>{if("normal"===t&&5===r)return;const n={...e,params:{...e.params,type:t,timeout:r,level_from:m,level_to:h,qual:u?1:0}},s=re("a",{href:a.gamesManager.generateGameLink(n),className:"game-popup-button",textContent:r});b.push({btn:s,type:t,timeout:r}),o.appendChild(s)})),n.appendChild(o)})),A(),function(e,t){e.querySelectorAll("a").forEach((e=>{e.scrollWidth>e.clientWidth&&F(e,e.textContent)})),function(e,t,a={}){const{draggableSelectors:r=[],interactiveSelectors:o=[],onClose:n=null}=a;e.parentNode||(e.style.visibility="hidden",document.body.appendChild(e));const s=(t,a)=>{const r=window.innerWidth,o=window.innerHeight,n=e.getBoundingClientRect(),s=r-n.width-pt,i=o-n.height-pt,l=Math.max(pt,Math.min(t,s)),p=Math.max(pt,Math.min(a,i));e.style.left=`${l}px`,e.style.top=`${p}px`};s(t.clientX,t.clientY),e.style.visibility="visible";const i={clickOutside:null,keydown:null,popupMouseDown:t=>{if((a=t.target)!==e&&!r.some((e=>a.matches&&a.matches(e)))||(e=>o.some((t=>e.matches&&(e.matches(t)||e.closest(t)))))(t.target))return;var a;if(0!==t.button)return;t.preventDefault();const n=t.clientX,l=t.clientY,p=parseInt(e.style.left,pt),c=parseInt(e.style.top,pt),d=e=>{const t=e.clientX-n,a=e.clientY-l;s(p+t,c+a)},g=()=>{document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",g),i.currentDrag=null};i.currentDrag={onMouseMove:d,onMouseUp:g},document.addEventListener("mousemove",d),document.addEventListener("mouseup",g)},currentDrag:null};e.addEventListener("mousedown",i.popupMouseDown),e.style.cursor="move";const l=t=>{t&&"keydown"===t.type&&"Escape"!==t.key||(n&&n(),p(),e.remove())},p=()=>{i.clickOutside&&document.removeEventListener("click",i.clickOutside),i.keydown&&document.removeEventListener("keydown",i.keydown),i.popupMouseDown&&e.removeEventListener("mousedown",i.popupMouseDown),i.currentDrag&&(document.removeEventListener("mousemove",i.currentDrag.onMouseMove),document.removeEventListener("mouseup",i.currentDrag.onMouseUp))};i.clickOutside=t=>{e.contains(t.target)||l(t)},i.keydown=e=>{"Escape"===e.key&&l(e)},requestAnimationFrame((()=>{document.addEventListener("click",i.clickOutside),document.addEventListener("keydown",i.keydown)}))}(e,t,{draggableSelectors:ht,interactiveSelectors:yt})}(n,t),n}function ft(e,t,a,r){let o,n,s=!1;const i=e=>{if(!s)return;const r=t(e,o);a(r,n)},l=()=>{s&&(s=!1,document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",l),r())};e.onmousedown=e=>{0===e.button&&(s=!0,[o,n]=t(e),document.addEventListener("mousemove",i),document.addEventListener("mouseup",l),e.preventDefault())}}function xt(e,t,a,r,o){const n=e.main.viewManager.getDisplayMode(),s=ae();if("wrap"===n){const r=e.main.panelWidths?.[s]||e.main.panelWidth;t.style.width=r,a.style.display="",ft(a,((e,a)=>void 0===a?[e.clientX,t.offsetWidth]:e.clientX-a),((e,a)=>{let r=a+e;const o=.95*window.innerWidth;r=Math.max(350,Math.min(r,o));const n=Math.round(r/window.innerWidth*100*10)/10;t.style.width=`${n}vw`}),(()=>{e.main.panelWidths=e.main.panelWidths||{},e.main.panelWidths[s]=t.style.width,e.main.settingsManager.saveSettings()}))}else a.style.display="none",t.style.width="",a.onmousedown=null;const i=e.main.panelHeights?.[s]||P.panelHeight;t.style.height=i,r&&(r.style.display="",ft(r,((e,a)=>void 0===a?[e.clientY,t.offsetHeight]:e.clientY-a),((e,a)=>{let r=a+e;const o=.95*window.innerHeight;r=Math.max(200,Math.min(r,o));const n=Math.round(r/window.innerHeight*100*10)/10;t.style.height=`${n}vh`}),(()=>{e.main.panelHeights=e.main.panelHeights||{},e.main.panelHeights[s]=t.style.height,e.main.settingsManager.saveSettings()}))),o&&(o.style.display="",ft(o,((e,a)=>{if(void 0===a){const a=parseFloat(t.style.top)||0;return[e.clientY,{height:t.offsetHeight,top:a}]}return a-e.clientY}),((e,a)=>{let r=a.height+e;const o=.95*window.innerHeight;r=Math.max(200,Math.min(r,o));const n=(r-a.height)/window.innerHeight*100;let s=a.top-n;s=Math.max(0,s);const i=Math.round(r/window.innerHeight*100*10)/10,l=Math.round(10*s)/10;t.style.height=`${i}vh`,t.style.top=`${l}vh`}),(()=>{const a=ae();e.main.panelHeights=e.main.panelHeights||{},e.main.panelHeights[a]=t.style.height,e.main.panelYPosition=e.main.panelYPosition||{};const r=parseFloat(t.style.top)||0;e.main.panelYPosition[a]=r,e.main.settingsManager.saveSettings()})))}function wt(e,t){if("wrap"===e.main.viewManager.getDisplayMode()){const a=ae(),r=e.main.panelYPosition[a]??0;"number"==typeof r&&r>=0&&r<=100&&(t.style.top=`${r}vh`);let o,n,s=!1;const i=e=>{if(!s)return;const a=e.clientY-o,r=n+a/window.innerHeight*100,i=t.offsetHeight,l=Math.max(0,(window.innerHeight-i)/window.innerHeight*100),p=Math.max(0,Math.min(r,l)),c=Math.round(10*p)/10;t.style.top=`${c}vh`},l=()=>{if(!s)return;s=!1,document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",l);const a=ae(),r=t.getBoundingClientRect(),o=Math.round(r.top/window.innerHeight*100*10)/10;e.main.panelYPosition[a]=o,e.main.settingsManager.saveSettings()},p=e=>{if(0!==e.button)return;if([".latest-game",".group-tab",".control-button",".resize-handle-horizontal",".resize-handle-vertical","#latest-games-search-input"].some((t=>e.target.closest(t))))return;s=!0,o=e.clientY;const a=t.getBoundingClientRect();n=a.top/window.innerHeight*100,document.addEventListener("mousemove",i),document.addEventListener("mouseup",l),e.preventDefault()};t.addEventListener("mousedown",p)}}const kt={draggedElement:null,isDragging:!1,isRightHalf:!1,dragDirection:0,lastDragDirection:0,lastPanelDragY:0,dragOffset:{x:0,y:0},initialX:0,initialY:0,dragThreshold:1,rotationAccumulator:0,rotationDegreeLimit:5,globalEvents:{},reset(){this.draggedElement=null,this.isDragging=!1,this.isRightHalf=!1,this.dragDirection=0,this.lastDragDirection=0,this.lastPanelDragY=0,this.dragOffset={x:0,y:0},this.initialX=0,this.initialY=0,this.rotationAccumulator=0,this.globalEvents={}},cleanup(){this.globalEvents.handleDragMove&&document.removeEventListener("mousemove",this.globalEvents.handleDragMove),this.globalEvents.handleDragEnd&&document.removeEventListener("mouseup",this.globalEvents.handleDragEnd),this.globalEvents={}}};function Ct(e){const t=e.getBoundingClientRect(),a=e.parentElement.getBoundingClientRect(),r=e.parentElement;return{element:{rect:t,width:e.offsetWidth,height:e.offsetHeight},parent:{rect:a,width:r.offsetWidth,height:r.offsetHeight}}}let Mt=null;function St(){Mt&&Mt.parentNode&&Mt.parentNode.removeChild(Mt)}function Lt(e,t){const a=Ct(kt.draggedElement);let r=e.clientX-kt.dragOffset.x-a.parent.rect.left,o=e.clientY-kt.dragOffset.y-a.parent.rect.top;r=Math.max(0,Math.min(r,a.parent.width-a.element.width)),o=Math.max(0,Math.min(o,a.parent.height-a.element.height)),kt.draggedElement.style.left=`${r}px`,kt.draggedElement.style.top=`${o}px`;const n=Array.from(t.querySelectorAll(".pin-game:not(.dragging)"));let s=null,i=1/0;if(n.forEach((t=>{const a=t.getBoundingClientRect(),r=a.left+a.width/2,o=a.top+a.height/2,n=Math.hypot(e.clientX-r,e.clientY-o);n{if(a.preventDefault(),0!==a.button)return;if(a.target.closest(".latest-game-buttons"))return;kt.cleanup(),e.wasDragging=!1,kt.initialX=a.clientX,kt.initialY=a.clientY,kt.isDragging=!0,kt.draggedElement=t;const r=Ct(t),o=a.clientX-r.element.rect.left;kt.isRightHalf=o>r.element.rect.width/2,kt.lastPanelDragY=a.clientY,kt.dragOffset={x:a.clientX-r.element.rect.left,y:a.clientY-r.element.rect.top},kt.globalEvents.handleDragMove=t=>function(e,t){if(!kt.isDragging||!kt.draggedElement)return;if(document.querySelectorAll(".dragged-game").forEach((e=>e.classList.remove("dragged-game"))),!t.wasDragging&&function(e){return Math.abs(e.clientX-kt.initialX)>kt.dragThreshold||Math.abs(e.clientY-kt.initialY)>kt.dragThreshold}(e)&&(t.wasDragging=!0,kt.draggedElement.classList.add("dragging"),"wrap"===t.viewManager.getDisplayMode())){const e=Ct(kt.draggedElement);kt.draggedElement.style.position="absolute",kt.draggedElement.style.left=e.element.rect.left-e.parent.rect.left+"px",kt.draggedElement.style.top=e.element.rect.top-e.parent.rect.top+"px",kt.draggedElement.style.width=`${e.element.rect.width}px`}e.preventDefault();const a=t.viewManager.getDisplayMode(),r=document.getElementById("latest-games");"scroll"===a?function(e,t){const a=Array.from(t.querySelectorAll(".pin-game:not(.dragging)"));let r=null;for(const t of a){const a=t.getBoundingClientRect(),o=a.top+a.height/2;if(e.clientYfunction(e){if(kt.cleanup(),St(),!kt.isDragging||!kt.draggedElement)return void kt.reset();kt.isDragging=!1,kt.draggedElement.classList.remove("dragging"),kt.draggedElement.classList.add("dragged-game");const t=e.viewManager.getDisplayMode();"wrap"===t&&(kt.draggedElement.style.position="",kt.draggedElement.style.left="",kt.draggedElement.style.top="",kt.draggedElement.style.width="");kt.draggedElement.style.transform="",e.gamesManager.updateGameOrderFromDOM(),kt.reset()}(e),document.addEventListener("mousemove",kt.globalEvents.handleDragMove),document.addEventListener("mouseup",kt.globalEvents.handleDragEnd)}))}const It=new class{constructor(){this.cache=new Map}getUserId(){const e=document.querySelector(".userpanel .user-block .name img");if(!e)return null;const t=e.src.match(/\/avatars\/(\d+)_/);return t?t[1]:null}parseGameParams(e){const t=e.href,a=new URL(t),r={};for(const[e,t]of a.searchParams)r[e]=t;return r}getGameId(e){const t=this.parseGameParams(e);return"voc"===t.gametype&&t.voc?t.voc:t.gametype?t.gametype:"normal"}buildApiUrl(e,t){const a=new URLSearchParams({userId:e}),r=Object.keys(M);return"voc"===t.gametype&&t.voc?a.append("gametype",`voc-${t.voc}`):t.gametype&&r.includes(t.gametype)?a.append("gametype",t.gametype):(console.warn(`Unsupported gametype "${t.gametype}", defaulting to "normal"`),a.append("gametype","normal")),`https://klavogonki.ru/api/profile/get-stats-details?${a.toString()}`}async fetchGameStats(e){if(this.cache.has(e))return this.cache.get(e);try{const t=await fetch(e);if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const a=await t.json();return this.cache.set(e,a),a}catch(e){return console.error("Failed to fetch game stats:",e),null}}formatTime(e){if(!e)return"N/A";return`${Math.floor(e/60)}:${(e%60).toString().padStart(2,"0")}`}formatDate(e){if(!e)return"N/A";try{return new Date(e).toLocaleDateString("ru-RU",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch(t){return e}}formatStats(e,t,a){if(!e||!e.ok)return"Данные отсутствуют";const{gametype:r,info:o}=e;let n="";if(n+="## Информация",r){if(r.name&&(n+=`[Название] ${r.name}`),r.id&&(n+=`[ID словаря] ${r.id}`),r.type){n+=`[Категория] ${S[r.type]||r.type}`}r.symbols&&(n+=`[Символов] ${r.symbols.toLocaleString()}`),r.rows&&(n+=`[Строк] ${r.rows.toLocaleString()}`)}if(n+="## Статистика",o&&(o.num_races&&(n+=`[Заездов] ${o.num_races}`),o.avg_speed&&(n+=`[Средняя скорость] ${Math.round(o.avg_speed)} зн/мин`),o.best_speed&&(n+=`[Лучшая скорость] ${o.best_speed} зн/мин`),void 0!==o.avg_error&&(n+=`[Средний % ошибок] ${o.avg_error.toFixed(2)}%`),void 0!==o.qual&&(n+="[Квалификация] "+(0===o.qual?"Нет":"Да")),o.haul&&o.haul.total&&(n+=`[Общее время] ${this.formatTime(o.haul.total)}`),o.haul)){const e=[];o.haul.hour&&e.push(`${o.haul.hour}ч`),o.haul.min&&e.push(`${o.haul.min}м`),e.length&&(n+=`[Время в игре] ${e.join(" ")}`)}return n.trim()}async getGameStats(e){const t=e.closest("li").querySelector("a");if(!t)return"[Ошибка] Не удалось найти параметры игры";const a=this.getGameId(t);if(!a)return"[Ошибка] Не удалось получить ID игры";const r=this.getUserId();if(!r)return`[Game ID] ${a} [Ошибка] Не удалось получить ID пользователя`;const o=this.parseGameParams(t),n=this.buildApiUrl(r,o);try{const e=await this.fetchGameStats(n);return this.formatStats(e,a,o)}catch(e){return console.error("Error getting game stats:",e),`[Game ID] ${a} [Ошибка] Ошибка загрузки статистики`}}};async function Gt(e,t){const a="voc"===t.params.gametype&&t.params.vocId,r=t.params.gametype,o="https://klavogonki.ru";let n=[{text:`${b} День`,className:"popup-button",onClick:()=>{const e=a?`${o}/vocs/${t.params.vocId}/top/day/`:`${o}/top/day/${r}/`;window.open(e,"_blank")}},{text:`${f} Неделя`,className:"popup-button",onClick:()=>{const e=a?`${o}/vocs/${t.params.vocId}/top/week/`:`${o}/top/week/${r}/`;window.open(e,"_blank")}}];if(a){const e=t.params.vocId,a=`${o}/vocs/${e}`,r=It.getUserId(),s=`${o}/u/#/${r}/stats`;if(n.unshift({text:`${x} Общая`,className:"popup-button",onClick:()=>window.open(a+"/","_blank")}),n.push({text:`${w} История`,className:"popup-button",onClick:()=>window.open(a+"/history/","_blank")},{text:`${k} Комментарии`,className:"popup-button",onClick:()=>window.open(a+"/comments/","_blank")}),r){const a={gametype:t.params.gametype,voc:t.params.vocId||t.params.voc},o=It.buildApiUrl(r,a),i=await It.fetchGameStats(o);i&&i.ok&&i.info&&i.info.num_races>0&&n.push({text:`${C} Статистика`,className:"popup-button",onClick:()=>window.open(s+`/voc-${e}/`,"_blank")})}}return xe(n,e,"game-popup","Информация")}function Tt(e,t,a){const r=e.gamesManager.getPreviousGameId(),o=t.pin?"pin-game":"",n=t.params&&t.params.gametype?`pin-gametype-${t.params.gametype}`:"",s=a===r?"previous-game":"",i=!1===t.params?.vocIsPublic?"voc-private":"",l=!0===t.params?.vocIsRemoved?"voc-removed":"";let p="";a===r&&(p="game"===ae()?H.playing:H.paused);const c=re("li",{className:`latest-game ${o} ${n} ${s} ${i} ${l}`.trim(),id:`latest-game-${a}`});let d;const g=re("div",{className:"latest-game-buttons"});c.addEventListener("mouseenter",(()=>{d=setTimeout((()=>{g.style.visibility="visible"}),400)})),c.addEventListener("mouseleave",(()=>{clearTimeout(d),g.style.visibility="hidden"}));const u=re("div",{className:"latest-game-pin",innerHTML:t.pin?H.unpin:H.pin});F(u,t.pin?"[Клик] Открепить с подтверждением. [Shift + Клик] Открепить без подтверждения.":"[Клик] Закрепить с подтверждением. [Shift + Клик] Закрепить без подтверждения."),u.addEventListener("click",(r=>{(r.shiftKey||confirm(t.pin?"Открепить игру?":"Закрепить игру?"))&&e.gamesManager.pinGame(a)}));const m=re("div",{className:"latest-game-delete",innerHTML:H.delete});F(m,"[Клик] Удалить с подтверждением. [Shift + Клик] Удалить без подтверждения."),m.addEventListener("click",(t=>{(t.shiftKey||confirm("Удалить игру?"))&&e.gamesManager.deleteGame(a)}));const h=re("div",{className:"latest-game-info",innerHTML:H.info});F(h,"voc"===t.params.gametype&&t.params.vocId?"Показать информацию о словаре":"Показать информацию об игре"),h.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),Gt(e,t)})),g.append(h,u,m);const y=re("a",{href:e.gamesManager.generateGameLink(t),innerHTML:e.gamesManager.generateGameName(t,{stateIcon:p})});y.addEventListener("click",(a=>{e.wasDragging&&(a.preventDefault(),e.wasDragging=!1);const r=(()=>{try{const e=localStorage.getItem("latestGames_activePlaylist");return e?JSON.parse(e):null}catch{return null}})();r&&!r.paused&&Re({...r,paused:!0});try{const e=y.closest("li");if(e&&e.id&&e.id.startsWith("latest-game-")){const t=e.id.replace("latest-game-",""),a=JSON.parse(localStorage.getItem("latestGamesData"))||{};a.previousGameId=t,localStorage.setItem("latestGamesData",JSON.stringify(a))}}catch(e){}const o=String(t.params.vocId||"");if(o)try{e.gamesManager.registerPendingPlayed(o,t.params.vocName||null,t.params.vocType||null)}catch(e){}}));const v={vocabulary:new WeakMap,stats:new WeakMap};return y.addEventListener("mouseover",(async e=>{const a="voc"===t.params?.gametype&&t.params?.vocId;if(e.shiftKey&&a){e.preventDefault(),e.stopPropagation(),K();try{if(!v.vocabulary.has(y)){const e=await Se(t.params.vocId);v.vocabulary.set(y,e)}Ee(y,v.vocabulary.get(y))}catch(e){console.error("Error loading vocabulary:",e)}}else if(e.ctrlKey){Ie(),X(y,"[Loading] Загрузка статистики...","stats");try{if(!v.stats.has(y)){const e=await It.getGameStats(y);v.stats.set(y,e)}X(y,v.stats.get(y),"stats")}catch(e){console.error("Error loading game stats:",e),X(y,"[Ошибка] Не удалось загрузить статистику","stats")}}else X(y,"\n [Удерживание ЛКМ] Создать|Сохранить игру с альтернативными параметрами\n [ПКМ] Переместить игру в другую группу\n [Shift + Наведение] Показать содержимое словаря\n [Ctrl + Наведение] Показать статистику игры\n ","info")})),y.addEventListener("mouseleave",(()=>{Ge()})),c.appendChild(g),c.appendChild(y),t.pin&&e.enableDragging&&Et(e,c),c}const Nt="latestGamesSearchQuery";function $t(){try{localStorage.removeItem(Nt)}catch(e){console.warn("Failed to clear search query:",e)}}function Dt(e,t){const a=e.value;if(!a)return void(t.style.left="");const r=function(e,t){const a=document.createElement("canvas").getContext("2d");return a.font=t,a.measureText(e).width}(a,function(e){const t=window.getComputedStyle(e);return`${t.fontWeight} ${t.fontSize} ${t.fontFamily}`}(e)),o=r+20;t.style.left=`${o}px`;o+(t.offsetWidth||24)>e.offsetWidth-8&&t.classList.remove("visible")}function Pt(e){const t=re("div",{className:"latest-games-search-container "+(e.showSearchBox?"":"latest-games-hidden")}),a=re("input",{type:"search",id:"latest-games-search-input"}),r=re("div",{id:"latest-games-clear-button",className:"latest-games-clear-btn",innerHTML:H.delete});t.style.position="relative";const o=function(){try{return localStorage.getItem(Nt)||""}catch(e){return console.warn("Failed to load search query:",e),""}}();return o&&(a.value=o,requestAnimationFrame((()=>{At(r,o),Dt(a,r),Ht(e,o)}))),a.addEventListener("input",(t=>{const o=t.target.value.trim();Ht(e,o),At(r,o),Dt(a,r),function(e){try{e&&e.trim()?localStorage.setItem(Nt,e.trim()):localStorage.removeItem(Nt)}catch(e){console.warn("Failed to save search query:",e)}}(o)})),r.addEventListener("click",(()=>{a.value="",a.focus(),Ht(e,""),At(r,""),Dt(a,r),$t()})),a.addEventListener("keydown",(e=>{"Backspace"!==e.key&&"Delete"!==e.key||1!==a.value.length||a.value.trim()||$t()})),At(r,a.value),Dt(a,r),t.appendChild(a),t.appendChild(r),t}function At(e,t){e.classList.toggle("visible",!!t)}function Ht(e,t,a=!1){const r=document.getElementById("latest-games");if(!r)return;if(r.innerHTML="",!t)return void e.uiManager.populateGamesList(r);const o=[];if(e.groupsManager.groups.forEach((a=>{a.games.forEach((r=>{const n=function(e,t){const a=e.toLowerCase(),r=t.toLowerCase();if(!r)return 0;if(a===r)return-1e3;if(a.startsWith(r))return-500;if(a.includes(r))return-100;let o=0,n=0,s=0;for(;oe.score-t.score));const n=a?o.length:50,s=o.slice(0,n),i=o.length-n;if(s.forEach((({group:t,game:a})=>{const o=e.uiManager.createGameElement(a,a.id);o.classList.add("latest-games-search-result"),o.addEventListener("click",(()=>{e.groupsManager.currentGroupId=t.id,e.uiManager.refreshContainer(),setTimeout((()=>{const e=document.getElementById(`latest-game-${a.id}`);e&&e.scrollIntoView({behavior:"smooth",block:"center"})}),100)})),r.appendChild(o)})),i>0){const a=re("li",{className:"latest-games-search-more",textContent:`Ещё ${i} результатов скрыто`});F(a,"Нажмите для показа всех результатов"),a.addEventListener("click",(()=>{Ht(e,t,!0)})),r.appendChild(a)}}function qt(e){const t=document.querySelector(".latest-games-search-container");if(!t)return;const a=t.classList.toggle("latest-games-hidden");if(e.showSearchBox=!a,e.settingsManager&&"function"==typeof e.settingsManager.saveSettings&&e.settingsManager.saveSettings(),!a){const e=document.getElementById("latest-games-search-input");e&&(e.focus(),e.select())}}const _t={popup:null,isDragging:!1,offsetX:0,offsetY:0,hasUnsavedChanges:!1,currentListType:"bannedVocabularies",_intendedX:null,_intendedY:null,listConfigs:{bannedVocabularies:{title:"Заблокированные словари",adjective:"заблокированных",mainKey:"bannedVocabularies",backupKey:"bannedVocabularies*Backup"},playedVocabularies:{title:"Проигранные словари",adjective:"проигранных",mainKey:"playedVocabularies",backupKey:"playedVocabularies*Backup"}},getConfig(){return this.listConfigs[this.currentListType]},get(){try{const e=this.getConfig(),t=localStorage[e.backupKey]?e.backupKey:e.mainKey,a=JSON.parse(localStorage[t])||[];return this.hasUnsavedChanges=t===e.backupKey,a.map((e=>"string"==typeof e?{id:e,isNew:!1}:{...e,isNew:e.isNew||!1}))}catch{return[]}},save(e,t=!0){const a=this.getConfig();if(t)localStorage[a.backupKey]=JSON.stringify(e),this.hasUnsavedChanges=!0;else{const t=this.hasUnsavedChanges?a.backupKey:a.mainKey;localStorage[t]=JSON.stringify(e)}},commitSave(){const e=this.getConfig(),t=localStorage[e.backupKey];t&&(localStorage[e.mainKey]=t,delete localStorage[e.backupKey]),this.hasUnsavedChanges=!1},revertChanges(){const e=this.getConfig();delete localStorage[e.backupKey],this.hasUnsavedChanges=!1},add(e){const t=this.get();t.some((t=>t.id===e))||(t.push({id:e,isNew:!0}),this.save(t))},filterVocabs(e,t,a="all",r="all"){let o=e;if("new"===a?o=o.filter((e=>e.isNew)):"old"===a?o=o.filter((e=>!e.isNew)):"unavailable"===a&&(o=o.filter((e=>!e.name))),"all"!==r&&(o=o.filter((e=>e.vocType===r))),t?.trim()){const e=t.toLowerCase().trim();o=o.filter((t=>t.id.toLowerCase().includes(e)||t.name&&t.name.toLowerCase().includes(e)||t.author&&t.author.toLowerCase().includes(e)))}return o},async fetchAndCacheVocabData(e,t=!1){if(!t&&e.name&&e.author&&e.vocType&&void 0!==e.createdDate)return e;const a=await $e(e.id);return a?{...e,name:a.vocabularyName,author:a.vocabularyAuthor,vocType:a.vocabularyType,isPublic:a.vocabularyIsPublic,createdDate:a.createdDate,versionDate:a.versionDate}:{...e,name:null,author:null,vocType:null,isPublic:null,createdDate:null,versionDate:null}},remove(e){this.save(this.get().filter((t=>t.id!==e))),this.refresh()},toggleBtnText(e,t,a,r=1e3){const o=this.popup.querySelector(e),n=a();o.textContent=t,setTimeout((()=>o.textContent=n),r)},async copy(e=null,t=!1,a="all",r="all",o=!1){const n=e||this.get();let s;if(t){s=n.map(((e,t)=>`${t+1}. Автор: ${e.author||"Неизвестный автор"}, Словарь: ${e.name||"Название недоступно"} - ${`https://klavogonki.ru/vocs/${e.id}/`}`)).join("\n")}else s=n.map((e=>e.id)).join(",");try{await navigator.clipboard.writeText(s)}catch{}this.toggleBtnText(".copy-all-btn","Скопировано!",(()=>this.getButtonText("copy",a,r,n.length,o)))},removeAll(e="all",t="all",a=null){const r=this.get();let o;if(a){const e=new Set(a.map((e=>e.id)));o=r.filter((t=>!e.has(t.id)))}else o="all"===e&&"all"===t?[]:r.filter((a=>{let r=!0,o=!0;return"new"===e?r=!a.isNew:"old"===e?r=a.isNew:"unavailable"===e&&(r=!!a.name),"all"!==t&&(o=a.vocType!==t),r&&o}));const n=r.length-o.length;this.save(o),this.toggleBtnText(".remove-all-btn","Удалено!",(()=>this.getButtonText("remove",e,t,n,!!a))),this.refresh()},getButtonText(e,t,a,r,o=!1){const n={all:"все",new:"новые",old:"старые",unavailable:"недоступные"},s={words:"Слова",phrases:"Фразы",texts:"Тексты",url:"URL",books:"Книга",generator:"Генератор"},i={copy:"Копировать",remove:"Удалить"}[e]||"";if(o)return`${i} результат (${r})`;const l=[];"all"!==t&&l.push(n[t]),"all"!==a&&l.push(s[a]);return`${i} ${l.length>0?l.join(" "):n.all} (${r})`},sortAll(){let e=this.get().map((e=>({...e,isNew:!1})));if("playedVocabularies"===this.currentListType){e.forEach((e=>{e.playHistory&&Array.isArray(e.playHistory)&&(e.playHistory=e.playHistory.sort(((e,t)=>new Date(e.date)-new Date(t.date))))}));const t={};e.forEach((e=>{if(e.playHistory&&e.playHistory.length>0){const a=e.playHistory[0].date,r=new Date(a).toLocaleDateString("ru-RU",{day:"numeric",month:"long",year:"numeric"});t[r]||(t[r]=[]),t[r].push(e)}}));e=Object.keys(t).sort(((e,t)=>new Date(e)-new Date(t))).flatMap((e=>t[e].sort(((e,t)=>parseInt(e.id)-parseInt(t.id)))))}else e.sort(((e,t)=>parseInt(e.id)-parseInt(t.id)));this.save(e),this.toggleBtnText(".sort-all-btn","Отсортировано!",(()=>"Сортировать")),this.refresh()},async forceFetchAll(){const e=this.popup.querySelector(".force-fetch-btn");e.textContent="Обновление...",e.disabled=!0;const t=this.get(),a=await Promise.all(t.map((e=>this.fetchAndCacheVocabData(e,!0)))),r=a.filter((e=>e.name)).length,o=a.filter((e=>!e.name)).length;this.save(a,!1),e.disabled=!1,this.toggleBtnText(".force-fetch-btn","Обновлено!",(()=>"Обновить все")),await this.refresh(),alert(`Обновление завершено!\n\nВсего словарей: ${a.length}\nДоступно: ${r}\nНедоступно: ${o}`)},async handleSave(){this.commitSave(),this.toggleBtnText(".save-btn","Сохранено!",(()=>"Сохранить")),await this.refresh()},async handleRevert(){this.revertChanges(),this.toggleBtnText(".revert-btn","Отменено!",(()=>"Отменить")),await this.refresh()},scrollToBottom(){if(this.popup){const e=this.popup.querySelector(".vocab-list");e&&(e.scrollTop=e.scrollHeight)}},scheduleScrollToBottom(){requestAnimationFrame((()=>this.scrollToBottom()))},createSearchAndFilterSection(){const e=document.createElement("div");e.className="popup-search-filters";const t=Object.assign(document.createElement("input"),{type:"text",placeholder:"Поиск по ID, названию или автору...",className:"search-input"}),a=document.createElement("div");a.className="filter-buttons";const r=Object.assign(document.createElement("button"),{className:"filter-btn active",textContent:"Все"});r.setAttribute("data-filter","all"),F(r,"Показать все словари");const o=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Новые"});o.setAttribute("data-filter","new"),F(o,"Показать только новые словари");const n=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Старые"});n.setAttribute("data-filter","old"),F(n,"Показать только старые словари");const s=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Недоступные"});s.setAttribute("data-filter","unavailable"),F(s,"Показать только недоступные словари"),a.append(r,o,n,s);const i=document.createElement("div");i.className="filter-buttons type-filter-buttons";const l=Object.assign(document.createElement("button"),{className:"filter-btn active",textContent:"Все типы"});l.setAttribute("data-type-filter","all"),F(l,"Показать все типы словарей");const p=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Слова"});p.setAttribute("data-type-filter","words"),F(p,'Показать только словари типа "Слова"');const c=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Фразы"});c.setAttribute("data-type-filter","phrases"),F(c,'Показать только словари типа "Фразы"');const d=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Тексты"});d.setAttribute("data-type-filter","texts"),F(d,'Показать только словари типа "Тексты"');const g=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"URL"});g.setAttribute("data-type-filter","url"),F(g,'Показать только словари типа "URL"');const u=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Книга"});u.setAttribute("data-type-filter","books"),F(u,'Показать только словари типа "Книга"');const m=Object.assign(document.createElement("button"),{className:"filter-btn",textContent:"Генератор"});return m.setAttribute("data-type-filter","generator"),F(m,'Показать только словари типа "Генератор"'),i.append(l,p,c,d,g,u,m),e.append(t,a,i),{searchSection:e,searchInput:t,statusFilterContainer:a,typeFilterContainer:i}},createVocabItem(e,t=0){const a=document.createElement("div");a.className="vocab-item",e.isNew&&a.classList.add("vocab-item-new"),a.dataset.id=e.id,a.style.cursor="pointer";const r=document.createElement("div");r.className="vocab-left";const o=Object.assign(document.createElement("button"),{className:"vocab-play-btn control-button",innerHTML:H.start});o.addEventListener("click",(t=>{t.stopPropagation();const a=new URLSearchParams({gametype:"voc",type:"normal",timeout:"10",level_from:"1",level_to:"9",submit:"1",voc:String(e.id)});window.location.href=`${location.protocol}//klavogonki.ru/create/?${a.toString()}`}));const n=Object.assign(document.createElement("button"),{className:"vocab-info-btn control-button",innerHTML:H.info});n.addEventListener("click",(t=>{t.stopPropagation();Gt(t,{params:{gametype:"voc",vocId:e.id}})}));const s=Object.assign(document.createElement("span"),{className:"vocab-id",textContent:e.id});if(e.createdDate||null!=e.isPublic){const t=[];if(null!=e.isPublic&&t.push(`[Публичный]${e.isPublic}`),e.createdDate){let a=`[Создан]${e.createdDate}`;e.versionDate&&(a+=` ${e.versionDate}`),t.push(a)}F(s,t.join(""))}if(r.appendChild(o),r.appendChild(n),r.appendChild(s),t>1){const e=Object.assign(document.createElement("span"),{className:"vocab-play-count-badge",textContent:t.toString()});r.appendChild(e)}const i=document.createElement("div");if(i.className="vocab-right",e.name){const t=Object.assign(document.createElement("div"),{className:"vocab-name",textContent:e.name});if(i.appendChild(t),e.author){const t=Object.assign(document.createElement("div"),{className:"vocab-author",textContent:`Автор: ${e.author}`});i.appendChild(t)}if(e.vocType){const t=Object.keys(L).find((t=>L[t]===e.vocType))||e.vocType,a=Object.assign(document.createElement("div"),{className:"vocab-type",textContent:`Тип словаря: ${t}`});i.appendChild(a)}}else{const e=Object.assign(document.createElement("div"),{className:"vocab-loading",textContent:"Не удалось загрузить"});i.appendChild(e)}const l=Object.assign(document.createElement("button"),{className:"remove-btn",textContent:"Удалить"});return a.append(r,i,l),a},async createElements(){const e=this.get(),t=document.createElement("div");t.className="vocabularies-manager-popup";const a=document.createElement("div");a.className="popup-header";const r=this.getConfig(),o=document.createElement("span");o.className="popup-header-title",o.textContent=this.hasUnsavedChanges?`${r.title} *`:r.title,a.appendChild(o),a.style.cursor="move",a.addEventListener("mousedown",(e=>this.startDrag(e))),t.appendChild(a);const n=document.createElement("div");n.className="popup-actions";const s=Object.assign(document.createElement("button"),{className:"copy-all-btn",textContent:this.getButtonText("copy","all","all",e.length,!1),disabled:!e.length});F(s,"[Клик] Копировать в соответствии с текущим фильтром или результатами поиска\n [Shift + Клик] Копировать в расширенном формате с авторами, названиями и ссылками");const i=Object.assign(document.createElement("button"),{className:"remove-all-btn",textContent:this.getButtonText("remove","all","all",e.length,!1),disabled:!e.length});F(i,"Удалить в соответствии с текущим фильтром или результатами поиска");const l=Object.assign(document.createElement("button"),{className:"sort-all-btn",textContent:"Сортировать",disabled:!e.length,onclick:()=>this.sortAll()});F(l,"Отсортировать все словари по ID и снять статус новых");const p=Object.assign(document.createElement("button"),{className:"force-fetch-btn",textContent:"Обновить",disabled:!e.length,onclick:()=>this.forceFetchAll()});if(F(p,"Принудительно обновить информацию о всех словарях"),n.append(s,i,l,p),this.hasUnsavedChanges){const e=Object.assign(document.createElement("button"),{className:"save-btn",textContent:"Сохранить",onclick:()=>this.handleSave()});F(e,"[Ctrl + S] Сохранить изменения");const t=Object.assign(document.createElement("button"),{className:"revert-btn",textContent:"Отменить",onclick:()=>this.handleRevert()});F(t,"[Ctrl + Z] Отменить все изменения"),n.append(e,t)}t.appendChild(n);const{searchSection:c,searchInput:d,statusFilterContainer:g,typeFilterContainer:u}=this.createSearchAndFilterSection();t.appendChild(c);const m=document.createElement("div");if(m.className="vocab-list",e.length){const t=await Promise.all(e.map((e=>this.fetchAndCacheVocabData(e))));this.save(t,!1);let a=t,r="all",o="all";const n=(e,a,r,o)=>{const n=o?.trim().length>0;if(s.textContent=this.getButtonText("copy",e,a,r.length,n),s.disabled=0===r.length,n)i.textContent=this.getButtonText("remove",e,a,r.length,!0),i.disabled=0===r.length;else{const r=this.filterVocabs(t,"",e,a);i.textContent=this.getButtonText("remove",e,a,r.length,!1),i.disabled=0===r.length}},l=()=>{const e=g.querySelector('[data-filter="all"]'),a=g.querySelector('[data-filter="new"]'),r=g.querySelector('[data-filter="old"]'),o=g.querySelector('[data-filter="unavailable"]'),n=t.filter((e=>e.isNew)).length,s=t.filter((e=>!e.isNew)).length,i=t.filter((e=>!e.name)).length;e.textContent=`Все (${t.length})`,a.textContent=`Новые (${n})`,r.textContent=`Старые (${s})`,o.textContent=`Недоступные (${i})`;const l=u.querySelector('[data-type-filter="all"]'),p=t.filter((e=>"words"===e.vocType)).length,c=t.filter((e=>"phrases"===e.vocType)).length,d=t.filter((e=>"texts"===e.vocType)).length,m=t.filter((e=>"url"===e.vocType)).length,h=t.filter((e=>"books"===e.vocType)).length,y=t.filter((e=>"generator"===e.vocType)).length;l.textContent=`Все типы (${t.length})`,u.querySelector('[data-type-filter="words"]').textContent=`Слова (${p})`,u.querySelector('[data-type-filter="phrases"]').textContent=`Фразы (${c})`,u.querySelector('[data-type-filter="texts"]').textContent=`Тексты (${d})`,u.querySelector('[data-type-filter="url"]').textContent=`URL (${m})`,u.querySelector('[data-type-filter="books"]').textContent=`Книга (${h})`,u.querySelector('[data-type-filter="generator"]').textContent=`Генератор (${y})`},p=e=>{if(m.innerHTML="",a=e,0===e.length){const e=document.createElement("div");return e.className="empty-state",e.textContent="Ничего не найдено",void m.appendChild(e)}if("playedVocabularies"===this.currentListType){const t=new Map;e.forEach((e=>{e.playHistory&&Array.isArray(e.playHistory)&&e.playHistory.forEach((a=>{const r=new Date(a.date).toLocaleDateString("ru-RU",{day:"numeric",month:"long",year:"numeric"});t.has(r)||t.set(r,{items:[],sortDate:new Date(a.date)}),t.get(r).items.push({vocab:e,count:a.count,date:a.date})}))}));Array.from(t.entries()).sort(((e,t)=>e[1].sortDate-t[1].sortDate)).map((([e])=>e)).forEach((e=>{const a=t.get(e).items,r=a.length,o=a.reduce(((e,{count:t})=>e+t),0),n=document.createElement("div");n.className="vocab-labels-container";const s=document.createElement("div");s.className="vocab-date",s.textContent=`${e}`;const i=document.createElement("div");i.className="vocab-count",i.textContent=o>r?`Словарей: ${r} | Заездов: ${o}`:`Словарей: ${r}`,n.appendChild(s),n.appendChild(i),m.appendChild(n),a.forEach((({vocab:e,count:t})=>{m.appendChild(this.createVocabItem(e,t))}))}))}else e.forEach((e=>m.appendChild(this.createVocabItem(e,0))));this.scheduleScrollToBottom()},c=()=>{const e=d.value,a=this.filterVocabs(t,e,r,o);p(a),n(r,o,a,e)};l(),p(t),n(r,o,a,""),s.addEventListener("click",(e=>{const t=e.shiftKey,n=d.value.trim().length>0;this.copy(a,t,r,o,n)})),i.addEventListener("click",(()=>{const e=d.value.trim().length>0;this.removeAll(r,o,e?a:null)})),d.addEventListener("input",c),g.addEventListener("click",(e=>{e.target.classList.contains("filter-btn")&&(g.querySelectorAll(".filter-btn").forEach((e=>e.classList.remove("active"))),e.target.classList.add("active"),r=e.target.dataset.filter,c())})),u.addEventListener("click",(e=>{e.target.classList.contains("filter-btn")&&(u.querySelectorAll(".filter-btn").forEach((e=>e.classList.remove("active"))),e.target.classList.add("active"),o=e.target.dataset.typeFilter,c())})),m.addEventListener("click",(e=>{const t=e.target.closest(".vocab-item");if(!t)return;const a=t.dataset.id;e.target.classList.contains("remove-btn")?this.remove(a):window.open(`https://klavogonki.ru/vocs/${a}/`,"_blank")})),m.addEventListener("mouseover",(e=>{if(!e.shiftKey)return;const t=e.target.closest(".vocab-item");if(!t)return;const a=t.dataset.id||t.querySelector(".vocab-id")?.textContent;a&&Se(a).then((e=>Ee(t,e))).catch((()=>{}))}),{capture:!0}),m.addEventListener("mouseout",(e=>{e.target.closest(".vocab-item")&&Ge()}),{capture:!0})}else{const e=document.createElement("div");e.className="empty-state",e.textContent=`Нет ${this.getConfig().adjective} словарей`,m.appendChild(e)}return t.appendChild(m),t},async refresh(){if(this.popup){const e=await this.createElements(),t=this.popup.parentNode,a=null!==this._intendedX?this._intendedX:this.popup.getBoundingClientRect().left,r=null!==this._intendedY?this._intendedY:this.popup.getBoundingClientRect().top;t.replaceChild(e,this.popup),this.popup=e,this.popup.style.left=a+"px",this.popup.style.top=r+"px",this.constrainToScreen(),this.scheduleScrollToBottom()}},async show(e=100,t=100,a=20,r=20){this.hide(),this.popup=await this.createElements(),document.body.appendChild(this.popup),this._intendedX=e+a,this._intendedY=t+r,this.popup.style.left=this._intendedX+"px",this.popup.style.top=this._intendedY+"px",this.constrainToScreen(),this.scheduleScrollToBottom(),setTimeout((()=>{document.addEventListener("click",this.outside),document.addEventListener("keydown",this.keydown)}),100),window.addEventListener("resize",this._onResize)},hide(){this.popup&&(document.body.removeChild(this.popup),this.popup=null,this.isDragging=!1,document.removeEventListener("click",this.outside),document.removeEventListener("keydown",this.keydown),document.removeEventListener("mousemove",this.drag),document.removeEventListener("mouseup",this.stopDrag),window.removeEventListener("resize",this._onResize))},toggle(e,t,a="bannedVocabularies"){this.popup?this.currentListType===a?this.hide():(this.currentListType=a,this.refresh().catch((()=>{}))):(this.currentListType=a,this.show(e,t))},outside:e=>{_t.popup?.contains(e.target)||"BUTTON"===e.target.tagName||_t.hide()},keydown:e=>{"Escape"===e.key?_t.hide():(e.ctrlKey||e.metaKey)&&"s"===e.key?(e.preventDefault(),_t.hasUnsavedChanges&&_t.handleSave()):(e.ctrlKey||e.metaKey)&&"z"===e.key&&(e.preventDefault(),_t.hasUnsavedChanges&&_t.handleRevert())},startDrag(e){this.isDragging=!0;const t=this.popup.getBoundingClientRect();this.offsetX=e.clientX-t.left,this.offsetY=e.clientY-t.top,document.addEventListener("mousemove",this.drag),document.addEventListener("mouseup",this.stopDrag)},drag:e=>{if(!_t.isDragging||!_t.popup)return;const t=e.clientX-_t.offsetX,a=e.clientY-_t.offsetY;_t._intendedX=t,_t._intendedY=a,_t.popup.style.left=t+"px",_t.popup.style.top=a+"px",_t.constrainToScreen()},stopDrag:()=>{_t.isDragging=!1,document.removeEventListener("mousemove",_t.drag),document.removeEventListener("mouseup",_t.stopDrag)},constrainToScreen(){if(!this.popup)return;const e=this.popup.getBoundingClientRect(),t=window.innerWidth-e.width,a=window.innerHeight-e.height;e.left<0&&(this.popup.style.left="0px"),e.top<0&&(this.popup.style.top="0px"),e.left>t&&(this.popup.style.left=t+"px"),e.top>a&&(this.popup.style.top=a+"px")},_onResize:()=>{_t.popup&&(null!==_t._intendedX&&(_t.popup.style.left=_t._intendedX+"px"),null!==_t._intendedY&&(_t.popup.style.top=_t._intendedY+"px"),_t.constrainToScreen())}},Bt=Object.entries(L).map((([e,t])=>({label:e,key:t}))),Vt=e=>{const t=e?JSON.parse(e):[];return Array.isArray(t)?t.map((e=>String("object"==typeof e&&e?.id?e.id:e))):[]};function Rt(e,t){try{const a=(e.validVocabularies?.[t]||[]).length,r=new Set(Vt(localStorage.getItem("playedVocabularies"))),o=new Set(Vt(localStorage.getItem("bannedVocabularies"))),n=(JSON.parse(localStorage.getItem("validVocabularies")||"{}")[t]||[]).filter((e=>r.has(String(e))&&!o.has(String(e)))).length;return{total:n+a,played:n,remained:a}}catch(e){return console.warn("Error calculating vocabulary counts:",e),{total:0,played:0,remained:0}}}function jt(e,t,a){return a&&0!==t?0===e?" danger":e<=10?" warning":"":""}function Ot(e,t){const a=Bt.map((({label:e,key:a})=>{const r=Rt(t,a),o=t.randomVocabulariesType[a];return{text:e,className:`group-tab${o?" active":""}${jt(r.remained,r.total,o)}`,onClick:e=>function(e,t,a){if(!(e instanceof HTMLElement))return;const r=!a.randomVocabulariesType[t];if(a.randomVocabulariesType[t]=r,e.classList.remove("active","warning","danger"),r){e.classList.add("active");const r=Rt(a,t),o=jt(r.remained,r.total,!0).trim();o&&e.classList.add(o)}a.settingsManager.saveSettings()}(e,a,t),counts:r}})),r=xe(a,e,"vocabulary-types-popup","Тип",!0);return r.querySelectorAll(".group-tab").forEach(((e,t)=>{const{total:r,played:o,remained:n}=a[t].counts;F(e,`[Всего:]${r} [Проиграно:]${o} [Осталось:]${n}`,"stats")})),r}function zt(e,t,a){const r=document.createElement(e);return t&&(r.className=t),void 0!==a&&(r.textContent=a),r}function Yt(e){return new Promise((t=>setTimeout(t,e)))}async function Wt(e,t,a,r){return Promise.all(e.map((async e=>{if(t.isCancelled())return{...e,data:null};const{group:o,game:n,vocId:s}=e,i=await $e(s).catch((()=>null));return a.value++,t.update(a.value,r,o.title,s,i?.vocabularyName||n.params?.vocName||null),{group:o,game:n,vocId:s,data:i}})))}async function Kt(e){const t=await(a=e.groupsManager.groups,new Promise((e=>{const t=a.filter((e=>e.games.some((e=>"voc"===e.params?.gametype&&e.params?.vocId))));if(!t.length)return void e([]);if(1===t.length)return void e(t);const r=zt("div","rg-scanner-overlay"),o=zt("div","rg-scanner-card");o.appendChild(zt("div","rg-scanner-title","📂 Выбор групп для сканирования"));const n=zt("div","rg-scanner-group-list"),s=new Set;let i=null;n.addEventListener("mousedown",(e=>{const t=e.target.closest("input[type=checkbox]")||e.target.closest("label")?.querySelector("input[type=checkbox]");t&&(i=!t.checked)})),n.addEventListener("mouseover",(e=>{if(null===i||1!==e.buttons)return void(i=null);const t=e.target.closest("input[type=checkbox]")||e.target.closest("label")?.querySelector("input[type=checkbox]");t&&t.checked!==i&&(t.checked=i,i?s.add(t.dataset.groupId):s.delete(t.dataset.groupId),g.disabled=0===s.size)})),document.addEventListener("mouseup",(()=>{i=null}),{capture:!0}),t.forEach((e=>{const t=e.games.filter((e=>"voc"===e.params?.gametype&&e.params?.vocId)).length,a=zt("label","rg-scanner-group-label"),r=document.createElement("input");r.type="checkbox",r.checked=!1,r.dataset.groupId=e.id,r.addEventListener("change",(()=>{r.checked?s.add(e.id):s.delete(e.id),g.disabled=0===s.size})),a.append(r,zt("span",null,e.title),zt("span","rg-scanner-group-label-count",`(${t} словарей)`)),n.appendChild(a)})),o.appendChild(n);const l=zt("div","rg-scanner-btn-row"),p=zt("button","rg-scanner-btn rg-scanner-btn--select","Выбрать все"),c=zt("button","rg-scanner-btn rg-scanner-btn--deselect","Снять все"),d=zt("button","rg-scanner-btn rg-scanner-btn--cancel","Отмена"),g=zt("button","rg-scanner-btn rg-scanner-btn--scan","Сканировать");g.disabled=!0,p.addEventListener("click",(()=>{n.querySelectorAll("input[type=checkbox]").forEach((e=>{e.checked=!0,s.add(e.dataset.groupId)})),g.disabled=!1})),c.addEventListener("click",(()=>{n.querySelectorAll("input[type=checkbox]").forEach((e=>{e.checked=!1,s.delete(e.dataset.groupId)})),g.disabled=!0})),d.addEventListener("click",(()=>{r.remove(),e(null)})),g.addEventListener("click",(()=>{r.remove(),e(t.filter((e=>s.has(e.id))))})),l.append(p,c,d,g),o.appendChild(l),r.appendChild(o),document.body.appendChild(r)})));var a;if(!t||0===t.length)return;const r=[];for(const e of t)for(const t of e.games){const a=String(t.params?.vocId||"");"voc"===t.params?.gametype&&a&&r.push({group:e,game:t,vocId:a})}if(0===r.length)return void alert("В выбранных группах нет игр с словарями.");const o=function(e){const t=zt("div","rg-scanner-overlay"),a=zt("div","rg-scanner-card rg-scanner-progress-card");a.appendChild(zt("div","rg-scanner-title","🔍 Сканирование словарей"));const r=zt("div","rg-scanner-progress-meta"),o=zt("span","rg-scanner-progress-group","—"),n=zt("span","rg-scanner-progress-fraction",`0 / ${e}`);r.append(o,n);const s=zt("div","rg-scanner-progress-voc"),i=zt("span","rg-scanner-progress-voc-id","#—"),l=zt("span","rg-scanner-progress-voc-name","Ожидание…");s.append(i,l);const p=zt("div","rg-scanner-bar-row"),c=zt("div","rg-scanner-bar-wrap"),d=zt("div","rg-scanner-bar-fill");d.style.width="0%",c.appendChild(d);const g=zt("span","rg-scanner-progress-percent","0%");p.append(c,g);const u=zt("button","rg-scanner-btn rg-scanner-btn--cancel","Отменить"),m=zt("div","rg-scanner-btn-row");m.appendChild(u),a.append(r,s,p,m),t.appendChild(a),document.body.appendChild(t);let h=!1;return u.addEventListener("click",(()=>{h=!0,u.disabled=!0,u.textContent="Отмена…"})),{isCancelled:()=>h,update(e,t,a,r,s){const p=t>0?Math.round(e/t*100):0;o.textContent=a||"—",n.textContent=`${e} / ${t}`,i.textContent=r?`#${r}`:"#—",l.textContent=s||"…",d.style.width=`${p}%`,g.textContent=`${p}%`},remove(){t.remove()}}}(r.length),n={value:0},s=[];for(let e=0;ee+t.items.length),0),i=t.reduce(((e,t)=>e+t.items.length),0),l=zt("div","rg-scanner-title");l.append(document.createTextNode(r?"⚠️ Сканирование прервано ":"✅ Сканирование завершено "),zt("span","rg-scanner-results-badge",`${s} непубличных`),...i>0?[document.createTextNode(" "),zt("span","rg-scanner-results-badge rg-scanner-results-badge--removed",`${i} удалённых`)]:[]),n.appendChild(l);const p=zt("div","rg-scanner-results-subtitle"),c=[`Проверено ${a} словарей.`];s>0&&c.push(`Непубличных: ${s}.`),i>0&&c.push(`Удалённых: ${i}.`),p.innerHTML=c.join(" "),n.appendChild(p);const d=zt("div","rg-scanner-results-tree");if(0===s&&0===i)d.appendChild(zt("div","rg-scanner-results-empty","Все словари публичные 🎉"));else{const a=({groupTitle:e,items:t},a)=>{if(0===t.length)return;const r=zt("div","rg-scanner-tree-group"),o=zt("div","rg-scanner-tree-group-header");o.append(zt("span","rg-scanner-tree-group-icon","📁"),zt("span","rg-scanner-tree-group-title",e),zt("span","rg-scanner-tree-group-count",String(t.length))),r.appendChild(o);const n=zt("ul","rg-scanner-tree-items");t.forEach((({vocId:e,vocName:t})=>{const r=zt("li","rg-scanner-tree-item"),o=document.createElement("a");o.className="rg-scanner-tree-item-link",o.textContent=`#${e}`,o.href=`https://klavogonki.ru/vocs/${e}/`,o.target="_blank",r.append(zt("span","rg-scanner-tree-item-icon",a),o,zt("span","rg-scanner-tree-item-name",t||"—")),n.appendChild(r)})),r.appendChild(n),d.appendChild(r)};s>0&&(d.appendChild(zt("div","rg-scanner-results-section-title","🔒 Непубличные словари")),e.forEach((e=>a(e,"🔒")))),i>0&&(d.appendChild(zt("div","rg-scanner-results-section-title","🗑️ Удалённые словари")),t.forEach((e=>a(e,"🗑️"))))}n.appendChild(d);const g=zt("div","rg-scanner-btn-row"),u=zt("button","rg-scanner-btn rg-scanner-btn--close","Закрыть");u.addEventListener("click",(()=>o.remove())),g.appendChild(u),n.appendChild(g),o.appendChild(n),document.body.appendChild(o)}([...p.values()],[...c.values()],l,i)}function Ft(e){const t=re("div",{className:"latest-games-controls"}),a=re("div",{className:"controls-limiter"}),r=re("div",{className:"controls-buttons"}),o=re("div",{className:"controls-visible"}),n=re("div",{className:"controls-more"});r.append(o,n),n.appendChild(a),t.append(r);const s=re("span",{id:"latest-games-options"});a.appendChild(s);const i=re("span",{id:"latest-games-count-dec",className:"control-button",innerHTML:H.chevronLeft});F(i,"Уменьшить количество сохраняемых игр");const l=re("span",{id:"latest-games-count",className:!1===e.shouldAutoSave?"latest-games-disabled":"",textContent:e.maxGameCount.toString()});F(l,e.shouldAutoSave?"Автосохранение: Включено":"Автосохранение: Отключено"),l.addEventListener("click",(()=>{e.shouldAutoSave=!e.shouldAutoSave,e.uiManager.updateGameCountDisplay(),e.settingsManager.saveSettings(),e.uiManager.refreshContainer()}));const p=re("span",{id:"latest-games-count-inc",className:"control-button",innerHTML:H.chevronRight});F(p,"Увеличить количество сохраняемых игр"),i.addEventListener("click",(()=>e.gamesManager.changeGameCount(-1))),p.addEventListener("click",(()=>e.gamesManager.changeGameCount(1))),s.append(i,l,p);const c=(e,t,a,r)=>{const o="function"==typeof a.click?a.click(t):a.click,n=a.shift?"function"==typeof a.shift?a.shift(t):a.shift:"",s=a.ctrl?"function"==typeof a.ctrl?a.ctrl(t):a.ctrl:"",i=a.alt?"function"==typeof a.alt?a.alt(t):a.alt:"",l=a.shiftAlt?"function"==typeof a.shiftAlt?a.shiftAlt(t):a.shiftAlt:"",p=a.ctrlShift?"function"==typeof a.ctrlShift?a.ctrlShift(t):a.ctrlShift:"";F(e,`\n [Клик] ${o}\n ${n?`[Shift + Клик] ${n}${r?` (${r} мс)`:""}`:""}\n ${s?`[Ctrl + Клик] ${s}`:""}\n ${i?`[Alt + Клик] ${i}`:""}\n ${l?`[Shift + Alt + Клик] ${l}`:""}\n ${p?`[Ctrl + Shift + Клик] ${p}`:""}\n `)},d=(t,a,r,o,n)=>{const s=a[r];t.classList.toggle("latest-games-disabled",!s),c(t,s,n,a[o]),t.onclick=s=>{if(s.ctrlKey&&t===y)return e.replayNextGame=!e.replayNextGame,e.settingsManager.saveSettings(),t.classList.toggle("replay-next-game",e.replayNextGame),t.innerHTML=h(),void c(t,a[r],n,a[o]);if(s.altKey&&t===y)return e.replayWithoutWaiting=!e.replayWithoutWaiting,e.settingsManager.saveSettings(),t.classList.toggle("replay-without-waiting",e.replayWithoutWaiting),t.innerHTML=h(),void c(t,a[r],n,a[o]);const i="function"==typeof n.shift?n.shift(a[r]):n.shift;if(s.shiftKey){const s=prompt(i,"");if(null!==s){const i=parseInt(s,10);!isNaN(i)&&i>=0?(a[o]=i,e.settingsManager.saveSettings(),c(t,a[r],n,i)):alert(n.delayErrorText)}}else a[r]=!a[r],e.settingsManager.saveSettings(),t.classList.toggle("latest-games-disabled",!a[r]),c(t,a[r],n,a[o])}},g=re("span",{className:"latest-games-refresh control-button",innerHTML:H.refresh});F(g,"\n [Клик] Сгенерировать новые уникальные ID для всех групп и игр\n [Shift + Клик] Получить актуальные данные для всех словарей (название, тип, публичность)\n "),g.addEventListener("click",(async t=>{if(t.shiftKey)await Kt(e);else{if(!confirm("Вы уверены, что хотите сгенерировать новые уникальные ID для всех групп и игр? Это действие нельзя отменить."))return;const t=e.groupsManager.currentGroupId,a=e.gamesManager.latestGamesData?.previousGameId;if(e.groupsManager.groups.forEach((e=>{e._oldId=e.id,e.games.forEach((e=>{e._oldId=e.id}))})),e.groupsManager.groups.forEach((t=>{t.id=ee(e.groupsManager.groups),t.games.forEach((t=>{t.id=ee(e.groupsManager.groups)}))})),t){const a=e.groupsManager.groups.find((e=>e._oldId===t));a&&(e.groupsManager.currentGroupId=a.id)}if(a)for(const t of e.groupsManager.groups){const r=t.games.find((e=>e._oldId===a));if(r){e.gamesManager.latestGamesData.previousGameId=r.id;break}}e.groupsManager.groups.forEach((e=>{delete e._oldId,e.games.forEach((e=>delete e._oldId))})),e.gamesManager.saveGameData(),e.uiManager.refreshContainer(),alert("✔️ Все ID для групп и игр были обновлены!")}}));const u=re("span",{className:"latest-games-reset-panels control-button",innerHTML:H.reset});F(u,"Сбросить настройки панели на значения по умолчанию"),u.addEventListener("click",(()=>{confirm("Вы уверены, что хотите сбросить настройки панели на значения по умолчанию? Это действие нельзя отменить.")&&function(e){e.panelWidths={...P.panelWidths},e.panelHeights={...P.panelHeights},e.panelYPosition={...P.panelYPosition},e.alwaysVisiblePanel={...P.alwaysVisiblePanel},e.settingsManager.saveSettings(),e.uiManager&&e.uiManager.refreshContainer&&e.uiManager.refreshContainer()}(e)}));const m=re("span",{className:"latest-games-play control-button",innerHTML:H.play});d(m,e,"shouldStart","startDelay",{click:e=>"Автозапуск игры: "+(e?"Включено":"Отключено"),shift:()=>"Изменить задержку автозапуска",delayErrorText:"Пожалуйста, введите корректное значение задержки автозапуска."});const h=()=>e.replayWithoutWaiting?H.replayImmediately:H.replay,y=re("span",{className:"latest-games-replay control-button"+(e.replayNextGame?" replay-next-game":"")+(e.replayWithoutWaiting?" replay-without-waiting":""),innerHTML:h()});d(y,e,"shouldReplay","replayDelay",{click:e=>"Автосоздание игры: "+(e?"Включено":"Отключено"),shift:()=>"Изменить задержку автосоздания",ctrl:()=>"Режим автосоздания: "+(e.replayNextGame?"Следующая️":"Текущая"),alt:()=>"Ожидание игроков: "+(e.replayWithoutWaiting?"Отключено":"Включено"),delayErrorText:"Пожалуйста, введите корректное значение задержки автосоздания."});const v=re("span",{className:"latest-games-replay-more control-button"+(!1===e.shouldReplayMore?" latest-games-disabled":""),innerHTML:H.replayMore}),b=()=>{F(v,`\n [Клик] Многократный повтор игры: ${e.shouldReplayMore?"Включено":"Отключено"}\n [Shift + Клик] Изменить количество повторов (${e.replayNextGameCount})\n `)};b(),v.onclick=t=>{if(t.shiftKey){let t;for(;;){if(t=prompt("Введите количество повторов игры:",e.replayNextGameCount.toString()),null===t)return;const a=parseInt(t,10);if(!isNaN(a)&&a>=1)return e.replayNextGameCount=a,e.settingsManager.saveSettings(),void b();alert("⚠️ Пожалуйста, введите корректное число (больше или равно 1).")}}else e.shouldReplayMore=!e.shouldReplayMore,e.settingsManager.saveSettings(),v.classList.toggle("latest-games-disabled",!e.shouldReplayMore),b()};const f=re("span",{className:"latest-games-pinall control-button",innerHTML:H.pin});F(f,"\n [Клик] Закрепить все игры в текущей группе\n [Shift + Клик] Закрепить все игры во всех группах\n "),f.onclick=t=>{if(t.shiftKey)e.groupsManager.groups.forEach((e=>e.games.forEach((e=>e.pin=1))));else{const t=e.groupsManager.getCurrentGroup(e.groupsManager.groups,e.groupsManager.currentGroupId);t&&t.games.forEach((e=>e.pin=1))}e.gamesManager.saveGameData(),e.uiManager.refreshContainer()};const x=re("span",{className:"latest-games-unpinall control-button",innerHTML:H.unpin});F(x,"\n [Клик] Открепить все игры в текущей группе\n [Shift + Клик] Открепить все игры во всех группах\n "),x.onclick=t=>{if(t.shiftKey)e.groupsManager.groups.forEach((e=>e.games.forEach((e=>e.pin=0))));else{const t=e.groupsManager.getCurrentGroup(e.groupsManager.groups,e.groupsManager.currentGroupId);t&&t.games.forEach((e=>e.pin=0))}e.gamesManager.saveGameData(),e.uiManager.refreshContainer()};const w=re("span",{className:"latest-games-sort control-button",innerHTML:H.sort});F(w,"Сортировать игры в текущей группе по алфавиту"),w.addEventListener("click",(()=>e.groupsManager.sortActiveGroupGames()));const k=re("span",{className:"latest-games-import control-button",innerHTML:H.import});F(k,"Импортировать настройки из JSON файла"),k.onclick=()=>e.settingsManager.importSettings(e);const C=re("span",{className:"latest-games-export control-button",innerHTML:H.export});F(C,"Экспортировать все настройки в JSON файл"),C.onclick=()=>e.settingsManager.exportSettings(e);const M=re("span",{className:"latest-games-removeall control-button",innerHTML:H.trashNothing});F(M,"Удалить все настройки"),M.onclick=()=>e.settingsManager.removeAllSettings(e);const S=re("span",{className:"latest-games-remove-unpinned control-button",innerHTML:H.broom});F(S,"\n [Клик] Удалить все незакреплённые игры в текущей группе\n [Shift + Клик] Удалить все незакреплённые игры во всех группах\n "),S.onclick=t=>{if(t.shiftKey)e.groupsManager.groups.forEach((e=>{e.games=e.games.filter((e=>e.pin))}));else{const t=e.groupsManager.getCurrentGroup(e.groupsManager.groups,e.groupsManager.currentGroupId);t&&(t.games=t.games.filter((e=>e.pin)))}e.gamesManager.saveGameData(),e.uiManager.refreshContainer()};const L=re("span",{className:"latest-games-drag-toggle control-button",innerHTML:H.drag});F(L,e.enableDragging?"Перетаскивание: Включено":"Перетаскивание: Отключено"),L.classList.toggle("latest-games-disabled",!e.enableDragging),L.onclick=()=>{e.enableDragging=!e.enableDragging,e.settingsManager.saveSettings(),e.uiManager.refreshContainer(),F(L,e.enableDragging?"Перетаскивание: Включено":"Перетаскивание: Отключено"),L.classList.toggle("latest-games-disabled",!e.enableDragging)};const E=re("span",{className:"latest-games-desc-toggle control-button",innerHTML:H.info});F(E,e.showButtonDescriptions?"Скрыть описания кнопок":"Показать описания кнопок"),E.classList.toggle("latest-games-disabled",!e.showButtonDescriptions),E.onclick=()=>{e.showButtonDescriptions=!e.showButtonDescriptions,e.settingsManager.saveSettings(),E.classList.toggle("latest-games-disabled",!e.showButtonDescriptions),F(E,e.showButtonDescriptions?"Скрыть описания кнопок":"Показать описания кнопок"),e.uiManager.refreshContainer(),setTimeout((()=>{const e=document.querySelector(".latest-games-controls");e&&(e.scrollTop=e.scrollHeight)}),0)};const I=re("span",{className:"latest-games-help-toggle control-button"+(e.showHelpTooltips?"":" latest-games-disabled"),innerHTML:H.help}),G=()=>{F(I,e.showHelpTooltips?"Скрыть подсказки":"Показать подсказки","help"),I.classList.toggle("latest-games-disabled",!e.showHelpTooltips)};G(),I.addEventListener("click",(()=>{O=null,e.showHelpTooltips=!e.showHelpTooltips,e.settingsManager.saveSettings(),G(),e.uiManager.refreshContainer()}));const N=re("span",{className:"latest-games-search-btn control-button"+(e.showSearchBox?"":" latest-games-disabled"),innerHTML:H.search}),$=()=>{F(N,e.showSearchBox?"[Ctrl + F] Скрыть поисковую строку":"[Ctrl + F] Показать поисковую строку"),N.classList.toggle("latest-games-disabled",!e.showSearchBox)};$(),N.addEventListener("click",(()=>{qt(e),$()}));const D=re("span",{className:"latest-games-random control-button"+(e.randomGameId?"":" latest-games-disabled"),innerHTML:H.random}),A=()=>{c(D,!!e.randomGameId,(()=>{const t={click:"Случайный выбор игры: "+("global"===e.randomGameId?"Глобальный":"local"===e.randomGameId?"Локальный":"Отключен")};return"global"===e.randomGameId?{...t,shift:()=>"Выбрать типы словарей",ctrl:()=>{let e=[];try{const t=JSON.parse(localStorage.getItem("validVocabularies")||"{}");t&&"object"==typeof t&&(e=Object.values(t).flat().filter(Boolean).map(String))}catch(t){e=[]}const t=new Set(e).size,a=(()=>{try{return new Set([...(JSON.parse(localStorage.getItem("bannedVocabularies")||"[]")||[]).map((e=>String("string"==typeof e?e:e.id||e||""))),...(JSON.parse(localStorage.getItem("playedVocabularies")||"[]")||[]).map((e=>String("string"==typeof e?e:e.id||e||"")))].filter(Boolean))}catch(e){return new Set}})();let r=0;for(const t of new Set(e))a.has(t)||r++;return`Обновить список допустимых словарей (всего: ${t}, доступно: ${r})`}}:"local"===e.randomGameId?{...t,shift:()=>"Выбрать типы словарей",alt:()=>"Включить стандартные режимы при локальном случайном выборе: "+(e.randomLocalIncludeStandardModes?"Включено":"Отключено"),shiftAlt:()=>"Исключение уже проигранных словарей: "+(e.randomLocalExcludePlayed?"Включено":"Отключено"),ctrlShift:()=>"Локальный выбор только из текущей группы: "+(e.randomLocalByActiveGroup?"Включено":"Отключено")}:t})()),D.classList.toggle("latest-games-disabled",!e.randomGameId),D.classList.remove("random-global","random-local"),"global"===e.randomGameId?D.classList.add("random-global"):"local"===e.randomGameId&&D.classList.add("random-local")};A(),D.onclick=t=>{if(t.ctrlKey&&t.shiftKey)return e.randomLocalByActiveGroup=!e.randomLocalByActiveGroup,e.settingsManager.saveSettings(),void A();if(t.ctrlKey){fetch("https://raw.githubusercontent.com/VimiummuimiV/KG_Latest_Games/refs/heads/main/src/etc/valid_vocabularies.txt",{cache:"no-store"}).then((e=>{if(!e.ok)throw new Error("Network response was not ok: "+e.status);return e.json()})).then((t=>{try{const a=e.settingsManager.saveValidVocabularies(t.validVocabularies||{}),r=Object.values(a).flat().length;A(),alert(`✔️ Список словарей обновлён, записано ${r} ID.`)}catch(e){console.warn("Could not save valid vocabularies via SettingsManager",e),alert("⚠️ Не удалось сохранить список в localStorage.")}})).catch((e=>{console.warn("Failed to fetch valid vocabularies:",e),alert("⚠️ Ошибка загрузки списка допустимых словарей: "+e.message)}))}else{if(t.shiftKey&&t.altKey)return e.randomLocalExcludePlayed=!e.randomLocalExcludePlayed,e.settingsManager.saveSettings(),void A();if(t.altKey)return e.randomLocalIncludeStandardModes=!e.randomLocalIncludeStandardModes,e.settingsManager.saveSettings(),void A();if(t.shiftKey)return t.preventDefault(),void Ot(t,e);!1===e.randomGameId?e.randomGameId="local":"local"===e.randomGameId?e.randomGameId="global":e.randomGameId=!1,e.settingsManager.saveSettings(),A()}};const q=re("span",{className:"latest-games-start control-button",innerHTML:H.start});F(q,"\n [Shift + Enter | Клик] Начать игру (последняя) или (следующая: на странице игры)||В режиме плейлиста: следующая игра (повтор) или возобновить (если на паузе)\n [Ctrl + Enter | Ctrl + Клик] Запустить (если Автозапуск выкл.) / Повторить текущую игру\n [Ctrl + Shift + Enter | Ctrl + Shift + Клик] Пройти квалификацию по словарю\n [Alt + Shift + Enter | Alt + Shift + Клик] Добавить текущий словарь в Избранные\n ");const _=e=>{try{const t=new URL(e);return t.searchParams.set("qual","1"),t.toString()}catch(t){return e}},B=(t=!1)=>{const a=Ve();if(t&&a){const t=Oe(e);if(t){if(!a.paused){Re({...a,paused:!0});try{e.pageHandler?.cancelReplay(!0)}catch(e){}}return void(location.href=_(t))}}if(a&&!a.paused){Re({...a,paused:!0});try{e.pageHandler?.cancelReplay(!0)}catch(e){}}const r=!t&&e.randomGameId;let o=null;try{if("game"===ae()&&!r&&!t){const a=e.groupsManager.getCurrentGroup(e.groupsManager.groups,e.groupsManager.currentGroupId);if(!a||!Array.isArray(a.games)||0===a.games.length)return alert("❌ Нет игр в текущей группе");const r=e.gamesManager.getPreviousGameId();let o=a.games.findIndex((e=>String(e.id)===String(r)));o=-1===o?0:(o+1)%a.games.length;const n=a.games[o];if(!n)return alert("❌ Не удалось определить следующую игру");e.groupsManager.selectGroup(a.id),e.gamesManager.latestGamesData=e.gamesManager.latestGamesData||{},e.gamesManager.latestGamesData.previousGameId=n.id,e.gamesManager.saveGameData();const s=String(n.params?.vocId||"");if(s)try{e.gamesManager.registerPendingPlayed(s,n.params?.vocName||null,n.params?.vocType||null)}catch(e){}const i=e.gamesManager.generateGameLink(n);return void(location.href=t?_(i):i)}}catch(e){console.warn("Error selecting next game in group",e)}if(r){if(o=e.gamesManager.getRandomGameId(),!o)return alert("❌ Нет подходящей игры")}else{const t=e.gamesManager.getPreviousGameId();if(!t)return alert("❌ Нет подходящей игры");const a=e.gamesManager.findGameById(t);if(!a)return alert("❌ Игра не найдена");o={mode:"local",id:t,game:a,groupId:e.groupsManager.currentGroupId,url:e.gamesManager.generateGameLink(a)}}if("local"!==o.mode)"global"!==o.mode||(async()=>{const a=await e.gamesManager.getValidRandomGameId();if(!a)return alert("🔒 Максимальное количество попыток поиска подходящей игры исчерпано. Попробуйте ещё раз.");if(a.id)try{e.gamesManager.registerPendingPlayed(a.id)}catch(e){}window.location.href=t?_(a.url):a.url})();else{if(o.groupId)e.groupsManager.selectGroup(o.groupId);else for(const t of e.groupsManager.groups)if(t.games.some((e=>e.id===o.id))){e.groupsManager.selectGroup(t.id);break}e.gamesManager.latestGamesData=e.gamesManager.latestGamesData||{},e.gamesManager.latestGamesData.previousGameId=o.id,e.gamesManager.saveGameData();const a=String(o.game.params.vocId||"");if(a)try{e.gamesManager.registerPendingPlayed(a,o.game.params.vocName||null,o.game.params.vocType||null)}catch(e){}if(!o.url){if(!o.game)return alert("❌ Игра не найдена");o.url=e.gamesManager.generateGameLink(o.game)}location.href=t?_(o.url):o.url}};async function V(){if("game"!==ae())return alert("⚠️ Блокировать словарь можно только на странице игры"),!1;const e=Te();if(!e)return alert("⚠️ Не удалось определить ID текущего словаря"),!1;try{_t.currentListType="bannedVocabularies";const t=_t.get();if(t.some((t=>t.id===String(e))))return alert(`🛑 Словарь ${e} уже в чёрном списке`),!1;const a=await $e(e).catch((()=>null)),r={id:String(e),name:a?.vocabularyName||null,author:a?.vocabularyAuthor||null,vocType:a?.vocabularyType||null,isPublic:a?.vocabularyIsPublic||null,createdDate:a?.createdDate||null,versionDate:a?.versionDate||null,isNew:!0},o=[...t,r];_t.save(o,!1),alert(`✔️ Словарь ${e} добавлен в чёрный список`);try{B()}catch(e){console.warn("Could not start a new game after banning vocabulary",e)}return!0}catch(e){return console.error("Error banning vocabulary:",e),alert("⚠️ Ошибка при блокировке словаря"),!1}}function R(){if("game"!==ae())return alert("⚠️ Добавлять в Избранные можно только на странице игры"),!1;const t=Te();if(!t)return alert("⚠️ Не удалось определить ID текущего словаря"),!1;let a=e.groupsManager.groups.find((e=>"Избранные"===e.title));if(!a){const t=e.groupsManager.createGroup("Избранные");e.groupsManager.groups.push(t),a=t}(async()=>{try{let r="",o=null;const n=await $e(t).catch((()=>null));n&&n.vocabularyName&&(r=n.vocabularyName,o=n.vocabularyType||null);const s=e.groupsManager.groups.find((e=>e.games.some((e=>String(e.params?.vocId)===String(t)))));if(s)return void(s.id===a.id?alert(`🛑 Словарь ${t} уже в группе "Избранные"`):alert(`🛑 Словарь ${t} уже в группе "${s.title}"`));De(a,String(t),r,o,e.groupsManager.groups,e),alert(`✔️ Словарь ${t} добавлен в группу "Избранные"`);const i=a.games.find((e=>String(e.params?.vocId)===String(t)));if(i){const t={clientX:Math.floor(window.innerWidth/2),clientY:Math.floor(window.innerHeight/2)};try{lt(e,e.groupsManager.groups,a.id,t,i.id)}catch(e){console.warn("Could not open migration popup for newly added vocabulary",e)}}}catch(e){console.warn("Could not add vocabulary to favorites group",e),alert("⚠️ Не удалось добавить словарь в Избранные")}})()}function j(){if("game"!==ae())return void alert("⚠️ Повторить игру можно только на странице игры");const t=document.querySelector("#status-inner #paused");if(!e.shouldStart&&t&&"none"!==t.style.display)return void("undefined"!=typeof game&&game.hostStart&&game.hostStart());const a=location.href.match(/[?&]gmid=(\d+)/),r=a?.[1];r&&(window.location.href=`https://klavogonki.ru/g/${r}.replay`)}const z=()=>{const t=Ve();if(!t)return!1;if(t.paused){Re({...t,paused:!1});const a=Oe(e);a&&(window.location.href=a)}else{const t=e.replayWithoutWaiting?document.querySelector(T.immediate):document.querySelector(T.normal);if(t&&"none"!==t.style.display){const t=Oe(e);t&&(window.location.href=t)}else{const t=ze(e);t?.url&&(window.location.href=t.url)}}return!0};q.onclick=e=>!e.ctrlKey||e.shiftKey||e.altKey?e.altKey&&e.shiftKey?(e.preventDefault(),void R()):e.ctrlKey&&e.shiftKey?(e.preventDefault(),void B(!0)):void(z()||B()):(e.preventDefault(),void j());const Y=re("span",{className:"latest-games-ban-vocabulary control-button",innerHTML:H.slash});F(Y,"\n [Клик] Показать заблокированные словари\n [Alt + Enter | Alt + Клик] Заблокировать текущий словарь\n "),Y.onclick=e=>{e.altKey?(e.preventDefault(),V()):(e.stopPropagation(),_t.toggle(e.clientX,e.clientY,"bannedVocabularies"))};const W=re("span",{className:"latest-games-played-vocabularies control-button",innerHTML:H.book});F(W,"Показать проигранные словари"),W.onclick=e=>{e.stopPropagation(),_t.toggle(e.clientX,e.clientY,"playedVocabularies")},document.body.classList.add("latest-games-registered"),document.addEventListener("keydown",(t=>{if(t.ctrlKey&&"KeyF"===t.code){const a=document.getElementById("latest-games-container");if(a&&a.classList.contains("visible"))return t.preventDefault(),qt(e),void $()}return t.altKey&&t.shiftKey&&"Enter"===t.code?(t.preventDefault(),void R()):t.ctrlKey&&t.shiftKey&&"Enter"===t.code?(t.preventDefault(),void B(!0)):t.ctrlKey&&"Enter"===t.code?(t.preventDefault(),void j()):t.shiftKey&&"Enter"===t.code?void(z()||B()):t.altKey&&"Enter"===t.code?(t.preventDefault(),void V()):void 0}));const K=re("span",{className:"latest-games-vocabulary-data control-button",innerHTML:H.vocabularyData}),X=()=>{F(K,e.showVocabularyData?"Скрыть содержимое словаря":"Показать содержимое словаря"),K.classList.toggle("latest-games-disabled",!e.showVocabularyData)};X(),K.addEventListener("click",(()=>{e.showVocabularyData=!e.showVocabularyData,e.settingsManager.saveSettings(),X(),e.uiManager.refreshContainer()})),at.main=e;const J=re("span",{className:"latest-games-playlists control-button",innerHTML:H.playlists}),U=()=>{const t=2===e.playlistPanelAutoOpen?"Закреплена":1===e.playlistPanelAutoOpen?"Автооткрытие":"Отключена";F(J,`[Клик] Открыть плейлисты\n [Ctrl + Клик] Панель при активном плейлисте: ${t}`)};U(),J.addEventListener("click",(t=>{if(t.stopPropagation(),t.ctrlKey)return e.playlistPanelAutoOpen=(e.playlistPanelAutoOpen+1)%3,e.settingsManager.saveSettings(),void U();at.toggle(t.clientX,t.clientY)}));const Z=[m,y,v,D,q,Y,W,J],Q=[e.themeManager.createThemeToggle(),e.viewManager.createDisplayModeToggle(),g,u,f,x,w,k,C,M,S,L,E,I,N,K],te=re("span",{className:"latest-games-more-toggle control-button",innerHTML:H.moreHorizontal});Z.forEach((e=>o.appendChild(e))),o.appendChild(te),F(te,"Показать дополнительные кнопки"),Q.forEach((e=>n.appendChild(e)));const oe=()=>{n.classList.remove("open"),te.classList.remove("open"),document.removeEventListener("click",ne)},ne=e=>{r.contains(e.target)||oe()};return te.addEventListener("click",(e=>{e.stopPropagation(),n.classList.contains("open")?oe():(n.classList.add("open"),te.classList.add("open"),setTimeout((()=>{document.addEventListener("click",ne)}),0))})),t}function Xt(e){const t=re("div",{id:"latest-games-hover-area"});t.addEventListener("mouseenter",(()=>Jt(e))),t.addEventListener("mouseleave",(()=>Ut(e))),document.body.appendChild(t)}function Jt(e){e.isHovered=!0,e.hoverTimeout&&clearTimeout(e.hoverTimeout),e.hoverTimeout=null;const t=document.getElementById("latest-games-container");if(t){const a=t.classList.contains("visible");if(t.classList.add("visible"),t.style.left="0","wrap"===e.viewManager.getDisplayMode()&&(t.style.top=`${e.panelYPosition}vh`),t.scrollTop=e.previousScrollPosition,!a){const e=t.querySelector(".latest-game.previous-game");e&&(e.style.animation="none",setTimeout((()=>e.style.animation=""),10))}}}function Ut(e){const t=ae();(e.alwaysVisiblePanel[t]??!1)||(e.isHovered=!1,e.hoverTimeout&&clearTimeout(e.hoverTimeout),e.hoverTimeout=setTimeout((()=>{if(!e.isHovered){const t=document.getElementById("latest-games-container");t&&(t.classList.remove("visible"),e.viewManager.updateContainerLeftOffset())}}),e.hidePanelDelay))}function Zt(e){const t=document.getElementById("latest-games-container"),a=ae(),r=e.alwaysVisiblePanel[a]??!1;return`\n [Клик] ${t&&t.classList.contains("visible")?"Скрыть":"Показать"} панель\n [Shift + Клик] ${r?"Открепить":"Закрепить"} панель\n [Ctrl + Клик] Изменить задержку скрытия панели\n (${e.hidePanelDelay??P.hidePanelDelay} мс)\n `}function Qt(e){if(document.getElementById("latest-games-panel-toggle"))return;const t=ae(),a=e.alwaysVisiblePanel[t]??!1,r=re("button",{id:"latest-games-panel-toggle",className:"latest-games-panel-toggle",type:"button",innerHTML:a?H.panelToggleOpened:H.panelToggleClosed}),o=document.getElementById("latest-games-container"),n=()=>{X(r,Zt(e))};r.addEventListener("mouseenter",n),F(r,Zt(e)),a&&r.classList.add("always-visible"),o&&(o.classList.toggle("visible",a),a||e.viewManager.updateContainerLeftOffset()),r.addEventListener("click",(t=>{const a=document.getElementById("latest-games-container");if(!a)return;const o=ae();if(t.ctrlKey){const t=e.hidePanelDelay??P.hidePanelDelay,a=prompt("Изменить задержку автоскрытия панели в миллисекундах:",t),r=parseInt(a,10);!isNaN(r)&&r>=0?(e.hidePanelDelay=r,e.settingsManager.saveSettings()):null!==a&&alert("Пожалуйста, введите корректное значение задержки.")}else if(t.shiftKey){e.alwaysVisiblePanel[o]=!e.alwaysVisiblePanel[o];const t=e.alwaysVisiblePanel[o];r.classList.toggle("always-visible",t),r.innerHTML=t?H.panelToggleOpened:H.panelToggleClosed,a.classList.toggle("visible",t),t||e.viewManager.updateContainerLeftOffset(),e.settingsManager.saveSettings(),n()}else{a.classList.contains("visible")?(e.hoverTimeout&&(clearTimeout(e.hoverTimeout),e.hoverTimeout=null),a.classList.remove("visible"),e.viewManager.updateContainerLeftOffset()):e.uiManager.showContainer(),n()}})),document.body.appendChild(r)}class ea{constructor(e){this.main=e,this.createGameElement=Tt.bind(null,this.main),this.createControls=Ft.bind(null,this.main),this.createSearchBox=Pt.bind(null,this.main),this.createHoverArea=Xt.bind(null,this.main),this.showContainer=Jt.bind(null,this.main),this.hideContainer=Ut.bind(null,this.main),this.createPanelToggleButton=Qt.bind(null,this.main)}scrollToPreviousGame(){const e=document.getElementById("latest-games-content"),t=document.querySelector(".previous-game");if(!e||!t)return;const a=e.getBoundingClientRect(),r=t.getBoundingClientRect(),o=r.top-a.top-a.height/2+r.height/2;e.scrollTop+=o}createContainer(){const e=re("div",{id:"latest-games-container"});e.addEventListener("mouseenter",(()=>{this.showContainer(),requestAnimationFrame((()=>this.scrollToPreviousGame()))}));const t=re("div",{id:"latest-games-content"}),a=this.createSearchBox();t.appendChild(a);const r=this.main.groupsManager.createGroupsContainer();t.appendChild(r);const o=re("ul",{id:"latest-games"});this.populateGamesList(o),t.appendChild(o);const n=this.createControls();e.append(n,t),t.addEventListener("scroll",(()=>{this.main.previousScrollPosition=t.scrollTop,this.main.settingsManager.saveSettings()})),e.addEventListener("mouseenter",(()=>this.showContainer())),e.addEventListener("mouseleave",(()=>this.hideContainer()));let s=null,i=!1;const l=e=>{const t=e.target.closest(".latest-game");if(!t)return;const a=t.id.replace("latest-game-",""),r=this.main.gamesManager.findGameById(a);r&&!this.main.enableDragging&&bt(r,e,this.main)};o.addEventListener("mousedown",(e=>{0===e.button&&(s=setTimeout((()=>{i=!0,e.preventDefault(),l(e)}),300))})),o.addEventListener("mouseup",(()=>{clearTimeout(s)})),o.addEventListener("click",(e=>{i&&(e.stopImmediatePropagation(),e.preventDefault(),i=!1)}),{capture:!0}),o.addEventListener("contextmenu",(e=>{const t=e.target.closest(".latest-game");if(t){e.preventDefault();const a=t.id.replace("latest-game-","");lt(this.main,this.main.groupsManager.groups,this.main.groupsManager.currentGroupId,e,a)}}));let p=e.querySelector(".resize-handle-horizontal");p||(p=re("div",{className:"resize-handle-horizontal"}),e.appendChild(p));let c=e.querySelector(".resize-handle-vertical-bottom");c||(c=re("div",{className:"resize-handle-vertical resize-handle-vertical-bottom"}),e.appendChild(c));let d=e.querySelector(".resize-handle-vertical-top");d||(d=re("div",{className:"resize-handle-vertical resize-handle-vertical-top"}),e.appendChild(d)),xt(this,e,p,c,d),wt(this,e),document.body.appendChild(e),this.main.groupsManager.updateGroupControlStates(),this.main.viewManager.updateDisplayModeClass();e.querySelectorAll(".group-tab").forEach((e=>{e.getBoundingClientRect().width>=300&&F(e,e.textContent)}));const g=this.main.viewManager.updateDisplayModeClass.bind(this.main.viewManager);this.main.viewManager.updateDisplayModeClass=(...t)=>{g(...t),xt(this,e,p,c,d),wt(this,e)},this.updateRemoveIcons(),setTimeout((()=>requestAnimationFrame((()=>this.scrollToPreviousGame()))),100)}updateGameCountDisplay(){const e=document.getElementById("latest-games-count");e&&(e.textContent=this.main.maxGameCount.toString(),e.classList.toggle("latest-games-disabled",!1===this.main.shouldAutoSave),F(e,this.main.shouldAutoSave?"Автосохранение: Включено":"Автосохранение: Отключено"))}populateGamesList(e){if(e.innerHTML="","tabs"===this.main.groupsManager.getGroupViewMode()){const t=this.main.groupsManager.getCurrentGroup();if(!t)return;const a=this.main.groupsManager.getPinnedGameCount(),r=Math.min(t.games.length,this.main.maxGameCount+a);for(let a=0;a{if(t.games.length>0){const a=this.main.groupsManager.createGroupHeader(t);e.appendChild(a);const r=t.games.filter((e=>e.pin)).length,o=Math.min(t.games.length,this.main.maxGameCount+r);for(let a=0;a0?H.trashSomething:H.trashNothing);const a=document.querySelector(".latest-games-removeall.control-button"),r=this.main.groupsManager.groups.some((e=>e.games&&e.games.length>0));a&&(a.innerHTML=r?H.trashSomething:H.trashNothing)}refreshContainer(){this.main.groupsManager.refreshGroupsContainer();const e=document.getElementById("latest-games");e&&(this.populateGamesList(e),this.main.viewManager.updateDisplayModeClass()),this.updateRemoveIcons(),this.updateGameCountDisplay(),requestAnimationFrame((()=>this.scrollToPreviousGame()))}}class ta{constructor(e){this.mainManager=e}parseGameParams(e,t){const a=e.className.split("-").pop(),r="voc"===a?e.textContent.replace(/[«»]/g,""):"";let o="";if("voc"===a){const t=e.querySelector("a");if(t){const e=t.href.match(/vocs\/(\d+)/);o=e?parseInt(e[1],10):""}}let n="normal";/одиночный/.test(t)?n="practice":/друзьями/.test(t)&&(n="private");let s=1,i=9;const l=t.match(/для (\S+)–(\S+),/);l&&(s=G[l[1]]||1,i=G[l[2]]||9);const p=t.match(/таймаут\s(\d+)\s(сек|мин)/),c=p?"сек"===p[2]?parseInt(p[1],10):60*parseInt(p[1],10):60,d=t.match(/AFK\s(\d+)\s(сек|мин)/i);return{gametype:a,vocName:r,vocId:o,vocType:null,type:n,level_from:s,level_to:i,timeout:c,idletime:d?"сек"===d[2]?parseInt(d[1],10):60*parseInt(d[1],10):0,qual:/квалификация/.test(t)?1:0,premium_abra:0}}generateGameName(e,t={}){const a=M[e.params.gametype],{vocName:r,timeout:o,type:n,level_from:s,level_to:i,qual:l,idletime:p}=e.params;let c="";t&&t.stateIcon&&(c=t.stateIcon);const d=re("span",{className:`latest-game-name gametype-${e.params.gametype}`});if(d.appendChild(document.createTextNode(""===r?a:`«${r}»`)),c){const e=re("span",{className:"latest-game-state-icon",innerHTML:c});d.appendChild(e)}let g=null;this.mainManager.showButtonDescriptions&&(g=re("span",{className:"latest-game-description"}));const u=re("span",{className:"latest-game-qual",innerHTML:l?H.qualification:""});let m="";if("normal"===n&&(1!==s||9!==i)){const e=I[s-1];m=s===i?` ${e}`:` ${e} - ${I[i-1]}`}const h=re("span",{className:"latest-game-levels",textContent:m});if(g){let e=`${E[n]}, TM ${o}`;p&&p>0&&(e+=`, AFK ${p}`),g.textContent=e,g.appendChild(u),m&&g.appendChild(h)}const y=re("div");return y.appendChild(d),g&&y.appendChild(g),y.innerHTML}generateGameLink(e){const{gametype:t,vocId:a,type:r,level_from:o,level_to:n,timeout:s,qual:i,idletime:l}=e.params,p=new URLSearchParams({gametype:t,type:r,timeout:s.toString(),submit:"1"});return"practice"!==r&&"private"!==r&&(p.set("level_from",o.toString()),p.set("level_to",n.toString())),""!==a&&p.set("voc",a),i&&p.set("qual","1"),null!=l&&p.set("idletime",l.toString()),`${location.protocol}//klavogonki.ru/create/?${p.toString()}`}loadGameData(){try{let e=localStorage.getItem("latestGamesData");if(e)if(e=JSON.parse(e),Array.isArray(e)){const t=[{id:ee(e),title:"Группа-1",games:e}],a=t[0].id;this.mainManager.groupsManager.setGroups(t,a),this.latestGamesData={}}else e&&Array.isArray(e.groups)?(this.mainManager.groupsManager.setGroups(e.groups,e.currentGroupId),this.latestGamesData={previousGameId:e.previousGameId,latestGroupAddedGameId:e.latestGroupAddedGameId}):(this.mainManager.groupsManager.setGroups([],null),this.latestGamesData={});else this.mainManager.groupsManager.setGroups([],null),this.latestGamesData={};this.migrateOldGameData(),this.assignGameIds()}catch(e){console.warn("Could not load game data from localStorage:",e),this.mainManager.groupsManager.setGroups([],null),this.latestGamesData={}}}saveGameData(){try{const e={groups:this.mainManager.groupsManager.groups,currentGroupId:this.mainManager.groupsManager.currentGroupId,previousGameId:this.latestGamesData?.previousGameId,latestGroupAddedGameId:this.latestGamesData?.latestGroupAddedGameId};localStorage.setItem("latestGamesData",JSON.stringify(e))}catch(e){console.warn("Could not save game data to localStorage:",e)}}migrateOldGameData(){this.mainManager.groupsManager.groups.forEach((e=>{e.games=e.games.map((e=>("on"!==e.params.qual&&""!==e.params.qual||(e.params.qual="on"===e.params.qual?1:0),e)))}))}assignGameIds(){const e=new Set;this.mainManager.groupsManager.groups.forEach((t=>{t.games.forEach((t=>{t.id&&e.add(t.id)}))})),this.mainManager.groupsManager.groups.forEach((t=>{t.games=t.games.map((t=>{if(t.id&&-1!==t.id)return e.add(t.id),t;{const a=ee(this.mainManager.groupsManager.groups);return e.add(a),{...t,id:a}}}))}))}updateGameOrderFromDOM(){const e=this.mainManager.groupsManager.getCurrentGroup(this.mainManager.groupsManager.groups,this.mainManager.groupsManager.currentGroupId);if(!e)return;const t=Array.from(document.querySelectorAll("#latest-games .latest-game"));e.games=t.map((t=>{const a=t.id.replace("latest-game-","");return e.games.find((e=>e.id===a))})).filter((e=>void 0!==e)),this.saveGameData()}findGameIndex(e){for(const t of this.mainManager.groupsManager.groups){const a=t.games.findIndex((t=>t.id==e));if(-1!==a)return{group:t,index:a}}return null}findGameById(e){for(const t of this.mainManager.groupsManager.groups){const a=t.games.find((t=>t.id===e));if(a)return a}return null}findGamesByVocId(e){const t=String(e),a=[];for(const e of this.mainManager.groupsManager.groups)for(const r of e.games)"voc"===r.params?.gametype&&String(r.params?.vocId)===t&&a.push(r);return a}deleteGame(e){const t=this.findGameIndex(e);if(!t)return null;const{group:a,index:r}=t,o=a.games.splice(r,1)[0];return this.assignGameIds(),this.saveGameData(),this.mainManager.uiManager.refreshContainer(),o}pinGame(e){const t=this.findGameIndex(e);if(!t)return;const{group:a,index:r}=t,o=a.games[r];o.pin=o.pin?0:1,a.games.sort(((e,t)=>t.pin-e.pin)),this.assignGameIds(),this.saveGameData(),this.mainManager.uiManager.refreshContainer()}changeGameCount(e){e<0&&this.mainManager.maxGameCount>0?this.mainManager.maxGameCount--:e>0&&this.mainManager.maxGameCount++,this.mainManager.uiManager.updateGameCountDisplay(),this.mainManager.settingsManager.saveSettings(),this.mainManager.uiManager.refreshContainer()}getPreviousGameId(){return this.latestGamesData&&this.latestGamesData.previousGameId?this.latestGamesData.previousGameId:null}getRandomGame(){if(!(this.mainManager&&this.mainManager.validVocabularies&&"object"==typeof this.mainManager.validVocabularies&&this.mainManager.randomVocabulariesType&&"object"==typeof this.mainManager.randomVocabulariesType))return null;const e=new Set,t=new Set;try{const a=localStorage.getItem("bannedVocabularies");if(a){const t=JSON.parse(a);Array.isArray(t)&&t.forEach((t=>{const a=String("string"==typeof t?t:t.id||String(t));e.add(a)}))}const r=localStorage.getItem("playedVocabularies");if(r){const e=JSON.parse(r);Array.isArray(e)&&e.forEach((e=>{const a=String("string"==typeof e?e:e.id||String(e));t.add(a)}))}}catch(e){console.warn("Could not parse banned/played vocabularies",e)}const a=Object.keys(this.mainManager.randomVocabulariesType).filter((e=>!0===this.mainManager.randomVocabulariesType[e]));if("global"===this.mainManager.randomGameId){const r=a.flatMap((e=>this.mainManager.validVocabularies[e]||[])).filter((a=>null!=a&&!e.has(String(a))&&!t.has(String(a))));if(0===r.length)return null;return{mode:"global",params:{gametype:"voc",vocName:"",vocId:r[Math.floor(Math.random()*r.length)],vocType:null,type:"normal",level_from:1,level_to:9,timeout:10,qual:0,premium_abra:0}}}const r=[],o=!1!==this.mainManager.randomLocalExcludePlayed,n=this.mainManager.groupsManager.getCurrentGroup();if((this.mainManager.randomLocalByActiveGroup&&n?[n]:this.mainManager.groupsManager.groups).forEach((n=>{n.games.forEach((s=>{if((a=>!!a&&(e.has(a)||o&&t.has(a)))(String(s.params.vocId||"")))return;const i=s.params.vocType,l=i&&a.includes(i),p=!i&&this.mainManager.randomLocalIncludeStandardModes;(l||p)&&r.push({game:s,groupId:n.id})}))})),0===r.length)return null;const s=Math.floor(Math.random()*r.length);return{mode:"local",game:r[s].game,groupId:r[s].groupId}}getRandomGameId(){const e=this.getRandomGame();if(!e)return null;if("global"===e.mode){const t={params:e.params};return{mode:"global",id:e.params.vocId,params:e.params,url:this.generateGameLink(t)}}return{mode:"local",id:e.game?e.game.id:null,game:e.game,groupId:e.groupId,url:e.game?this.generateGameLink(e.game):null}}async getValidRandomGameId(e=50){const t=!e||e<=0;for(let a=0;t||a("string"==typeof e?e:e.id)===r));if(-1!==i){"string"==typeof o[i]&&(o[i]={id:o[i],playHistory:[]}),o[i].playHistory||(o[i].playHistory=[]);const e=o[i].playHistory.find((e=>{const t=new Date(e.date);return t.setHours(0,0,0,0),t.toISOString()===s}));e?e.count++:o[i].playHistory.push({date:s,count:1}),o[i].playedAt=(new Date).toISOString(),o[i].isNew=!0}else{const e=t&&a?null:await $e(r).catch((()=>null));o.push({id:r,name:t||e?.vocabularyName||null,author:e?.vocabularyAuthor||null,vocType:a||e?.vocabularyType||null,isPublic:e?.vocabularyIsPublic||null,createdDate:e?.createdDate||null,versionDate:e?.versionDate||null,isNew:!0,playedAt:(new Date).toISOString(),playHistory:[{date:s,count:1}]})}localStorage.setItem("playedVocabularies",JSON.stringify(o));try{this.registerPendingPlayed(r)}catch(e){}}catch(e){}}}Object.values(v).forEach((e=>{if(!document.getElementById(e.id)){const t=document.createElement("link");t.id=e.id,t.rel="stylesheet",t.href=e.url,document.head.appendChild(t)}})),window.latestGamesManager??=new class{constructor(){this.initializeDefaults(),this.initializeManagers(),this.init()}initializeDefaults(){Object.assign(this,P)}initializeManagers(){this.themeManager=new le(this),this.settingsManager=new pe(this),this.groupsManager=new ce(this),this.viewManager=new de(this),this.pageHandler=new it(this),this.uiManager=new ea(this),this.gamesManager=new ta(this)}init(){this.settingsManager.loadSettings(),this.gamesManager.loadGameData(),this.groupsManager.initializeGroups(),this.uiManager.createHoverArea(),this.uiManager.createContainer(),this.alwaysVisiblePanel&&this.uiManager.showContainer(),this.uiManager.createPanelToggleButton(),this.pageHandler.handlePageSpecificLogic(),this.exposeGlobalFunctions(),this.themeManager.applyTheme()}exposeGlobalFunctions(){window.latestGamesManager=this}}})();