Участник:Skmp/LEP.js

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Страница персонального оформления. У этого JS-кода есть документация: Участник:Skmp/LEP.
После сохранения очистите кэш браузера.
// ======================== ! ВНИМАНИЕ ! ========================
// Инструмент находится на ранней стадии разработки, и
// хоть ошибочных откатов и патрулирований у меня еще
// не возникало, имейте ввиду, что я НЕ беру на себя
// ответственность за ошибочные действия, совершённые
// при использовании этого инструмента.
//
// Больше информации про инструмент тут — Участник:Skmp/LEP/info
// ==============================================================

const LEP_VER = "0.6β";

const lep_html =
`
<style>
    #lep-version {
        float: right;

        margin-top: 2px;
    	margin-bottom: 10px;

        color: hsl(0, 0%, 50%);
        font-size: 12px;
    }

    #lep {
        position: relative;

        display: flex;

	    height: 100%;

        font-family: sans-serif;
    }

    #lep.darkmode {
    	background-color: hsl(228,4%,10%);
    }

    #lep.darkmode a {
	    color: hsl(217deg 91% 45%);
    }

    #lep > .edits-panel {
        overflow: auto;

        flex-shrink: 0;
    
        width: 250px;
    }

    #lep > .edits-panel > .items {
        display: flex;
        flex-direction: column;
    }

    #lep > .edits-panel > .items > .new,
    #lep > .edits-panel > .items > .blacklist,
    #lep > .edits-panel > .items > .others,
    #lep > .edits-panel > .items > .reds {
        display: flex;
        flex-direction: column-reverse;
    }

    @keyframes lep-item-show {
        0% {
            filter: invert(1);
        }
        25% {
            filter: invert(0);
        }
        50% {
            filter: invert(1);
        }
        100% {
            filter: invert(0);
        }
    }

    #lep > .edits-panel > .items > .blacklist > .item,
    #lep > .edits-panel > .items > .reds > .item {
        animation: lep-item-show 0.5s ease-in-out forwards;
    }

    #lep > .edits-panel > .items > .blacklist > .item {
        color: crimson !important;
    }

    #lep > .edits-panel > .items .item {
        display: flex;
        justify-content: space-between;
        align-items: center;

        padding: 9px 10px;
        
        user-select: none;
        cursor: pointer;

        background-color: white;

        font-size: 14px;
    }

    #lep.darkmode > .edits-panel > .items .item {
	    color: hsl(228,4%,80%);
		background-color: hsl(228,4%,14%);
	}

    #lep > .edits-panel > .items .item.selected {
        background-color: #eaf3ff;
        color: #36c;
    }

    #lep.darkmode > .edits-panel > .items .item.selected {
		background-color: hsl(228deg 28% 20%);
	    color: hsl(228deg 100% 68%);
	}

    #lep > .edits-panel > .items .item > .title {
        width: 75%;
        word-break: break-word;
    }

    #lep > .edits-panel > .items .item > .title > span {
    	color: gray;
    	font-size: 12px;
	}

    #lep > .edits-panel > .items .item > .score {
        color: hsl(0, 0%, 50%);

        font-size: 12px;
        font-style: italic;
    }

    #lep > .edits-panel > .items .item > .score.red {
        color: crimson;
        font-weight: bold;
    }

    #lep.darkmode > .edits-panel > .items .item > .score.red {
    	color: #ff1e48;
	}

    #lep > .edits-panel > .items .item > .score.orange {
        color: coral;
        font-weight: bold;
    }

    #lep > .edits-panel > .items .item:hover {
        background-color: rgba(234, 243, 255, 0.75);
    }

    #lep.darkmode > .edits-panel > .items .item:hover {
	    color: hsl(228,4%,90%);
		background-color: hsl(228,4%,22%);
	}

    #lep > .main-panel {
        display: flex;
        flex-direction: column;

        width: 100%;

        border-left: 1px solid #a2a9b1;
    }

    #lep.darkmode > .main-panel {
        border-left: 1px solid hsl(228,4%,25%);
	}

    #lep > .main-panel > .actions-panel {
        display: flex;
        align-items: center;
        justify-content: space-between;
        box-sizing: border-box;

        width: 100%;
        padding: 15px;
    }

    #lep > .main-panel > .actions-panel > .settings-panel {
        display: flex;
        align-items: flex-end;

        height: 100%;
    }

    #lep > .main-panel > .actions-panel > .actions {
        display: flex;
    }

    #lep > .main-panel > .actions-panel > .actions .buttons-container {
        display: flex;
        align-self: center;
    }

    #lep > .main-panel > .actions-panel > .actions .buttons-container > .vertical-container {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }

    #lep > .main-panel > .actions-panel .normal-button {
        padding: 4px 8px;
        
        user-select: none;
        cursor: pointer;

        background-color: #f8f9fa;

        border: 1px solid #a2a9b1;
        border-radius: 3px;

        color: #444;
        font-size: 12px;
        font-weight: bold;

        text-align: center;

        transition: 0.1s;
    }

    #lep.darkmode > .main-panel > .actions-panel .normal-button {
	    color: hsl(228,4%,70%);

        border: 1px solid hsl(228,4%,15%);
        background-color: hsl(228,4%,15%);
    }

    #lep > .main-panel > .actions-panel .normal-button:hover {
        background-color: white;
    }

    #lep.darkmode > .main-panel > .actions-panel .normal-button:hover {
	    color: hsl(228,4%,85%);

        border: 1px solid hsl(228,4%,22%);
        background-color: hsl(228,4%,22%);
	}

    #lep > .main-panel > .actions-panel .normal-button:active {
        background-color: hsl(0, 0%, 90%);
        border: 1px solid hsl(212, 9%, 60%);
    }

    #lep > .main-panel > .actions-panel .normal-button.big {
        font-size: 12.5px;
        padding: 8px 14px;
    }

    #lep > .main-panel > .actions-panel .normal-button.small {
        font-size: 12px;
        font-weight: normal;
        padding: 3px 6px;
    }

    #lep > .main-panel > .actions-panel .normal-button.disabled {
        pointer-events: none;

        background-color: #eaecf0;
        color: #72777d;
        border: 1px solid #c8ccd1 !important;
    }

    #lep.darkmode > .main-panel > .actions-panel .normal-button.disabled {
	    color: hsl(228,4%,40%);

        border: 1px solid hsl(228,0%,20%) !important;
        background-color: hsl(228,0%,20%);
    }

    #lep > .main-panel > .actions-panel .normal-button.blue {
        border: 2px solid hsla(228, 80%, 50%, 1);
    }

    #lep > .main-panel > .actions-panel > .actions .big-button {
        padding: 25px;
        margin-right: 6px;

        user-select: none;
        cursor: pointer;

        color: white;
        background-color: #E82000;
        border-radius: 5px;

        font-size: 16px;
        font-family: monospace;
        text-transform: uppercase;
        letter-spacing: 2px;

        transition: 0.2s;
    }

    #lep > .main-panel > .actions-panel > .actions .big-button.hidden {
        display: none;
    }

    #lep > .main-panel > .actions-panel > .actions .big-button.blue {
        background-color: #1744FF;
    }

    #lep > .main-panel > .actions-panel > .actions .big-button.blue:hover {
        background-color: hsl(228, 100%, 46%);
    }

    #lep > .main-panel > .actions-panel > .actions .big-button.disabled {
        transition: 0s;

        background-color: hsl(0, 0%, 70%);
        pointer-events: none;
    }

    #lep > .main-panel > .actions-panel > .actions .big-button:hover {
        background-color: hsl(8, 100%, 43%);
        box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.15);
    }

    #lep > .main-panel > .actions-panel > .actions .big-button:active {
        transition: 0s;

        background-color: hsl(8, 100%, 37%);
        box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.15);
    }

    #lep > .main-panel > .actions-panel > .actions > .undo-container {
        display: flex;
        flex-direction: column;
        
        padding: 0 15px;

        width: 150px;
    }

    #lep > .main-panel > .actions-panel > .actions > .undo-container > .text {
        color: hsl(0, 0%, 20%);
        font-size: 12px;
        font-style: italic;

        margin-bottom: 4px;
    }

    #lep > .main-panel > .actions-panel > .actions > .undo-container > .buttons {
        display: flex;
        align-items: flex-start;
        align-content: flex-start;
        flex-wrap: wrap;
    }

    #lep > .main-panel > .actions-panel .buttons .normal-button {
        margin: 0 3px 3px 0;
    }

    #lep > .main-panel > .edit-panel {
        height: 100%;
        width: 100%;

        overflow: auto;
        padding: 10px;
        box-sizing: border-box;

        border-top: 1px solid #a2a9b1;
    }

    #lep.darkmode > .main-panel > .edit-panel {
        border-top: 1px solid hsl(228,4%,25%);
	}

    #lep.darkmode > .main-panel > .edit-panel .diff {
    	filter: invert(1);
    }

    #lep > .main-panel > .edit-panel > .edit-info {
        display: flex;
        align-items: center;

        padding-bottom: 8px;
    }

    #lep > .main-panel > .edit-panel > .edit-info > span,
    #lep > .main-panel > .edit-panel > .edit-info > a {
        margin-right: 10px;

        text-decoration: none;
    }

    #lep > .main-panel > .edit-panel > .edit-info > span:empty,
    #lep > .main-panel > .edit-panel > .edit-info > a:empty {
        margin-right: 0;
    }

    #lep > .main-panel > .edit-panel > .edit-info > a.red {
        color: crimson;
    }

    #lep.darkmode > .main-panel > .edit-panel > .edit-info > a.red {
    	color: #ff1e48;
	}

    #lep > .main-panel > .edit-panel > .edit-info > a.green {
        color: #00DD37;
    }

    #lep > .main-panel > .edit-panel > .edit-info > a:hover {
        text-decoration: underline;
    }

    #lep-diff-title {
        font-weight: bold;
    }
    
    #lep-diff-user {
        font-style: italic;
        font-size: 14px;
    }

    #lep-diff-summary {
        font-size: 12px;
        color: hsl(0, 0%, 20%);
    }

    #lep-diff-result {
        font-weight: bold;
    }

    #lep-locked-indicator {
        position: absolute;

        top: 0;
        right: 0;

        margin: 10px;

        color: hsl(0, 0%, 60%);
        font-size: 12px;
    }
    
    /* Navigation */
    #lep > .edits-panel > .navigation {
	    display: flex;
        justify-content: space-between;

	    height: 34px;

    	border-bottom: 1px solid #a2a9b1;
    }
    
    #lep.darkmode > .edits-panel > .navigation {
    	border-bottom: 1px solid hsl(228,4%,25%);
	}

    #lep > .edits-panel > .navigation .button {
	    width: 48px;
	    
	    font-family: monospace;
	    font-weight: bold;
	    text-align: center;
	    line-height: 34px;
	    
	    cursor: pointer;
	    
	    background-color: white;
	    border-right: 1px solid #a2a9b1;
	}
	
    #lep > .edits-panel > .navigation .button.left {
		border-right: none;
		border-left: 1px solid #a2a9b1;
    }
	
    #lep.darkmode > .edits-panel > .navigation .button {
		color: hsl(228,4%,60%);
	    background-color: hsl(228,4%,15%);

	    border-right: 1px solid hsl(228,4%,25%);
	}

    #lep.darkmode > .edits-panel > .navigation .button.left {
		border-right: none;
		border-left: 1px solid hsl(228,4%,25%);
    }

    #lep.darkmode > .edits-panel > .navigation .button.invert > img {
		filter: invert(1);
    }

    #lep > .edits-panel > .navigation .button:hover {
	    background-color: hsl(212, 9%, 95%);
    }
    
    #lep.darkmode > .edits-panel > .navigation .button:hover {
    	color: hsl(228,4%,80%);
    	background-color: hsl(228,4%,22%);
	}

    #lep > .edits-panel > .navigation .button:active {
	    background-color: hsl(212, 5%, 90%);
    }
</style>
<div id="lep">
    <div id="lep-locked-indicator"></div>

    <div class="edits-panel">
    	<div class="navigation">
    		<div onclick="lep_nav_back()" class="button">&lt;</div>
    		<div style="display: flex">
	    		<div onclick="lep_clean_rollbacked()" class="button left"><i style="font-weight: normal">cln</i></div>
	    		<div onclick="lep_show_settings()" class="button invert left">
	    			<img src="https://upload.wikimedia.org/wikipedia/commons/5/58/Ic_settings_48px.svg" style="width: 13px; opacity: 0.75;">
	    		</div>
    		</div>
    	</div>
        <div class="items">
            <div class="blacklist"></div>
            <div class="reds"></div>
            <div class="new"></div>
            <div class="others"></div>
        </div>
    </div>
    <div class="main-panel">
        <div class="actions-panel">
            <div class="actions">
                <div class="buttons-container">
                    <div id="lep-rollback-btn" class="big-button" onclick="lep_rollback()">Откат</div>
                    <div class="vertical-container">
                        <div id="lep-patrol-btn" class="normal-button big disabled" onclick="lep_patrol()">Пат</div>
                        <div id="lep-patrol-btn" class="normal-button big" onclick="lep_diff()">Diff</div>
                    </div>
                </div>
                <div class="undo-container">
                    <div class="buttons">
                        <div class="normal-button small" onclick="lep_undo('bel', this)">БЕЛ</div>
                        <div class="normal-button small" onclick="lep_undo('ukr', this)">НАУКР</div>
                        <div class="normal-button small" onclick="lep_undo('src', this)">АИ?</div>
                        <div class="normal-button small" onclick="lep_undo('nn', this)">Не значимо</div>
                    </div>
                </div>
                <!-- V this should not be an undo-container V -->
                <div class="undo-container" style="align-self: flex-start;">
                	<div class="buttons">
	                    <div id="lep-del-btn" class="normal-button" onclick="lep_del_link()">Удалить</div>
	                    <div id="lep-del-btn-o3" class="normal-button" onclick="lep_del_link('o3')">О3</div>
	                    <div id="lep-del-btn-c5" class="normal-button" onclick="lep_del_link('c5')">C5</div>
                    </div>
                </div>
            </div>
            <!-- <div class="settings-panel">
                <div id="lep-settings-button" class="normal-button" onclick="lep_show_settings()">Настройки</div>
            </div> -->
        </div>
        <div class="edit-panel">
            <div class="edit-info">
                <a target="_blank" id="lep-diff-title"></a>
                <a target="_blank" id="lep-diff-user"></a>
                <span target="_blank" id="lep-diff-summary"></span>
                <a target="_blank" id="lep-diff-result"></a>
            </div>
            <div id="lep-page-html" style="font-size: 0.875em; line-height: 1.6"></div>
            <table class="diff" style="font-size: 14px;">
                <colgroup>
                  <col class="diff-marker">
                  <col class="diff-content">
                  <col class="diff-marker">
                  <col class="diff-content">
                </colgroup>
                <tbody id="lep-diff"></tbody>
            </table>
        </div>
    </div>
</div>
<div id="lep-version"><span>v. ${ LEP_VER }${ window.LEP_DEV ? " dev" : "" }</span> · <a href="/wiki/ОУ:Skmp" target="_blank">Обратная связь</a> · <a href="/wiki/У:Skmp/LEP/info" target="_blank">Про инструмент</a></div>
`;

const lep_query_url = "/api.php?action=query&format=json&list=recentchanges&rcdir=older&rcprop=title%7Cids%7Cflags%7Ccomment%7Coresscores%7Cparsedcomment%7Ctags%7Cuser&rcshow=!bot&rclimit=25&rctype=edit%7Cnew";

var lep_last_time = new Date().toISOString();
var lep_locked = false;

var lep_el_lockedindicator;

var lep_el_btn_patrol;
var lep_el_btn_rollback;

var lep_el_diff_title;
var lep_el_diff_user;
var lep_el_diff_summary;
var lep_el_diff_result;
var lep_el_diff_container;

var lep_el_page_html;

var lep_el_items_blacklist;
var lep_el_items_reds;
var lep_el_items_new;
var lep_el_items_others;

var lep_edits = {};
var lep_blacklisted_users = [];
var lep_curr_edit = -1;

var lep_good_users = [];
var lep_sites = ["ru.wikipedia.org"];

var lep_nav_history = [];
var lep_nav_history_pos = -1;

// Загрузка добросовесных пользователей из localstorage
if(localStorage.hasOwnProperty("lep_good_users")) {
	lep_good_users = localStorage.getItem("lep_good_users").split("|");
}

// Загрузка интервики для отслеживания из localstorage
if(localStorage.hasOwnProperty("lep_sites")) {
	lep_sites = localStorage.getItem("lep_sites").split("|");
}

// Данные кнопок быстрой отмены
var lep_undo_data = {
	bel: {
		buttontext: "БЕЛ",
		summary: "В Википедии принято использовать название «Белоруссия» (см. [[ВП:БЕЛ]])"
	},
	ukr: {
		buttontext: "НАУКР",
		summary: "В Википедии принято использовать форму «На Украине» (см. [[ВП:НАУКР]])"
	},
	src: {
		buttontext: "АИ?",
		summary: "[[ВП:АИ|Источник]]?"
	},
	nn: {
		buttontext: "Не значимо",
		summary: "Не [[ВП:ЗНАЧ|значимо]]"
	}
};

// Настройки
var lep_config = JSON.parse(localStorage.getItem("lep_config")) || {
    ores_min: 0.5,
    ores_max: 0.94,

    display_new: true,
    display_new_suspicious: false,

    tabclose_notify: true,
    
    darkmode: false,

    audio_notify: false,
    audio_notify_volume: 0.33,
    audio_notify_url: ""
};

var lep_tokens = {
	
};

// Валидация настроек
if(lep_config.ores_max < lep_config.ores_min) { lep_config.ores_min = 0.5; lep_config.ores_max = 0.94; }
if(lep_config.ores_min < 0.01 || lep_config.ores_min > 0.94) lep_config.ores_min = 0.5;
if(lep_config.ores_max < 0.01 || lep_config.ores_max > 0.99) lep_config.ores_max = 0.94;

if(!lep_config.audio_notify_volume || lep_config.audio_notify_volume > 1) lep_config.audio_notify_volume = 0.33;

// Звуковое уведомление
var lep_notification_sound = new Audio(lep_config.audio_notify_url || "https://notificationsounds.com/message-tones/appointed-529/download/mp3");
lep_notification_sound.volume = lep_config.audio_notify_volume;

function lep_getCsrfToken(token_type, callback) {
	if(!token_type) token_type = "edit";
	
	if(window.LEP_DEV) console.log("Getting token!", token_type);

	$.getJSON(mw.config.get('wgScriptPath') + `/api.php?action=tokens&format=json&type=${ token_type }`, function (response) {
		const response_token = response.tokens[`${ token_type }token`];
		
		if(response_token) lep_tokens[token_type] = response_token;
		
		if(callback) callback();
	});
}

function lep_apiCall(url, params, csrf_token_type, callback) {
	if(lep_tokens[csrf_token_type]) {
		params.token = lep_tokens[csrf_token_type];
		
		$.ajax({
	        url,
	        type: "POST",
	        crossDomain: true,
	        dataType: "json",
	        data: params,
	        success: function (response) {
		        if(response.error && window.LEP_DEV) console.log(response.error);
			
				if(response.error && response.error.code === "badtoken") {
					lep_getCsrfToken(csrf_token_type, function() {
						lep_apiCall(url, params, csrf_token_type, callback);
					});
				} else {
		    		callback(response);
				}
	        },
	        error: function (xhr, status) {
		        console.log(status);
	    	}
		});
	} else {
		lep_getCsrfToken(csrf_token_type, function() {
			lep_apiCall(url, params, csrf_token_type, callback);
		});
	}
}

// Сохранить настройки
function lep_config_save() {
	// Поля ввода (числовые)
	const inputs_num = document.querySelectorAll('#lep-config-dialog input[type="number"]');
	for(const input of inputs_num) {
		if(input.checkValidity() && input.value !== "") {
			if(input.name === "audio_notify_volume") lep_config[input.name] = parseInt(input.value, 10) / 100;
			else lep_config[input.name] = parseFloat(input.value, 10);
		}
	}
	
	// Поля ввода (текст)
	const inputs_text = document.querySelectorAll('#lep-config-dialog input[type="text"]');
	for(const input of inputs_text) {
		lep_config[input.name] = input.value;
	}
	
	// Сайты
	const input_textarea = document.querySelector('#lep-config-dialog textarea');
	localStorage.setItem("lep_sites", input_textarea.value.replace(/\n/g, "|"));
	lep_sites = input_textarea.value.split("\n");
	
	// Чекбоксы
	const checkboxes = document.querySelectorAll('#lep-config-dialog input[type="checkbox"]');
	for(const checkbox of checkboxes) {
		lep_config[checkbox.name] = checkbox.checked;
	}
	
	// Обновить тёмный режим
	if(lep_config.darkmode) {
		document.getElementById("lep").classList.add("darkmode");

		document.getElementById("mw-panel").style.filter = "invert(1)";
		document.body.style.backgroundColor = "hsl(0, 0%, 15%)";
	} else {
		document.getElementById("lep").classList.remove("darkmode");

		document.getElementById("mw-panel").style.filter = "unset";
		document.body.style.backgroundColor = "unset";
	}
	
	window.localStorage.setItem("lep_config", JSON.stringify(lep_config));

	// Обновить уведомление
	lep_notification_sound = new Audio(lep_config.audio_notify_url || "https://notificationsounds.com/message-tones/appointed-529/download/mp3");
	lep_notification_sound.volume = lep_config.audio_notify_volume;
}

// Навигация назад
function lep_nav_back() {
	let len = lep_nav_history.length;
	
	// История пуста
	if(len === 0) return;
	
	if(lep_nav_history_pos === -1 || lep_nav_history_pos >= len) {
		lep_nav_history_pos = len - 2;
	}
	
	lep_show(lep_nav_history[lep_nav_history_pos], false, false, true);
	
	lep_nav_history_pos -= 1;
}

var lep_stat_clean_undone = 0;

// Очистка отменённых правок
function lep_clean_rollbacked() {
	if(confirm("Вы уверены, что хотите очистить уже отменённые правки?")) {
		let els = document.querySelectorAll("#lep > .edits-panel > .items .item");
		let next_time = 0;
		
		// Каждая правка в левой панеле правок
		for (const el of els) {
		    let id = el.id.split("-", 3)[2];
		    let user = lep_edits[id].user;
		    let pageid = lep_edits[id].pageid;
		
		    setTimeout(() => {
		    	// Запрашиваем у сервера последние правки страницы
		        lep_apiCall(`/w/api.php?action=query&format=json&prop=revisions&pageids=${ lep_edits[id].pageid }&rvprop=comment%7Cuser%7Cids&rvlimit=8&rvendid=${ id }`, {}, "edit", a => {
		            let last_rev = a.query.pages[pageid].revisions[0];
		
		            if(last_rev.user === user) {
						// Последняя правка была сделана подозрительным пользователем => правка не отменена
		                console.log(user, "not rollbacked")
		            } else {
		            	// Кто-то редактировал страницу после подозрительного пользователя
		                for(const rev of a.query.pages[pageid].revisions) {
		                    if(rev.comment.includes(user)) {
		                        if(rev.comment.startsWith("[[ВП:Откат|откат]]") || rev.comment.startsWith("[[ВП:×|отмена]]") || rev.comment.includes("автоматическая отмена")) {
		                    		// В правке после правки подозрительного пользователя упоминается последний и присутствует строка "откат", "отмена", ...
		                            console.log("ROLLBACKED!", rev.comment);
		                            el.remove();
		                            
		                            // Добавить в blacklist
		                            lep_blacklisted_users.push(user);
		                            
		                            lep_stat_clean_undone += 1;

		                            break;
		                        }
		                    }
		                }
		
		                console.log(user, "not rollbacked");
		            }
		        });
		    }, next_time);
		
		    next_time += 500;
		}
	}
}

// Очистить список добросовестных пользователей
function lep_clear_good_users() {
	localStorage.removeItem("lep_good_users");
	lep_good_users = [];
	
	const button = document.getElementById("lep_config_goodusers_clear")
	
	button.innerText = "Готово!";
	
	window.setTimeout(function() {
		button.innerText = "Очистить список добросовестных пользователей";
	}, 1500);
}

// Открыть окно настроек
function lep_show_settings() {
	$("#lep-config-dialog").dialog("open");
}

// Заблокировать обновления (когда курсор нахидится внутри LEP)
function lep_lock() {
    lep_el_lockedindicator.innerHTML = "locked";
    lep_locked = true;
}

// Разблокировать обновления (когда курсор НЕ нахидится внутри LEP)
function lep_unlock() {
    lep_el_lockedindicator.innerHTML = "";
    lep_locked = false;
}

// Удалить выделение правки в левом меню
function lep_deselect() {
    const selected_els = document.querySelectorAll("#lep > .edits-panel > .items .item.selected");

    for(const el of selected_els) {
        el.classList.remove("selected");
    }
}

// Открыть страницу удаления
function lep_del_link(type) {
	if(type === "c5") {
		// Не значимо
		window.open(`https://ru.wikipedia.org/w/index.php?title=${ lep_edits[lep_curr_edit].title }&action=delete&wpReason=[[ВП%3AКБУ%23С5|С5]]%3A нет доказательств энциклопедической значимости (автор [[Служебная:Вклад/${ lep_edits[lep_curr_edit].user }|${ lep_edits[lep_curr_edit].user }]])`);
	} else if(type === "o3") {
		// Вандализм
		window.open(`https://ru.wikipedia.org/w/index.php?title=${ lep_edits[lep_curr_edit].title }&action=delete&wpReason=[[ВП%3AКБУ%23О3|О3]]%3A+страница%2C+созданная+для+[[ВП%3AВандализм|вандализма]] (автор [[Служебная:Вклад/${ lep_edits[lep_curr_edit].user }|${ lep_edits[lep_curr_edit].user }]])`);
	} else {
		// Пустая причина
		window.open(`https://ru.wikipedia.org/w/index.php?title=${ lep_edits[lep_curr_edit].title }&action=delete&wpReason=(автор [[Служебная:Вклад/${ lep_edits[lep_curr_edit].user }|${ lep_edits[lep_curr_edit].user }]])`);
	}
}

// Открыть страницу диффа
function lep_diff() {
    if(lep_curr_edit > 0) window.open(`https://${ lep_edits[lep_curr_edit].site }/w/index.php?diff=${ lep_curr_edit }`);
}

// Патрулирование правки
function lep_patrol() {
	// Отключаем кнопку
    lep_el_btn_patrol.classList.add("disabled");
    lep_el_btn_patrol.innerText = "...";

    // Патрулируем
	lep_apiCall(`https://${ lep_edits[lep_curr_edit].site }/w/api.php?action=review&format=json`, {
    	revid: lep_curr_edit,
    }, "edit", function(response) {
    	// Отпатрулировано
        lep_el_btn_patrol.innerText = "Готово";
	});
}

// Откат правки
function lep_rollback() {
    const rollback_revid = lep_curr_edit;
    const pageid = lep_edits[lep_curr_edit].pageid;
    const user = lep_edits[lep_curr_edit].user;
    const site = lep_edits[lep_curr_edit].site;

	// Добавить пользователя, совершившего правку, в чёрный список этой сессии
	lep_blacklisted_users.push(user);
	
	$.ajax({
        url: `https://${ site }/w/api.php?action=query&format=json`,
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        data: {
	    	prop: "revisions",
	    	pageids: pageid,
	    	rvprop: "ids|user"
        },
        success: function (response) {
	        // Проверяем, или нас не опередили
	        if(response.query.pages[pageid].revisions[0].user === user) {
	        	// Отключаем кнопку отката
	            lep_el_btn_rollback.classList.add("disabled");
	            lep_el_btn_rollback.innerText = "...";
	
	            // Совершаем откат
	        	lep_apiCall(`https://${ site }/w/api.php?action=rollback&format=json`, {
	            	user: lep_edits[lep_curr_edit].user,
	            	title: lep_edits[lep_curr_edit].title
	            }, "rollback", function(rollback_response) {
					// Статус совершённого действия
	            	lep_el_diff_result.innerText = "Откачено";
	                lep_el_diff_result.classList.add("green");
	            	
	        		// Получаем дифф нашей правки
					$.ajax({
				        url: `https://${ site }/w/api.php?action=compare&format=json`,
				        type: "GET",
				        crossDomain: true,
				        dataType: "jsonp",
				        data: {
		                	fromrev: rollback_response.rollback.revid,
		                	torelative: "prev",
		                	prop: "diff"
				        },
				        success: function (rollback_rev_response) {
							// Дифф
		                    lep_el_diff_container.innerHTML = rollback_rev_response.compare["*"];
		
							// Текущая правка
		                    // lep_curr_edit = rollback_rev_response.revid;
		
							// Кнопка отката
						    lep_el_btn_rollback.innerText = "DONE";
		
		                    // Удалить откаченную страницу из левой панели
		                    const left_panel_item = document.getElementById("lep-rev-" + rollback_revid);
		                    if(left_panel_item) left_panel_item.remove();
				        },
				        error: function (xhr, status) {
					        console.log(status);
				    	}
					});
				}, site);
	        } else {
	        	// Статус совершённого действия
	            lep_el_diff_result.innerText = "Ошибка отката. Кажется кто-то опередил.";
				lep_el_diff_result.classList.add("red");
	
	            lep_el_btn_rollback.classList.add("disabled");
	            lep_el_btn_rollback.innerText = "NOPE";
	        }
        },
        error: function (xhr, status) {
	        console.log(status);
    	}
	});
}

// Отмена правки с описанием
function lep_undo(type, el) {
    const undo_revid = lep_curr_edit;
    const pageid = lep_edits[lep_curr_edit].pageid;
    const user = lep_edits[lep_curr_edit].user;
    const site = lep_edits[lep_curr_edit].site;

	if(site !== "ru.wikipedia.org") return;

	// TODO
    $.post(mw.config.get('wgScriptPath') + "/api.php?action=query&format=json", {
    	prop: "revisions",
    	pageids: pageid,
    	rvprop: "ids|user"
    }, function(response) {
    	// Проверяем, или нас не опередили
        if(response.query.pages[pageid].revisions[0].user === user) {
        	// Отключаем кнопку отмены
            el.classList.add("disabled");
            el.innerText = "...";

            // Отмена правки
        	lep_apiCall(`https://${ site }/w/api.php?action=edit&format=json`, {
            	title: lep_edits[lep_curr_edit].title,
            	undo: undo_revid,
            	summary: `[[ВП:×|отмена]] правки ${ undo_revid } участника [[Special:Contribs/${ user }|${ user }]] ([[UT:${ user }|обс.]]) ${ lep_undo_data[type].summary }`
            }, "edit", function(undo_response) {
				// Статус совершённого действия
            	lep_el_diff_result.innerText = "Отменено";
                lep_el_diff_result.classList.add("green");
            	
        		// Получаем дифф нашей правки
                $.post(mw.config.get('wgScriptPath') + "/api.php?action=compare&format=json", {
                	fromrev: undo_response.edit.newrevid,
                	torelative: "prev",
                	prop: "diff"
                }, function(undo_rev_response) {
                    // Дифф
                    lep_el_diff_container.innerHTML = undo_rev_response.compare["*"];
                    
                    // Текущая правка
                    // lep_curr_edit = undo_rev_response.revid;

					// Включаем кнопку отмены обратно
                    el.classList.remove("disabled");
                    el.innerText = lep_undo_data[type].buttontext;

                    // Удалить отменённую страницу из левой панели
                    const left_panel_item = document.getElementById("lep-rev-" + undo_revid);
                    if(left_panel_item) left_panel_item.remove();
                });            	
			});
        } else {
        	// Статус совершённого действия
            lep_el_diff_result.innerText = "Ошибка отмены. Кажется кто-то опередил.";
            lep_el_diff_result.classList.add("red");

            el.innerText = lep_undo_data[type].buttontext;
        }
    });
}

// Показать правку
function lep_show(revid, del_link, new_page, is_from_nav) {
    // Элемент левой панели
    const el = document.getElementById("lep-rev-" + revid);

	// Убираем выделение из левой панели
    lep_deselect();

	const this_edit = lep_edits[revid];

	// Записываем в историю правок
	if(is_from_nav !== true) {
		lep_nav_history.push(revid);
		lep_nav_history_pos = -1;
	}

	if(new_page) {
		lep_el_page_html.innerHTML = "";

		lep_el_diff_container.style.display = "none";
		lep_el_page_html.style.display = "block";
	} else {
		lep_el_diff_container.innerHTML = "";

		lep_el_diff_container.style.display = "contents";
		lep_el_page_html.style.display = "none";
	}

	// Сброс кнопок и прочего
    lep_el_btn_patrol.classList.add("disabled");
    lep_el_btn_patrol.innerText = "Пат";

    lep_el_diff_result.innerText = "";
    lep_el_diff_result.className = "";

    lep_el_btn_rollback.classList.remove("disabled");
    lep_el_btn_rollback.innerText = "Откат";

	// Удалять ли элемент из левой панели
	if(is_from_nav !== true) {
    	if(del_link) el.remove();
    	else el.classList.add("selected");
	}

	// Прверяем, можно ли отпатрулировать
	// TODO globalize
	if(this_edit.site === "ru.wikipedia.org" && !new_page) {
	    $.post(mw.config.get('wgScriptPath') + "/api.php?action=query&format=json", {
	    	titles: this_edit.title,
	    	prop: "flagged|revisions"
	    }, function(response) {
	        if( response.query.pages[this_edit.pageid] &&
	        	response.query.pages[this_edit.pageid].flagged &&
	        	response.query.pages[this_edit.pageid].flagged.stable_revid === response.query.pages[this_edit.pageid].revisions[0].parentid
	          ) {
	            lep_el_btn_patrol.classList.remove("disabled");
	        }
	    });
	}

	if(new_page) {
		// Запрашиваем страницу
		$.ajax({
	        url: `https://${ this_edit.site }/w/api.php?action=parse&format=json`,
	        type: "GET",
	        crossDomain: true,
	        dataType: "jsonp",
	        data: {
				prop: "text|displaytitle",
				oldid: revid
	        },
	        success: function (response) {
				// Название страницы
		        lep_el_diff_title.innerHTML = lep_edits[revid].title;
		        lep_el_diff_title.href = `https://${ this_edit.site }/wiki/${ lep_edits[revid].title}`;
		
				// Пользователь, совершивший правку
		        lep_el_diff_user.innerHTML = lep_edits[revid].user;
		        lep_el_diff_user.href = `https://${ this_edit.site }/wiki/Special:Contributions/${ lep_edits[revid].user }`;
		
				// Описание правки
		        lep_el_diff_summary.innerHTML = lep_edits[revid].parsedcomment;
		
				// Дифф
				if(response.error && response.error.code === "nosuchrevid") {
					lep_el_page_html.innerHTML = "";
		
		            lep_el_diff_result.innerText = "Невозможно получить правку. Возможно, страница была удалена.";
		            lep_el_diff_result.classList.add("red");
				} else {
		        	lep_el_page_html.innerHTML = response.parse.text["*"];
				}
		        
		        // Текущая правка
		        lep_curr_edit = revid;
	        },
	        error: function (xhr, status) {
		        console.log(status);
	    	}
		});
	} else {
		// Запрашиваем правку
		$.ajax({
	        url: `https://${ this_edit.site }/w/api.php?action=compare&format=json`,
	        type: "GET",
	        crossDomain: true,
	        dataType: "jsonp",
	        data: {
		    	fromrev: revid,
		    	torelative: "prev",
		    	prop: "diff|parsedcomment"
	        },
	        success: function (response) {
				// Название страницы
		        lep_el_diff_title.innerHTML = lep_edits[revid].title;
		        lep_el_diff_title.href = `https://${ this_edit.site }/wiki/${ lep_edits[revid].title}`;
		
				// Пользователь, совершивший правку
		        lep_el_diff_user.innerHTML = lep_edits[revid].user;
		        lep_el_diff_user.href = `https://${ this_edit.site }/wiki/Special:Contributions/${ lep_edits[revid].user }`;
		
				// Описание правки
		        lep_el_diff_summary.innerHTML = lep_edits[revid].parsedcomment;
		
				// Дифф
				if(response.error && response.error.code === "nosuchrevid") {
					lep_el_diff_container.innerHTML = "";
		
		            lep_el_diff_result.innerText = "Невозможно получить правку. Возможно, страница была удалена.";
		            lep_el_diff_result.classList.add("red");
				} else {
		        	lep_el_diff_container.innerHTML = response.compare["*"];
				}
		        
		        // Текущая правка
		        lep_curr_edit = revid;
	        },
	        error: function (xhr, status) {
		        console.log(status);
	    	}
		});
	}
}

// Получить правки (раз в 5 секунд)
function lep_getEdits(site) {
	$.ajax({
        url: `https://${ site }/w${ lep_query_url }&rcend=${ encodeURIComponent(lep_last_time) }&rcstart=${ encodeURIComponent(new Date((new Date()) - 10000).toISOString()) }`,
        type: "GET",
        crossDomain: true,
        dataType: "jsonp",
        success: async function (response) {
            for(const edit of response.query.recentchanges) {
		    	edit.site = site;
		    	
		    	// Пропустить правку, если она уже есть в lep_edits с готовой оценкой ORES
		    	if(lep_edits[edit.revid]) {
		    		if(lep_edits[edit.revid].oresscores.length !== 0) continue;
		        	if(lep_edits[edit.revid].oresscores.length === 0 && edit.oresscores.length === 0) continue;
		    	}
		    	
		    	// Пропустить, если новая страница от добросовестного участника
		    	if(edit.type === "new") {
		    		if(lep_good_users.includes(edit.user)) {
		    			if(window.LEP_DEV) console.log("skipping good user: ", edit.user);
		    			
		    			continue;
		        	} else {
						$.ajax({
					        url: `https://${ site }/w/api.php?action=query&format=json`,
					        type: "GET",
					        crossDomain: true,
					        dataType: "jsonp",
					        data: {
								list: "users",
								usprop: "groups",
								ususers: edit.user
					        },
					        success: function (user_response) {
								const user_groups = user_response.query.users[0].groups;
								if(user_groups !== undefined) {
									if(user_groups.includes("editor") ||
									   user_groups.includes("autoeditor")
									) {
										if(window.LEP_DEV) console.log("adding good user from " + site + " to the list: ", edit.user);
										
									  	lep_good_users.push(edit.user);
			
										if(!localStorage.hasOwnProperty("lep_good_users")) {
											localStorage.setItem("lep_good_users", "Jimbo Wales");
										}
			
									  	const new_list = localStorage.getItem("lep_good_users")  + "|" + edit.user;
									  	localStorage.setItem("lep_good_users", new_list);
									}
								}
					        },
					        error: function (xhr, status) {
						        console.log(status);
					    	}
						});
		        	}
		    	}
		    	
		    	lep_edits[edit.revid] = edit;
		    	
				// ORES score
				let score;
				let ores_NA = false;
				let force_show = false;
				
				if(edit.oresscores && edit.oresscores.length !== 0) {
		        	score = edit.oresscores.damaging.true;
				} else {
					ores_NA = true;
					
					await new Promise(function(resolve) {
						$.ajax({
					        url: `https://${ site }/w/api.php?action=query&format=json`,
					        type: "GET",
					        crossDomain: true,
					        dataType: "jsonp",
					        data: {
								list: "users",
								usprop: "groups",
								ususers: edit.user
					        },
					        success: function (user_response) {
					        	const user_groups = user_response.query.users[0].groups;
								if(user_groups !== undefined) {
									if(!user_groups.includes("editor") &&
									   !user_groups.includes("autoeditor") &&
									   !user_groups.includes("autoreview")
									) {
										force_show = true;
									}
								} else {
									force_show = true;
								}
								
								resolve();
					        },
					        error: function (xhr, status) {
						        console.log(status);
					    	}
						});
					});
					score = 0;
				}
		
				if(window.LEP_DEV) console.log(edit.revid, score, force_show, edit.user, site);
		
				// Новый элемент левой панели
		        let new_item = document.createElement("div");
		        new_item.id = "lep-rev-" + edit.revid;
		        new_item.className = "item";
		
				if(edit.type === "new") {
		        	new_item.onclick = () => { lep_show(edit.revid, true, true) };
				} else {
		        	new_item.onclick = () => { lep_show(edit.revid, true) };
				}
		
		        new_item.innerHTML += '<div class="title"><span>[' + site.split(".")[0] + ']</span> ' + edit.title
		            + '</div><div class="score ' + ((score >= lep_config.ores_min || force_show) ? ' red' : (edit.type === 'new' ? ' orange' : '')) + '">' + (edit.type === 'new' ? 'new' : (force_show ? "N/A" : (score || "???"))) + '</div>';
		
				let in_blacklist = lep_blacklisted_users.includes(edit.user);
		
				// Определяем, записывать ли в левое меню
				if(in_blacklist) {
					// Пользователя уже откатывали
					lep_el_items_blacklist.appendChild(new_item);
					
					if(lep_config.audio_notify) lep_notification_sound.play();
					if(!lep_locked) lep_show(edit.revid);
				} else if(force_show || (score >= lep_config.ores_min && score <= lep_config.ores_max)) {
					// ORES score выше порога
		            lep_el_items_reds.appendChild(new_item);
		            
		            if(lep_config.audio_notify) lep_notification_sound.play();
		            if(!lep_locked) lep_show(edit.revid);
		        } else if(lep_config.display_new && edit.type === "new"
		        && !/^(Обсуждение|Обсуждение участника|Категория):+/.test(edit.title)) {
					// Новая страница
					if(lep_config.display_new_suspicious) {
						// Отображать как подозрительную правку
		                lep_el_items_reds.appendChild(new_item);
		                
		                if(lep_config.audio_notify) lep_notification_sound.play();
		            	if(!lep_locked) lep_show(edit.revid, false, true);
					} else {
						lep_el_items_new.appendChild(new_item);
					}
				} else if(!score && !ores_NA) {
		        	// ORES score ещё не готов
		            lep_el_items_others.appendChild(new_item);
		        }
	    	}
	
	    	lep_last_time = new Date((new Date()) - 10000).toISOString();
	    },
	    error: function (xhr, status) {
	        console.log(status);
	    }
    });
}

// Иньекция HTML
function lep_inject() {
	// @TODO
	// Загрузка стилей
    let mediawiki_css = document.createElement("link");
    mediawiki_css.href = "https://www.mediawiki.org/w/load.php?modules=mediawiki.legacy.shared|mediawiki.diff.styles&only=styles";
    mediawiki_css.rel = "stylesheet";

    document.head.appendChild(mediawiki_css);

	// Удаление некоторых элементов интерфейса mediawiki
	document.getElementById("mw-head").remove();
	document.getElementById("mw-head-base").remove();
	document.getElementById("mw-page-base").remove();
	document.getElementById("footer").remove();
	
	const content_el = document.getElementById("content");
	content_el.style.borderColor = "#a2a9b1";
	content_el.style.padding = "0";
	content_el.style.height = "100%";

	// Изменение названия вкладки на "(LEP) Участник:..."
	window.document.title = "(LEP) " + window.document.title;

	// Иньекция HTML
    document.querySelector("#content.mw-body").innerHTML = lep_html;

	// Ивенты для блокировки и разблокировки обновлений
    document.getElementById("lep").addEventListener("mouseenter", lep_lock);
    document.getElementById("lep").addEventListener("mouseleave", lep_unlock);

	// Уведомление о закрытии вкладки
	if(lep_config.tabclose_notify) {
		window.onbeforeunload = function(e) {
		    e = e || window.event;
		
		    if(e) e.returnValue = '1';
		    return '1';
		};
	}
	
	// Тёмный режим
	if(lep_config.darkmode) {
		document.getElementById("lep").classList.add("darkmode");

		document.getElementById("mw-panel").style.filter = "invert(1)";
		document.body.style.backgroundColor = "hsl(0, 0%, 15%)";
	}

	// Элементы интерфейса
    lep_el_lockedindicator = document.getElementById("lep-locked-indicator");

    lep_el_btn_patrol = document.getElementById("lep-patrol-btn");
    lep_el_btn_rollback = document.getElementById("lep-rollback-btn");

    lep_el_diff_title = document.getElementById("lep-diff-title");
    lep_el_diff_user = document.getElementById("lep-diff-user");
    lep_el_diff_summary = document.getElementById("lep-diff-summary");
    lep_el_diff_result = document.getElementById("lep-diff-result");
    lep_el_diff_container = document.getElementById("lep-diff");

	lep_el_page_html = document.getElementById("lep-page-html");

	lep_el_items_blacklist = document.querySelector("#lep > .edits-panel > .items > .blacklist");
    lep_el_items_reds = document.querySelector("#lep > .edits-panel > .items > .reds");
    lep_el_items_new = document.querySelector("#lep > .edits-panel > .items > .new");
    lep_el_items_others = document.querySelector("#lep > .edits-panel > .items > .others");
}

mw.loader.using('mediawiki.util').done(function() {
	// Ссылка в левом меню интерфейса MediaWiki
	var listItem = document.querySelector("#p-tb > div > ul");
	if(listItem)listItem.innerHTML += `<li id="t-lep"><a href="/wiki/Участник:Skmp/LEP" title="Запустить LEP [alt-shift-e]" accesskey="e">Запустить LEP</a></li>`;
    
    if(mw.config.get('wgPageName') === "Участник:Skmp/LEP") {
    	// Запуск инструмента
        lep_inject();

        // Создаём интервал новых правок
        setInterval(function() {
        	for(const site of lep_sites) {
        		lep_getEdits(site);
        	}
        }, 5000);
    }
});

// Окно настроек
mw.loader.using( 'jquery.ui', function() {
	$(`<div id="lep-config-dialog">\
<fieldset name="filtration"><legend>Фильтрация правок</legend>\
<p style="color: hsl(0, 0%, 40%); font-style: italic; font-size: 11px; margin: 2px 0 10px 0">Правка будет отображена, если её оценка <a target="_blank" href="https://www.mediawiki.org/wiki/ORES"><i>ORES</i></a> удволитворит критериям ниже.</p>\
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0">\
    <span>Минимальное значение <small style="color: gray">(0.5)</small></span>\
    <input value="${ lep_config.ores_min }" style="width: 50px" name="ores_min" type="number" min="0.01" max="1" step="0.01">\
</div>\
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0">\
    <span>Максимальное значение <small style="color: gray">(0.95)</small></span>\
    <input value="${ lep_config.ores_max }" style="width: 50px" name="ores_max" type="number" min="0.01" max="1" step="0.01">\
</div>\
<div style="display: flex; align-items: center">\
    <input ${ lep_config.display_new ? 'checked' : "" } style="margin: 0 5px 0 0" type="checkbox" name="display_new">\
    <span>Отображать создание новых страниц</span>\
</div>\
<div style="display: flex; align-items: center; margin: 5px 0 0 10px">\
    <input ${ lep_config.display_new_suspicious ? 'checked' : "" } style="margin: 0 5px 0 0" type="checkbox" name="display_new_suspicious">\
    <span>Отображать как подозрительные</span>\
</div>\
</fieldset>\
<fieldset name="notification"><legend>Звуковое уведомление</legend>\
<div style="display: flex; align-items: center; margin: 4px 0">\
    <input ${ lep_config.audio_notify ? 'checked' : "" } style="margin: 0 5px 0 0" type="checkbox" name="audio_notify">\
    <span>Включить звуковые уведомления</span>\
</div>\
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0">\
    <span>Громкость уведомления <small style="color: gray">(1% — 100%)</small></span>\
    <input value="${ lep_config.audio_notify_volume * 100 }" style="width: 50px" name="audio_notify_volume" type="number" min="1" max="100" step="1">\
</div>\
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0">\
    <span>Ссылка на аудиофайл <small style="color: gray">(<a target="_blank" href="https://notificationsounds.com/notification-sounds">библиотека</a>)</small></span>\
    <input value="${ lep_config.audio_notify_url || '' }" style="width: 150px" name="audio_notify_url" type="text">\
</div>\
<p style="color: hsl(0, 0%, 40%); font-style: italic; font-size: 11px; margin: 10px 0 0 0">Ссылку на пользовательский аудиофайл указывать не обязательно.</p>\
</fieldset>\
<fieldset name="other"><legend>Прочее</legend>\
<div style="display: flex; align-items: center; margin: 4px 0">\
    <input ${ lep_config.tabclose_notify ? 'checked' : "" } style="margin: 0 5px 0 0" type="checkbox" name="tabclose_notify">\
    <span>Предупреждать о закрытии вкладки</span>\
</div>\
<!-- Включить darkmode. display should be flex -->\
<div style="display: none; align-items: center; margin: 4px 0">\
    <input ${ lep_config.darkmode ? 'checked' : "" } style="margin: 0 5px 0 0" type="checkbox" name="darkmode">\
    <span>Тёмный режим</span>\
</div>\
<button style="margin-top: 4px" id="lep_config_goodusers_clear" onclick="lep_clear_good_users()">Очистить список добросовестных пользователей</button>\
</fieldset>\

<fieldset name="sites_set"><legend>Сайты (WIP)</legend>\
<div style="margin: 4px 0">\
	<span>Список сайтов для слежения (разделять новой строкой)</span>\
    <textarea style="margin-top: 5px; width: 100%; max-width: 100%; resize: none" rows="5" name="sites_list">${ lep_sites.join("\n") }</textarea>\
</div>\
</fieldset>\
`)
	.dialog({
	    title: "Настройки LEP",
	    closeOnEscape: true,
	    autoOpen: false,
	    resizable: false,
		width: 450,
	    dialogClass: "lep-config-dialog-root",
	    buttons: [{
	    	text: "Сохранить",
	    	click: function() {
		        lep_config_save();
		        $( this ).dialog( "close" );
	    	}
	    }]
	});
});