1(function() { 2 'use strict'; 3 function escapeHtml(s) { 4 return String(s == null ? '' : s).replace(/[&<>"']/g, (function(c) { 5 return { 6 '&': '&', 7 '<': '<', 8 '>': '>', 9 '"': '"', 10 "'": ''' 11 }[c]; 12 })); 13 } 14 function appsIcon(file) { 15 if (typeof window.assetUrl === 'function') return window.assetUrl(file); 16 return (window.APP_BASE || '/app/') + 'public/' + file; 17 } 18 function fallbackAppIcon() { 19 return appsIcon('img/svg/app-default.svg'); 20 } 21 function withPulse(html, selector) { 22 if (!selector) return html; 23 try { 24 var tpl = document.createElement('div'); 25 tpl.innerHTML = html; 26 var target = tpl.querySelector(selector); 27 if (target) target.classList.add('is-pulse'); 28 return tpl.innerHTML; 29 } catch (e) { 30 return html; 31 } 32 } 33 function pickDemoKey() { 34 var keys = window.AuthModule && window.AuthModule.vpnKeys || []; 35 if (Array.isArray(keys)) { 36 for (var i = 0; i < keys.length; i++) { 37 var k = keys[i]; 38 if (k && (k.protocol || '').toLowerCase() === 'vless') return k; 39 } 40 } 41 return makeFakeVlessKey(); 42 } 43 function makeFakeVlessKey() { 44 var nowSec = Math.floor(Date.now() / 1e3); 45 return { 46 id: 'demo', 47 name: 'demo-aid-vless', 48 username: 'demo-aid-vless', 49 cstname: 'Ðемо-клÑÑ', 50 sub_link: '', 51 subscription_url: '', 52 pay_end_time: nowSec + 24 * 86400, 53 expires_at: nowSec + 24 * 86400, 54 status: 'active', 55 protocol: 'vless', 56 clients_count: 1, 57 addons: [], 58 location: null, 59 is_v2: true 60 }; 61 } 62 function detectOS() { 63 try { 64 if (window.OSDetection && typeof window.OSDetection.detect === 'function') { 65 var os = window.OSDetection.detect(); 66 if (os === 'macos') return 'macOS'; 67 if (os === 'windows') return 'Windows'; 68 if (os === 'ios') return 'iOS'; 69 return 'Android'; 70 } 71 } catch (e) {} 72 return 'iOS'; 73 } 74 function appsForOS(osLabel) { 75 try { 76 var data = window.getVpnAppsData ? window.getVpnAppsData() : null; 77 var key = osLabel === 'Windows' ? 'Windows11' : osLabel === 'macOS' ? 'MacOS' : osLabel; 78 var list = data && data[key] || []; 79 list = list.slice().sort((function(a, b) { 80 var ar = a.badge === 'recommended' || a.like ? -1 : 0; 81 var br = b.badge === 'recommended' || b.like ? -1 : 0; 82 return ar - br; 83 })); 84 return list.slice(0, 3); 85 } catch (e) { 86 return []; 87 } 88 } 89 function badgeOf(app) { 90 if (!app) return null; 91 if (app.badge === 'recommended' || app.like === true) return { 92 cls: 'recommended', 93 text: 'Рек' 94 }; 95 if (app.badge === 'pro') return { 96 cls: 'pro', 97 text: 'Pro' 98 }; 99 if (app.badge === 'alternative') return { 100 cls: 'alternative', 101 text: 'ÐлÑÑ' 102 }; 103 return null; 104 } 105 var MOCKUPS = { 106 keyCard: function(opts) { 107 var pulseTarget = opts && opts.highlight || null; 108 var pulseSelector = null; 109 if (pulseTarget === 'manage') pulseSelector = '.tariff-button--manage'; else if (pulseTarget === 'renew') pulseSelector = '.tariff-button:not(.tariff-button--manage):not(.tariff-button--delete)'; 110 var key = pickDemoKey(); 111 if (key && typeof window.createKeyCard === 'function') { 112 try { 113 var realHtml = window.createKeyCard(key); 114 return '<div class="vpnst-mock vpnst-mock-realkey">' + withPulse(realHtml, pulseSelector) + '</div>'; 115 } catch (e) {} 116 } 117 return '' + '<div class="vpnst-mock vpnst-mock-keycard">' + '<div class="vpnst-mock-keycard__protocol">VLESS</div>' + '<span class="vpnst-mock-keycard__status">ÐкÑивен</span>' + '<div class="vpnst-mock-keycard__name">Ðой клÑÑ</div>' + '<div class="vpnst-mock-keycard__id">#5f3a</div>' + '<div class="vpnst-mock-keycard__time">оÑÑалоÑÑ 24 днÑ</div>' + '<div class="vpnst-mock-keycard__actions">' + '<button class="vpnst-mock-keycard__action ' + (pulseTarget === 'manage' ? 'is-pulse' : '') + '">Ðой клÑÑ</button>' + '<button class="vpnst-mock-keycard__action vpnst-mock-keycard__action--ghost ' + (pulseTarget === 'renew' ? 'is-
117pulse' : '') + '">ÐÑодлиÑÑ</button>' + '</div>' + '</div>'; 118 }, 119 appsGrid: function(opts) { 120 var activeOs = opts && opts.os || detectOS(); 121 var noBadges = !!(opts && opts.noBadges); 122 var oss = [ 'Android', 'iOS', 'Windows', 'macOS' ]; 123 var btns = ''; 124 for (var i = 0; i < oss.length; i++) { 125 btns += '<button class="toggle-switch__btn' + (oss[i] === activeOs ? ' toggle-switch__btn--active' : '') + '">' + oss[i] + '</button>'; 126 } 127 var apps = appsForOS(activeOs); 128 if (!apps.length) { 129 apps = [ { 130 name: 'Happ', 131 image: 'img/external/happ-icon.webp', 132 badge: 'recommended' 133 }, { 134 name: 'V2RayTun', 135 image: 'img/external/v2raytun-icon.webp', 136 badge: 'alternative' 137 } ]; 138 } 139 var iconsHtml = ''; 140 for (var j = 0; j < apps.length; j++) { 141 var app = apps[j]; 142 var b = noBadges ? null : badgeOf(app); 143 var pulse = j === 0 ? ' is-pulse' : ''; 144 iconsHtml += '<div class="vpn-app-icon' + (b ? ' vpn-app-icon--' + b.cls : '') + pulse + '">' + (b ? '<div class="vpn-app-badge vpn-app-badge--' + b.cls + '">' + b.text + '</div>' : '') + '<img src="' + appsIcon(app.image || 'img/svg/app-default.svg') + '" ' + 'alt="' + escapeHtml(app.name) + '" class="vpn-app-icon__image" ' + 'onerror="this.src=\'' + fallbackAppIcon() + '\'" />' + '<div class="vpn-app-icon__name">' + escapeHtml(app.name) + '</div>' + '</div>'; 145 } 146 return '' + '<div class="vpnst-mock vpnst-mock-apps-real">' + '<div class="toggle-switch">' + '<div class="toggle-switch__bg">' + btns + '</div>' + '</div>' + '<div class="vpn_app_icons">' + iconsHtml + '</div>' + '</div>'; 147 }, 148 installFlow: function() { 149 return MOCKUPS._flow({ 150 variant: 'install' 151 }); 152 }, 153 addKeyFlow: function() { 154 return MOCKUPS._flow({ 155 variant: 'addkey'
156 }); 157 }, 158 _flow: function(opts) { 159 var variant = opts && opts.variant || 'install'; 160 var iconUrl = appsIcon('img/external/happ-icon.webp'); 161 var fallback = fallbackAppIcon(); 162 var imgErr = ' onerror="this.src=\'' + fallback + '\'"'; 163 var appsHtml = MOCKUPS.appsGrid({ 164 noBadges: true 165 }); 166 var appsBlock = '<div class="vpnst-mock-flow__apps">' + appsHtml + '</div>'; 167 var sheet = '' + '<div class="vpnst-mock-flow__sheet">' + '<div class="vpnst-mock-flow__sheet-row">' + '<img src="' + iconUrl + '" alt="" class="vpnst-mock-flow__sheet-icon"' + imgErr + ' />' + '<div class="vpnst-mock-flow__sheet-text">' + '<div class="vpnst-mock-flow__sheet-name">Happ</div>' + '<div class="vpnst-mock-flow__sheet-meta">VPN-клиенÑ</div>' + '</div>' + '</div>' + '<div class="vpnst-mock-flow__sheet-buttons">' + '<button type="button" class="vpnst-mock-flow__sheet-btn vpnst-mock-flow__sheet-btn--blue">УÑÑановиÑÑ</button>' + '<button type="button" class="vpnst-mock-flow__sheet-btn vpnst-mock-flow__sheet-btn--gray">ÐобавиÑÑ ÐºÐ»ÑÑ</button>' + '</div>' + '</div>'; 168 var installSuccessSvg = '<svg class="vpnst-mock-flow__installing-success-icon" viewBox="0 0 16 16" aria-hidden="true">' + '<path fill="none" stroke="currentColor" stroke-width="2.4" ' + 'stroke-linecap="round" stroke-linejoin="round" d="M3.5 8.5 6.7 11.7 12.7 5"/>' + '</svg>'; 169 var installFinal = variant === 'install' ? '<div class="vpnst-mock-flow__installing">' + '<div class="vpnst-mock-flow__installing-icon">' + '<img src="' + iconUrl + '" alt=""' + imgErr + ' />' + '</div>' + '<div class="vpnst-mock-flow__installing-bar"><i></i></div>' + '<div class="vpnst-mock-flow__installing-success" aria-hidden="true">' + installSuccessSvg + '<span class="vpnst-mock-flow__installing-success-text">ÐÑиложение ÑÑÑановлено</span>' + '</div>' + '</div>' : ''; 170 var addKeyFinal = ''; 171 if (variant === 'addkey') { 172 var locations = [ { 173 flag: 'ð©ðª', 174 name: 'Germany', 175 active: true 176 }, { 177 flag: 'ð³ð±', 178 name: 'Netherlands', 179 active: false 180 }, { 181 flag: 'ð¸ðª', 182 name: 'Sweden', 183 active: false 184 } ]; 185 var checkSvg = '<svg viewBox="0 0 16 16" aria-hidden="true">' + '<path fill="none" stroke="currentColor" stroke-width="2.4" ' + 'stroke-linecap="round" stroke-linejoin="round" ' + 'd="M3.5 8.5 6.7 11.7 12.7 5"/>' + '</svg>'; 186 var locsHtml = ''; 187 for (var li = 0; li < locations.length; li++) { 188 var L = locations[li]; 189 locsHtml += '<div class="vpnst-mock-flow__happ-loc' + (L.active ? ' vpnst-mock-flow__happ-loc--active' : '') + '"' + ' style="--li:' + li + '">' + '<span class="vpnst-mock-flow__happ-loc-flag">' + L.flag + '</span>' + '<span class="vpnst-mock-flow__happ-loc-name">' + escapeHtml(L.name) + '</span>' + '<span class="vpnst-mock-flow__happ-loc-check" aria-label="добавлено">' + checkSvg + '</span>' + '</div>'; 190 } 191 addKeyFinal = '<div class="vpnst-mock-flow__happ">' + '<div class="vpnst-mock-flow__happ-header">' + '<img src="' + iconUrl + '" alt="" class="vpnst-mock-flow__happ-logo"' + imgErr + ' />' + '<div class="vpnst-mock-flow__happ-title">Happ</div>' + '<div class="vpnst-mock-flow__happ-sub">ÐлÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½</div>' + '</div>' + '<div class="vpnst-mock-flow__happ-list">' + locsHtml + '</div>' + '</div>'; 192 } 193 var rootCls = 'vpnst-mock vpnst-mock-flow vpnst-mock-flow--' + variant; 194 return '<div class="' + rootCls + '">' + appsBlock + sheet + installFinal + addKeyFinal + '</div>'; 195 }, 196 manageToggle: function(opts) { 197 var which = opts && opts.tab || 'change'; 198 var u = which === 'manage' ? ' toggle-switch__btn--active is-pulse' : ''; 199 var c = which === 'change' ? ' toggle-switch__btn--active is-pulse' : ''; 200 var indicatorPos = which === 'manage' ? 'left' : 'right'; 201 return '' + '<div class="vpnst-mock vpnst-mock-managetoggle">' + '<div class="toggle-switch">' + '<div class="toggle-switch__bg">' + '<div class="toggle-switch__indicator vpnst-mt-indicator vpnst-mt-indicator--' + indicatorPos + '"></div>' + '<button class="toggle-switch__btn' + u + '">УпÑавление</button>' + '<button class="toggle-switch__btn' + c + '">Смена ÑаÑиÑа</button>' + '</div>' + '</div>' + '<div class="vpnst-mock-managetoggle__caption">' + 'ÐнÑÑÑи каÑÑоÑки ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеклÑÑиÑеÑÑ Ð½Ð° Ð²ÐºÐ»Ð°Ð´ÐºÑ <b>«Смена ÑаÑиÑа»</b>.' + '</div>' + '</div>'; 202 }, 203 tariffChangeUI: function() { 204 function stack(items) { 205 var inner = ''; 206 for (var i = 0; i < items.length; i++) { 207 inner += '<span class="vpnst-tc-val vpnst-tc-val--' + items[i].cls + '">' + escapeHtml(items[i].text) + '</span>'; 208 } 209 return '<span class="vpnst-tc-stack">' + inner + '</span>'; 210 } 211 var deviceCount = stack([ { 212 cls: 'a', 213 text: '3' 214 }, { 215 cls: 'bc', 216 text: '4' 217 } ]); 218 var newTerm = stack([ { 219 cls: 'a', 220 text: '14д' 221 }, { 222 cls: 'b', 223 text: '9д' 224 }, { 225 cls: 'c', 226 text: '5д' 227 } ]); 228 return '' + '<div class="vpnst-mock vpnst-mock-tariffchange">' + '<div class="vpnst-tc-card">' + '<div class="clients-slider-container">' + '<div class="clients-slider-header">' + '<span class="clients-slider-label">ÐолиÑеÑÑво ÑÑÑÑойÑÑв</span>' + '<span class="clients-slider-value">' + deviceCount + '</span>' + '</div>' + '<div class="clients-slider-wrapper">' + '<div class="clients-slider-track">' + '<div class="clients-slider-fill vpnst-tc-fill"></div>' + '</div>' + '<div class="vpnst-tc-thumb"></div>' + '</div>' + '</div>' + '<div class="vpnst-tc-divider"></div>' + '<div class="addon-item">' + '<div class="addon-toggle">' + '<div class="addon-toggle-track vpnst-tc-toggle-track"></div>' + '<div class="addon-toggle-thumb vpnst-tc-toggle-thumb"></div>' + '</div>' + '<div class="addon-info">' + '<div class="addon-name">ÐелÑй ÑпиÑок</div>' + '<div class="addon-desc">СайÑÑ Ð² Ð¾Ð±Ñ Ð¾Ð´ VPN, Ñ Ð¾Ð´ÑÑ Ð½Ð°Ð¿ÑÑмÑÑ</div>' + '</div>' + '<div class="addon-price">+50â½</div>' + '</div>' + '<div class="vpnst-tc-divider"></div>' + '<div class="vpn-time-recalc-row">' + '<div class="vpn-time-recalc-col">' + '<div class="vpn-time-recalc-label">ТекÑÑий ÑÑок</div>' + '<div class="vpn-time-recalc-value vpn-time-recalc-value--neutral">24д</div>' + '</div>' + '<div class="vpn-time-recalc-arrow">â</div>' + '<div class="vpn-time-recalc-col">' + '<div class="vpn-time-recalc-label">ÐовÑй ÑÑок</div>' + '<div class="vpn-time-recalc-value vpn-time-recalc-value--negative">' + newTerm + '</div>' + '</div>' + '</div>' + '<button class="button-blue-primary vnmk-button vpnst-tc-button" type="button">ÐзмениÑÑ ÑаÑиÑ</button>' + '</div>' + '</div>'; 229 }, 230 renewUI: function() { 231 function rnStack(items) { 232 var inner = ''; 233 for (var i = 0; i < items.length; i++) { 234 inner += '<span class="vpnst-tc-val vpnst-rn-val--' + items[i].cls + '">' + items[i].text + '</span>'; 235 } 236 return '<span class="vpnst-tc-stack">' + inner + '</span>'; 237 } 238 function priceVal(num) { 239 return escapeHtml(num) + '<i class="vpnst-rn-cur">â½</i>'; 240 } 241 var amount = rnStack([ { 242 cls: 'a', 243 text: priceVal('199') 244 }, { 245 cls: 'b', 246 text: priceVal('597') 247 }, { 248 cls: 'c', 249 text: priceVal('1075') 250 }, { 251 cls: 'd', 252 text: priceVal('2030') 253 } ]); 254 var oldPrice = rnStack([ { 255 cls: 'a', 256 text: '' 257 }, { 258 cls: 'b', 259 text: '' 260 }, { 261 cls: 'c', 262 text: priceVal('1194') 263 }, { 264 cls: 'd', 265 text: priceVal('2388') 266 } ]); 267 var period = rnStack([ { 268 cls: 'a',
269 text: escapeHtml('1 меÑ') 270 }, { 271 cls: 'b', 272 text: escapeHtml('3 меÑ') 273 }, { 274 cls: 'c', 275 text: escapeHtml('6 меÑ') 276 }, { 277 cls: 'd', 278 text: escapeHtml('12 меÑ') 279 } ]); 280 var discountText = rnStack([ { 281 cls: 'c', 282 text: escapeHtml('-10% за 6 меÑ') 283 }, { 284 cls: 'd', 285 text: escapeHtml('-15% за 12 меÑ') 286 } ]); 287 return '' + '<div class="vpnst-mock vpnst-mock-renew">' + '<div class="vpnst-rn-card">' + '<div class="toggle-switch">' + '<div class="toggle-switch__bg">' + '<div class="toggle-switch__indicator vpnst-rn-indicator"></div>' + '<button type="button" class="toggle-switch__btn vpnst-rn-btn vpnst-rn-btn--a">1 меÑ</button>' + '<button type="button" class="toggle-switch__btn vpnst-rn-btn vpnst-rn-btn--b">3 меÑ</button>' + '<button type="button" class="toggle-switch__btn vpnst-rn-btn vpnst-rn-btn--c">6 меÑ</button>' + '<button type="button" class="toggle-switch__btn vpnst-rn-btn vpnst-rn-btn--d">12 меÑ</button>' + '</div>' + '</div>' + '<div class="vpnst-tc-divider"></div>' + '<div class="vpnst-rn-summary">' + '<div class="purchase-bar">' + '<div class="purchase-bar__info">' + '<div class="purchase-bar__price">' + '<span class="purchase-bar__amount">' + amount + '</span>' + '<span class="purchase-bar__old">' + oldPrice + '</span>' + '</div>' + '<div class="purchase-bar__details">' + '<span>VLESS</span>' + '<span class="purchase-bar__dot">â¢</span>' + '<span>' + period + '</span>' + '</div>' + '</div>' + '</div>' + '<div class="vpnst-rn-discount">' + discountText + '</div>' + '</div>' + '<button class="button-blue-primary vnmk-button vpnst-rn-button" type="button">ÐÑодлиÑÑ</button>' + '</div>' + '</div>'; 288 }, 289 renewSuccess: function() { 290 return '' + '<div class="vpnst-mock vpnst-mock-renewsuccess">' + '<div class="vpnst-mock-renewsuccess__icon">' + '<svg viewBox="0 0 24 24" aria-hidden="true">' + '<path d="M5 12.5 L10 17.5 L19 7"/>' + '</svg>' + '</div>' + '<div class="vpnst-mock-renewsuccess__title">ÐоÑово!</div>' + '<div class="vpnst-mock-renewsuccess__sub">VPN клÑÑ ÑÑпеÑно пÑодлÑн</div>' + '<div class="vpnst-mock-renewsuccess__balance">' + 'СпиÑано Ñ Ð±Ð°Ð»Ð°Ð½Ñа AID: <b>1 075 â½</b>' + '</div>' + '</div>'; 291 } 292 }; 293 var BASE_BOTTOM = '#0b0d10'; 294 var THEMES = { 295 blue: { 296 gradTop: '#3b82f6', 297 gradBottom: BASE_BOTTOM 298 }, 299 indigo: { 300 gradTop: '#6366f1', 301 gradBottom: BASE_BOTTOM 302 }, 303 violet: { 304 gradTop: '#a855f7', 305 gradBottom: BASE_BOTTOM 306 }, 307 magenta: { 308 gradTop: '#d946ef', 309 gradBottom: BASE_BOTTOM 310 }, 311 amber: { 312 gradTop: '#f59e0b', 313 gradBottom: BASE_BOTTOM 314 }, 315 green: { 316 gradTop: '#10b981', 317 gradBottom: BASE_BOTTOM 318 }, 319 teal: { 320 gradTop: '#14b8a6', 321 gradBottom: BASE_BOTTOM 322 } 323 }; 324 var FA_ICONS = { 325 install: '<svg viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M144 480C64.5 480 0 415.5 0 336c0-62.8 40.2-116.2 96.2-135.9c-.1-2.7-.2-5.4-.2-8.1c0-88.4 71.6-160 160-160c59.3 0 111 32.2 138.7 80.2C409.9 102 428.3 96 448 96c53 0 96 43 96 96c0 12.2-2.3 23.8-6.4 34.6C596 238.4 640 290.1 640 352c0 70.7-57.3 128-128 128H144zm79-167l72 72c9.4 9.4 24.6 9.4 33.9 0l72-72c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-31 31V224c0-13.3-10.7-24-24-24s-24 10.7-24 24v86.1l-31-31c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9z"/></svg>', 326 tariff: '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M0 416c0 17.7 14.3 32 32 32l54.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 448c17.7 0 32-14.3 32-32s-14.3-32-32-32l-246.7 0c-12.3-28.3-40.5-48-73.3-48s-61 19.7-73.3 48L32 384c-17.7 0-32 14.3-32 32zm128 0a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM320 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32-80c-32.8 0-61 19.7-73.3 48L32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l246.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48l54.7 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-54.7 0c-12.3-28.3-40.5-48-73.3-48zM192 128a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm73.3-64C253 35.7 224.8 16 192 16s-61 19.7-73.3 48L32 64C14.3 64 0 78.3 0 96s14.3 32 32 32l86.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 128c17.7 0 32-14.3 32-32s-14.3-32-32-32l-214.7 0z"/></svg>', 327 extend: '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
327<path fill="currentColor" d="M105.1 202.6c7.7-21.8 20.2-42.3 37.8-59.8c62.5-62.5 163.8-62.5 226.3 0L386.3 160 352 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l111.5 0c0 0 0 0 .1 0l.4 0c17.7 0 32-14.3 32-32l0-112c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 35.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0C73.2 122 55.6 150.7 44.8 181.4c-5.9 16.7 2.9 35 19.5 40.9s35-2.9 40.9-19.5zM39 289.3c-5 1.5-9.8 4.2-13.7 8.2c-4 4-6.7 8.8-8.1 14c-.3 1.2-.6 2.5-.8 3.8c-.3 1.7-.4 3.4-.4 5.1L16 432c0 17.7 14.3 32 32 32s32-14.3 32-32l0-35.1 17.6 17.5c87.5 87.4 229.3 87.4 316.7 0c24.4-24.4 42.1-53.1 52.9-83.7c5.9-16.7-2.9-35-19.5-40.9s-35 2.9-40.9 19.5c-7.7 21.8-20.2 42.3-37.8 59.8c-62.5 62.5-163.8 62.5-226.3 0l-.1-.1L125.6 352l34.4 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L48.4 288c-1.6 0-3.2 .1-4.8 .3s-3.1 .5-4.6 1z"/></svg>' 328 }; 329 var STORIES = [ { 330 id: 'install', 331 title: 'Ðак ÑÑÑановиÑÑ VPN', 332 label: 'Ðак ÑÑÑановиÑÑ VPN', 333 tile: { 334 gradient: 'linear-gradient(135deg, #1d2025 0%, #1e3a8a 55%, #40a7e3 100%)', 335 icon: FA_ICONS.install 336 }, 337 steps: [ { 338 theme: 'blue', 339 title: 'ÐÑо Ð²Ð°Ñ ÐºÐ»ÑÑ', 340 body: 'ÐаждÑй клÑÑ ÑÑо оÑделÑÐ½Ð°Ñ ÐºÐ°ÑÑоÑка. ЧÑÐ¾Ð±Ñ ÑÑÑановиÑÑ ÐºÐ»ÑÑ, нажмиÑе <b>«Ðой клÑÑ»</b>.', 341 mockup: [ 'keyCard', { 342 highlight: 'manage' 343 } ] 344 }, { 345 theme: 'violet', 346 title: 'ÐÑбеÑиÑе пÑиложение', 347 body: 'ÐÑбеÑиÑе из ÑпиÑка Ñекомендованное пÑиложение или алÑÑеÑнаÑивное, еÑли Ñ Ð²Ð°Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ ÑекомендованнÑм.', 348 mockup: [ 'appsGrid' ] 349 }, { 350 theme: 'green', 351 title: 'УÑÑановиÑе пÑиложение', 352 body: 'ÐажмиÑе на Ð¸ÐºÐ¾Ð½ÐºÑ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ на ÐºÐ½Ð¾Ð¿ÐºÑ <b>«УÑÑановиÑÑ»</b>.', 353 mockup: [ 'installFlow' ] 354 }, { 355 theme: 'teal', 356 title: 'ÐобавÑÑе клÑÑ', 357 body: 'ÐажмиÑе на Ð¸ÐºÐ¾Ð½ÐºÑ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ <b>«ÐобавиÑÑ ÐºÐ»ÑÑ»</b> или ÑделайÑе ÑÑо вÑÑÑнÑÑ.', 358 mockup: [ 'addKeyFlow' ] 359 } ] 360 }, { 361 id: 'tariff', 362 title: 'СмениÑÑ ÑаÑÐ¸Ñ ÐºÐ»ÑÑа', 363 label: 'Ðак ÑмениÑÑ ÑаÑиÑ', 364 tile: { 365 gradient: 'linear-gradient(135deg, #1d2025 0%, #4c1d95 55%, #8b5cf6 100%)', 366 icon: FA_ICONS.tariff 367 }, 368 steps: [ { 369 theme: 'violet', 370 title: 'ÐÑкÑойÑе «Ðой клÑÑ»', 371 body: 'ТаÑÐ¸Ñ Ð¼ÐµÐ½ÑеÑÑÑ ÑеÑез каÑÑоÑÐºÑ ÐºÐ»ÑÑа. СнаÑала оÑкÑойÑе <b>«Ðой клÑÑ»</b>.', 372 mockup: [ 'keyCard', { 373 highlight: 'manage' 374 } ] 375 }, { 376 theme: 'magenta', 377 title: 'ÐеÑейдиÑе в ÑÐ¼ÐµÐ½Ñ ÑаÑиÑа', 378 body: 'ÐнÑÑÑи каÑÑоÑки пеÑеклÑÑиÑе Ð²ÐºÐ»Ð°Ð´ÐºÑ Ñ <b>«УпÑавление»</b> на <b>«Смена ÑаÑиÑа»</b>.', 379 mockup: [ 'manageToggle', { 380 tab: 'change' 381 } ] 382 }, { 383 theme: 'magenta', 384 title: 'ÐоменÑйÑе паÑамеÑÑÑ', 385 body: 'ÐвигайÑе бегÑнок ÑÑÑÑойÑÑв, вклÑÑайÑе доп. опÑии и нажмиÑе <b>«ÐзмениÑÑ ÑаÑиÑ»</b>.', 386 mockup: [ 'tariffChangeUI' ], 387 duration: 7e3 388 } ] 389 }, { 390 id: 'extend', 391 title: 'ÐÑодлиÑÑ ÐºÐ»ÑÑ', 392 label: 'Ðак пÑодлиÑÑ ÐºÐ»ÑÑ', 393 tile: { 394 gradient: 'linear-gradient(135deg, #1d2025 0%, #92400e 55%, #f59e0b 100%)', 395 icon: FA_ICONS.extend 396 }, 397 steps: [ { 398 theme: 'amber', 399 title: 'Ðнопка «ÐÑодлиÑÑ»', 400 body: 'Ðнопка <b>«ÐÑодлиÑÑ»</b> вÑегда доÑÑÑпна - пÑоÑÑо нажмиÑе еÑ. ÐлÑÑ Ð¾ÑÑаÑÑÑÑ Ð¿Ñежним, пеÑеÑÑÑанавливаÑÑ Ð½Ð¸Ñего не нÑжно.', 401 mockup: [ 'keyCard', { 402 highlight: 'renew' 403 } ] 404 }, { 405 theme: 'amber', 406 title: 'ÐÑбеÑиÑе ÑÑок', 407 body: 'ÐеÑеклÑÑайÑе ÑÑок 1 / 3 / 6 / 12 меÑÑÑев - Ñена пеÑеÑÑиÑаеÑÑÑ ÑÑазÑ. Ðогда вÑÑ Ð¾Ðº, жмиÑе <b>«ÐÑодлиÑÑ»</b>.', 408 mockup: [ 'renewUI' ] 409 }, {
410 theme: 'green', 411 title: 'ÐÑ ÑÑпеÑно пÑодлили клÑÑ', 412 body: 'СÑмма ÑпиÑалаÑÑ Ñ Ð±Ð°Ð»Ð°Ð½Ñа AID, ÑÑок клÑÑа пÑодлÑн. Ðожно полÑзоваÑÑÑÑ Ð´Ð°Ð»ÑÑе.', 413 mockup: [ 'renewSuccess' ] 414 } ] 415 } ]; 416 function register() { 417 if (window.AidVpnStories && typeof window.AidVpnStories.configure === 'function') { 418 window.AidVpnStories.configure({ 419 stories: STORIES, 420 mockups: MOCKUPS, 421 themes: THEMES 422 }); 423 } else { 424 window.setTimeout(register, 50); 425 } 426 } 427 if (document.readyState === 'loading') { 428 document.addEventListener('DOMContentLoaded', register); 429 } else { 430 register(); 431 } 432})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.