1$(document).ready(function () { 2 $.fancybox.defaults.hash = false; 3 $("[data-fancybox]").fancybox({ 4 afterShow: function( instance, current ) { 5 console.log('current', current) 6 if (current.origSrc.match(/^.+vk.com\/clip/)) { 7 // ÐобавлÑем клаÑÑ, еÑли ÑÑо клип 8 console.log('instance.$refs', instance.$refs) 9 instance.$refs.container.addClass('vk-clip'); 10 } 11 } 12 }); 13 $.fn.select2.amd.define('select2/i18n/ru',[],function () { 14 // Russian 15 return { 16 errorLoading: function () { 17 return 'РезÑлÑÑÐ°Ñ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°Ð³ÑÑжен.'; 18 }, 19 inputTooLong: function (args) { 20 var overChars = args.input.length - args.maximum; 21 var message = 'ÐожалÑйÑÑа, ÑдалиÑе ' + overChars + ' Ñимвол'; 22 if (overChars >= 2 && overChars <= 4) { 23 message += 'а'; 24 } else if (overChars >= 5) { 25 message += 'ов'; 26 } 27 return message; 28 }, 29 inputTooShort: function (args) { 30 var remainingChars = args.minimum - args.input.length; 31 32 var message = 'ÐожалÑйÑÑа, введиÑе ' + remainingChars + ' или более Ñимволов'; 33 34 return message; 35 }, 36 loadingMore: function () { 37 return 'ÐагÑÑжаем еÑÑ ÑеÑÑÑÑÑâ¦'; 38 }, 39 maximumSelected: function (args) { 40 var message = 'ÐÑ Ð¼Ð¾Ð¶ÐµÑе вÑбÑаÑÑ ' + args.maximum + ' ÑлеменÑ'; 41 42 if (args.maximum >= 2 && args.maximum <= 4) { 43 message += 'а'; 44 } else if (args.maximum >= 5) { 45 message += 'ов'; 46 } 47 48 return message; 49 }, 50 noResults: function () { 51 return 'ÐиÑего не найдено'; 52 }, 53 searching: function () { 54 return 'ÐоиÑкâ¦'; 55 } 56 }; 57 }); 58 // UTM меÑки в кÑки 59 let searchParams = new URLSearchParams(window.location.search) 60 let expires = 60 * 60 * 24 * 14 // 14 дней 61 if (searchParams.has('utm_source')) { 62 BX.setCookie('utm_source', searchParams.get('utm_source'), {path: '/', expires: expires}); 63 } 64 if (searchParams.has('utm_medium')) { 65 BX.setCookie('utm_medium', searchParams.get('utm_medium'), {path: '/', expires: expires}); 66 } 67 if (searchParams.has('utm_campaign')) { 68 BX.setCookie('utm_campaign', searchParams.get('utm_campaign'), {path: '/', expires: expires}); 69 } 70 if (searchParams.has('utm_term')) { 71 BX.setCookie('utm_term', searchParams.get('utm_term'), {path: '/', expires: expires}); 72 }
73 if (searchParams.has('utm_content')) { 74 BX.setCookie('utm_content', searchParams.get('utm_content'), {path: '/', expires: expires}); 75 } 76 if (searchParams.has('yclid')) { 77 BX.setCookie('yclid', searchParams.get('yclid'), {path: '/', expires: expires}); 78 } 79 80 phoneMask(); 81 82 $('input[type="tel"]').not('.js-phone-filter').focusout(function (e) { 83 let phone = $(this).val().replace(/[^.\d]+/g, "").substring(1); 84 85 if (phone === '' || phone.length < 10) { 86 $(this).addClass('error'); 87 if (!$(this).next().hasClass('error-phone')) { 88 $(this).after('<span class="error-phone">ÐведиÑе Ð½Ð¾Ð¼ÐµÑ ÑелеÑона полноÑÑÑÑ</span>'); 89 } 90 } else { 91 $(this).removeClass('error'); 92 if ($(this).next().hasClass('error-phone')) { 93 $(this).next().remove(); 94 } 95 } 96 }); 97 98 $(document).on('click', '.js-callback', function () { 99 let title = $(this).attr('data-title'), 100 type = $(this).attr('data-type'), 101 url = $(this).attr('data-url') ? $(this).attr('data-url') : location.href.split("?")[0]; 102 103 if (!title) { 104 title = 'ÐаказаÑÑ Ð·Ð²Ð¾Ð½Ð¾Ðº'; 105 } 106 107 $('#modalCallback .modal-title').text(title); 108 $('#modalCallback input[name="one_click"]').val('N'); 109 $('#modalCallback input[name="form_name"]').val('ФоÑма "' + title + '"'); 110 if (type) { 111 $('#modalCallback input[name="type"]').val(type); 112 } 113 $('#modalCallback input[name="url"]').val(url); 114 115 $('.modal').modal('hide'); 116 $('#modalCallback').modal(); 117 }); 118 119 $(document).on('click', '#modalCallback .modal-close, #modalCallback .modal-overlay', function() { 120 $('#recaptcha-message').hide(); 121 $('#recaptcha-v2-container').hide(); 122 }); 123 124 function ensureLegacyCallbackHidden($form, name, value, force) { 125 let $field = $form.find('input[name="' + name + '"]'); 126 127 if (!$field.length) { 128 $field = $('<input>', { 129 type: 'hidden', 130 name: name 131 }).appendTo($form); 132 } 133 134 if (force || !$field.val()) { 135 $field.val(value); 136 } 137 138 return $field; 139 } 140 141 function ensureLegacyCallbackRecaptcha($form) { 142 if (!$form.find('.recaptcha-message').length) { 143 $('<div class="recaptcha-message" style="display:none;"><span class="recaptcha-message-text"></span></div>').appendTo($form); 144 } 145 146 if (!$form.find('.recaptcha-v2-container').length) { 147 $('<div class="recaptcha-v2-container" style="display:none;"><div class="recaptcha-v2"></div></div>').appendTo($form); 148 } 149 } 150 151 $(document).on('submit', '.oneClickCallback', function (e) { 152 let $form = $(this); 153 154 if ($form.hasClass('js-call-me')) { 155 return; 156 } 157 158 e.preventDefault(); 159 e.stopImmediatePropagation(); 160 161 let formType = $.trim($form.find('input[name="formtype"]').val() || ''), 162 formName = formType || 'ФоÑма "Ðне нÑжна конÑÑлÑÑаÑиÑ"'; 163 164 ensureLegacyCallbackHidden($form, 'confirm', 'N', false); 165 ensureLegacyCallbackHidden($form, 'one_click', 'N', true); 166 ensureLegacyCallbackHidden($form, 'form_name', formName, true); 167 ensureLegacyCallbackHidden($form, 'type', 'form_call_ordering', false); 168 ensureLegacyCallbackHidden($form, 'url', location.href.split("?")[0], true); 169 ensureLegacyCallbackRecaptcha($form); 170 171 $form.addClass('js-call-me'); 172 $form.trigger('submit'); 173 }); 174 175 // ÐÑпÑавка ÑоÑÐ¼Ñ "ÐозвониÑе мне" 176 /*$(document).on('submit', '.js-call-me', function (e) { 177 e.preventDefault(); 178 179 $('.js-call-me').removeClass('active'); 180 let data = $(this).serializeArray().reduce(function (obj, item) { 181 obj[item.name] = item.value; 182 return obj; 183 }, {}); 184 185 if (data['confirm'] === 'Y') { 186 let _this = $(this), 187 $button = _this.find('button[type="submit"], input[type="submit"]').first() 188 189 $button.btnLoading(); 190 data['url'] = data['url'] ? data['url'] : location.href.split("?")[0]; 191 data['title'] = document.title; 192 193 fbq('track', 'Lead'); 194 VK.Goal('lead'); 195 196 BX.ajax.runComponentAction('8up:catalog.element', 'sendCallbackForm', { 197 mode: 'class', 198 data: {data: data} 199 }).then(function (response) { 200 $button.btnLoading('hide'); 201 $('.js-form-confirm').find('button[type="submit"]').btnLoading('hide'); 202 if (response.data.ERROR) { 203 alert('Ðозникла оÑибка, попÑобÑйÑе позже.'); 204 } else { 205 $('.modal').modal('hide'); 206 modalMessage('СпаÑибо, ваÑа заÑвка ÑÑпеÑно оÑпÑавлена. ÐÐµÐ½ÐµÐ´Ð¶ÐµÑ ÑвÑжеÑÑÑ Ñ Ð²Ð°Ð¼Ð¸ в ближайÑее вÑемÑ.'); 207 _this.find("input[name='name']").val(''); 208 _this.find("input[name='phone']").val(''); 209 _this.find("input[name='confirm']").val('N'); 210 if (data['type']) { 211 dataLayer.push({'event': data['type']}); 212 } 213 if(window.location.pathname === '/mebel/divany/na-zakaz/') { 214 dataLayer.push({'event': 'order_by_one_click'}); 215 } 216 dataLayer.push({'event': 'form_call_ordering'}); 217 } 218 }); 219 } else { 220 $('#modalFormConfirm input[type="tel"]').val(data['phone']); 221 $('.modal').modal('hide'); 222 $(this).addClass('active'); 223 $('#modalFormConfirm').attr('data-form', '.js-call-me').modal(); 224 } 225 });*/ 226 227 // ÐÑпÑавка ÑоÑÐ¼Ñ "ÐозвониÑе мне" (ÐеÑÑÐ¸Ñ ÐºÐ°Ð¿ÑÑей) 228 $(document).on('submit', '.js-call-me', function (e) { 229 e.preventDefault(); 230 231 $('.js-call-me').removeClass('active'); 232 let data = $(this).serializeArray().reduce(function (obj, item) { 233 obj[item.name] = item.value; 234 return obj; 235 }, {}); 236 237 if (data['confirm'] === 'Y') { 238 let _this = $(this), 239 $button = _this.find('button[type="submit"], input[type="submit"]').first() 240 241 $button.btnLoading(); 242 data['url'] = data['url'] ? data['url'] : location.href.split("?")[0]; 243 data['title'] = document.title; 244 245 window.GliverRecaptcha.execute('callback_form').then(function(token) { 246 data['recaptcha_token'] = token; 247 data['recaptcha_version'] = 'v3'; 248 249 fbq('track', 'Lead'); 250 VK.Goal('lead'); 251 252 BX.ajax.runComponentAction('8up:catalog.element', 'sendCallbackForm', { 253 mode: 'class', 254 data: {data: data} 255 }).then(function (response) { 256 $button.btnLoading('hide'); 257 $('.js-form-confirm').find('button[type="submit"]').btnLoading('hide'); 258 259 if (response.data.ERROR) { 260 alert('Ðозникла оÑибка, попÑобÑйÑе позже.'); 261 } else if (response.data.SUSPICIOUS) { 262 var isModalForm = _this.closest('#modalCallback').length > 0; 263 var $messageContainer, $recaptchaContainer, recaptchaElementId; 264 265 if (isModalForm) { 266 $('#modalFormConfirm').modal('hide'); 267 $('#modalCallback').modal(); 268 recaptchaElementId = 'recaptcha-v2'; 269 } 270 271 $messageContainer = _this.find('.recaptcha-message'); 272 $recaptchaContainer = _this.find('.recaptcha-v2-container'); 273 recaptchaElementId = _this.find('.recaptcha-v2')[0]; 274 275 $messageContainer.show(); 276 if (response.data.message) { 277 $messageContainer.find('.recaptcha-message-text').text(response.data.message); 278 } 279 280 $recaptchaContainer.show(); 281 282 var formKey = _this.attr('id') || 'form_' + Math.random().toString(36).substr(2, 9); 283 if (!window.recaptchaV2Rendered) { 284 window.recaptchaV2Rendered = {}; 285 } 286 287 if (!window.recaptchaV2Rendered[formKey]) { 288 window.GliverRecaptcha.renderV2(recaptchaElementId, { 289 'sitekey': window.RECAPTCHA_V2_SITE_KEY, 290 'callback': function(v2Token) { 291 data['recaptcha_token'] = v2Token; 292 data['recaptcha_version'] = 'v2'; 293 294 $button.btnLoading(); 295 BX.ajax.runComponentAction('8up:catalog.element', 'sendCallbackForm', { 296 mode: 'class', 297 data: {data: data} 298 }).then(function (response) { 299 $button.btnLoading('hide'); 300 $recaptchaContainer.hide(); 301 $messageContainer.hide(); 302 window.GliverRecaptcha.reset(window.recaptchaV2Rendered[formKey]); 303 304 if (response.data.ERROR) { 305 alert('Ðозникла оÑибка, попÑобÑйÑе позже.'); 306 } else { 307 if (isModalForm) { 308 $('.modal').modal('hide'); 309 } 310 modalMessage('СпаÑибо, ваÑа заÑвка ÑÑпеÑно оÑпÑавлена. ÐÐµÐ½ÐµÐ´Ð¶ÐµÑ ÑвÑжеÑÑÑ Ñ Ð²Ð°Ð¼Ð¸ в ближайÑее вÑемÑ.'); 311 _this.find("input[name='name']").val(''); 312 _this.find("input[name='phone']").val(''); 313 _this.find("input[name='confirm']").val('N'); 314 if (data['type']) { 315 dataLayer.push({'event': data['type']}); 316 } 317 if(window.location.pathname === '/mebel/divany/na-zakaz/') { 318 dataLayer.push({'event': 'order_by_one_click'}); 319 } 320 dataLayer.push({'event': 'form_call_ordering'}); 321 } 322 }); 323 } 324 }).then(function(widgetId) { 325 window.recaptchaV2Rendered[formKey] = widgetId; 326 }).catch(function() { 327 $button.btnLoading('hide'); 328 alert('Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ reCAPTCHA. ÐопÑобÑйÑе позже.'); 329 }); 330 } 331 } else { 332 $('.modal').modal('hide'); 333 modalMessage('СпаÑибо, ваÑа заÑвка ÑÑпеÑно оÑпÑавлена. ÐÐµÐ½ÐµÐ´Ð¶ÐµÑ ÑвÑжеÑÑÑ Ñ Ð²Ð°Ð¼Ð¸ в ближайÑее вÑемÑ.'); 334 _this.find("input[name='name']").val(''); 335 _this.find("input[name='phone']").val(''); 336 _this.find("input[name='confirm']").val('N'); 337 if (data['type']) { 338 dataLayer.push({'event': data['type']}); 339 } 340 if(window.location.pathname === '/mebel/divany/na-zakaz/') { 341 dataLayer.push({'event': 'order_by_one_click'}); 342 } 343 dataLayer.push({'event': 'form_call_ordering'}); 344 } 345 }); 346 }).catch(function() { 347 $button.btnLoading('hide'); 348 alert('Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ reCAPTCHA. ÐопÑобÑйÑе позже.'); 349 }); 350 } else { 351 $('#modalFormConfirm input[type="tel"]').val(data['phone']); 352 $('.modal').modal('hide'); 353 $(this).addClass('active'); 354 $('#modalFormConfirm').attr('data-form', '.js-call-me').modal(); 355 } 356 }); 357 358 // ФоÑма подÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ ÑелеÑона 359 $(document).on('submit', '.js-form-confirm', function (e) { 360 e.preventDefault(); 361 362 if ($(this).find('.error-phone').length > 0) { 363 return false;
364 } 365 366 let phone = $(this).find('input[type="tel"]').val(), 367 $form = $($('#modalFormConfirm').attr('data-form') + '.active'); 368 369 if (phone && $form.length > 0) { 370 $(this).find('button[type="submit"]').btnLoading(); 371 $form.find('input[type="tel"]').val(phone); 372 $form.find('input[name="confirm"]').val('Y'); 373 $form.submit(); 374 } 375 }); 376 377 // ÐаÑнÑÐµÑ 378 $(document).on('click', '.counter__button[data-quantity="plus"]', function (e) { 379 e.preventDefault(); 380 let $input = $(this).closest('.counter').find('input'), 381 currentVal = parseInt($input.val()); 382 383 if (!isNaN(currentVal)) { 384 $input.val(currentVal + 1); 385 } else { 386 $input.val(1); 387 } 388 }); 389 $(document).on('click', '.counter__button[data-quantity="minus"]', function (e) { 390 e.preventDefault(); 391 let $input = $(this).closest('.counter').find('input'), 392 currentVal = parseInt($input.val()); 393 394 if (!isNaN(currentVal) && currentVal > 1) { 395 $input.val(currentVal - 1); 396 } else { 397 $input.val(1); 398 } 399 }); 400 $(document).on('change', '.counter__input input', function (e) { 401 let value = $(this).val(); 402 if(!value || value <= 0) { 403 $(this).val(1); 404 } 405 }); 406 407 tippy(".js-mail-copy", { 408 trigger: "click", 409 theme: 'copy', 410 hideOnClick: false, 411 onShow(instance) { 412 setTimeout(() => { 413 instance.hide(); 414 }, 2000); 415 } 416 }); 417 418 $(document).on('click', '.js-mail-copy', function (e) { 419 let $temp = $("<input>"), 420 mail = $(this).closest('.gl-menu-contact-item-wrapper').find('.mailto-link').text(); 421 422 $("body").append($temp); 423 $temp.val(mail).select(); 424 document.execCommand("copy"); 425 $temp.remove(); 426 dataLayer.push({'event': 'copy_mail'}); 427 }); 428 429 $(window).scroll(function () { 430 setHeaderScrolled(); 431 }); 432 setHeaderScrolled(); 433 434 function setHeaderScrolled() { 435 if ($(window).scrollTop() > 50) { 436 $('.header').addClass("scrolled"); 437 } else { 438 $('.header').removeClass("scrolled"); 439 } 440 } 441 442 $(document).on('click', '.js-whatsapp-widget', function (e) { 443 const phone = $(this).data('phone'); 444 const dt = new Date(); 445 const padL = (nr, len = 2, chr = `0`) => `${nr}`.padStart(2, chr); 446 const dateString = `${ 447 padL(dt.getDate())}.${ 448 padL(dt.getMonth()+1)}.${ 449 dt.getFullYear()} ${ 450 padL(dt.getHours())}:${ 451 padL(dt.getMinutes())}:${ 452 padL(dt.getSeconds())}`; 453 454 if (typeof window.ym === 'function') { 455 window.ym(32989379, 'reachGoal', `wa_${phone}`, {date_time: dateString}); 456 } 457 }); 458}); 459 460$.fn.modal = function (param) { 461 let currentModal = $(this), 462 currentModalOverlay = currentModal.find(".modal-overlay"); 463 464 if (param === 'hide') { 465 $(this).removeClass("is-visible"); 466 $("body").removeClass("overflow-hidden"); 467 } else { 468 let movedToBody = false; 469 if (currentModal.length && currentModal.hasClass("modal-web-form") && !currentModal.parent().is("body")) { 470 currentModal.appendTo("body"); 471 movedToBody = true; 472 } 473 if (movedToBody) { 474 currentModal[0].offsetHeight; 475 } 476 const zIndex = Math.max.apply(Math, $('.modal.is-visible').map(function () { 477 return $(this).css("z-index"); 478 }).get()); 479 $(this).css('z-index', zIndex + 1); 480 if (param !== 'above') { 481 //$(".modal").not(this).removeClass("is-visible"); 482 } 483 currentModal.addClass("is-visible"); 484 485 if (window.matchMedia("(max-width:991.98px)").matches) { 486 if (!currentModalOverlay.hasClass("desktop-only")) { 487 $("body").addClass("overflow-hidden"); 488 } 489 } else if (window.matchMedia("(min-width:992px)").matches) { 490 if (!currentModalOverlay.hasClass("modal-overlay-mobile")) { 491 $("body").addClass("overflow-hidden"); 492 } 493 } 494 } 495}; 496 497File.prototype.convertToBase64 = function (callback) { 498 let reader = new FileReader(); 499 500 reader.onloadend = function (e) { 501 callback(e.target.result, e.target.error); 502 };
503 reader.readAsDataURL(this); 504}; 505 506const modalAlert = (message, title = 'Ðнимание') => { 507 $('#modalAlert .modal-title').text(title); 508 $('#modalAlert .modal-body').html(message); 509 $('#modalAlert').modal(); 510} 511 512const modalMessage = (text) => { 513 $('#modalMessage .modal-body').html(text); 514 $('#modalMessage').modal(); 515} 516 517const modalDebug = (text) => { 518 $('.modal').modal('hide'); 519 $('#modalDebug .modal-body').html(text); 520 $('#modalDebug').modal(); 521} 522 523const uploadFile = (file, inputImage = 'arFields[IMAGE]', inputPdf = 'arFields[PDF]', inputDoc = 'arFields[DOC]') => { 524 let filename = file.name, 525 idxDot = filename.lastIndexOf(".") + 1, 526 extFile = filename.substr(idxDot, filename.length).toLowerCase(); 527 528 const $btn = $(".upload-image").closest('form').find('.btn[type="submit"]'); 529 if ($btn.length) { 530 $btn.btnLoading(); 531 } 532 533 if (extFile === "jpg" || extFile === "jpeg" || extFile === "png" || extFile === "gif") { 534 file.convertToBase64(function (base64) { 535 BX.ajax.runComponentAction('8up:calc.basket', 'saveImage', { 536 mode: 'class', 537 data: {base64: base64}, 538 }).then(function (response) { 539 if (response.data.ERROR) { 540 alert(response.data.ERROR); 541 } else { 542 $(".upload-image").append(`<div class="upload-image__item"> 543 <img src="` + base64 + `" height="100%"> 544 <div class="upload-image__remove js-remove-image">Ã</div> 545 <input class="js-image" t
545ype="hidden" name="` + inputImage + `[]" value="` + response.data.URL + `"> 546 <input class="js-image" type="hidden" name="arFields[IMAGE_NAME][]" value="` + filename + `"> 547 </div>`); 548 } 549 if ($btn.length) { 550 $btn.btnLoading('hide'); 551 } 552 }); 553 }) 554 555 } else if (extFile === "pdf") { 556 let formData = new FormData(); 557 558 formData.append('file', file); 559 560 BX.ajax.runComponentAction('8up:calc.custom.item', 'savePdf', { 561 mode: 'class', 562 data: formData, 563 }).then(function (response) { 564 if (response.data.ERROR) { 565 alert(response.data.ERROR); 566 } else { 567 $(".upload-image").append(`<div class="upload-image__item"> 568 <div class="bx-file-icon-container-medium icon-pdf"> 569 <div class="bx-file-icon-cover"> 570 <div class="bx-file-icon-corner"> 571 <div class="bx-file-icon-corner-fix"></div> 572 </div> 573 <div class="bx-file-icon-images"></div> 574 </div> 575 <div class="bx-file-icon-label"></div> 576 </div> 577 <div class="upload-image__title">` + filename + `</div> 578 <div class="upload-image__remove js-remove-image">Ã</div> 579 <input class="js-pdf" type="hidden" name="` + inputPdf + `[]" value="` + response.data.URL + `"> 580 </div>`); 581 } 582 if ($btn.length) { 583 $btn.btnLoading('hide'); 584 } 585 }); 586 587 } else if (extFile === "doc" || extFile === "docx") { 588 let formData = new FormData(); 589 590 formData.append('file', file); 591 592 BX.ajax.runComponentAction('8up:calc.custom.item', 'saveDoc', { 593 mode: 'class', 594 data: formData, 595 }).then(function (response) { 596 if (response.data.ERROR) { 597 alert(response.data.ERROR); 598 } else { 599 $(".upload-image").append(`<div class="upload-image__item"> 600 <div class="bx-file-icon-container-medium icon-doc"> 601 <div class="bx-file-icon-cover"> 602 <div class="bx-file-icon-corner"> 603 <div class="bx-file-icon-corner-fix"></div> 604 </div> 605 <div class="bx-file-icon-images"></div> 606 </div> 607 <div class="bx-file-icon-label"></div> 608 </div> 609 <div class="upload-image__title">` + filename + `</div> 610 <div class="upload-image__remove js-remove-image">Ã</div> 611 <input class="js-pdf" type="hidden" name="` + inputDoc + `[]" value="` + response.data.URL + `"> 612 </div>`); 613 } 614 if ($btn.length) { 615 $btn.btnLoading('hide'); 616 } 617 }); 618 } 619 else { 620 alert('ÐевеÑнÑй ÑоÑÐ¼Ð°Ñ Ñайла (ÐоддеÑживаемÑе ÑоÑмаÑÑ: jpg, jpeg, png, gif, pdf)'); 621 } 622} 623 624const saveImage = (base64) => {
625 return BX.ajax.runComponentAction('dev:calc.basket', 'saveImage', { 626 mode: 'class', 627 data: {base64: base64}, 628 }).then(function (response) { 629 if (response.data.ERROR) { 630 alert(response.data.ERROR); 631 } else { 632 return response.data; 633 } 634 }); 635} 636 637const phoneMask = () => { 638 $('input[type="tel"]').inputmask({ 639 mask: "+7 (9h9) 999-9999", 640 definitions: { 641 "h": { 642 validator: function (chrs, maskset, pos) { 643 if (chrs === "9" && (maskset.buffer[4] === "8" || maskset.buffer[4] === "7")) { 644 return { 645 remove: [pos, pos - 1], 646 insert: { 647 pos: pos - 1, 648 c: chrs 649 }, 650 caret: pos 651 } 652 } 653 if (chrs === "8" && (maskset.buffer[4] === "8" || maskset.buffer[4] === "7")) { 654 return { 655 remove: [pos, pos - 1], 656 insert: { 657 pos: pos - 1, 658 c: chrs 659 }, 660 caret: pos 661 } 662 } 663 664 return { 665 c: chrs 666 } 667 } 668 } 669 }, 670 }); 671} 672 673$.fn.btnLoading = function (param) { 674 if (param === 'hide') { 675 $(this) 676 .removeClass('btn--loading') 677 .find(".icon-loading").remove(); 678 } else { 679 $(this) 680 .addClass('btn--loading') 681 .append(`<div class="icon-loading"></div>`) 682 } 683}; 684 685const confirmDialog = (title, message, yesCallback, noCallback, force = false) => { 686 if(force) { 687 yesCallback(); 688 } 689 else { 690 $('#modalConfirm .modal-title').html(title); 691 $('#modalConfirm .modal-form__text-block span').html(message); 692 $('#modalConfirm').modal(); 693 694 $('#modalConfirm .js-confirm-yes').off('click').click(async function (e) { 695 e.preventDefault(); 696 if (typeof yesCallback === 'function') { 697 await yesCallback(); 698 } 699 $('#modalConfirm').modal('hide'); 700 }); 701 $('#modalConfirm .js-confirm-no').off('click').click(async function () { 702 if (typeof noCallback === 'function') { 703 await noCallback(); 704 } 705 $('#modalConfirm').modal('hide'); 706 }); 707 } 708} 709 710const html2PngWait = (ms) => new Promise(resolve => setTimeout(resolve, ms)); 711 712const html2PngElement = (query) => { 713 if (query instanceof Element) { 714 return query; 715 } 716 717 if (query && query.jquery) { 718 return query[0]; 719 } 720 721 if (typeof query === 'string') { 722 return document.querySelector(query); 723 } 724 725 return null; 726}; 727 728const html2PngWaitImages = async (element, timeout = 5000) => { 729 const images = Array.from(element.querySelectorAll('img')); 730 731 if (!images.length) { 732 return; 733 } 734 735 await Promise.all(images.map(img => new Promise(resolve => { 736 img.setAttribute('loading', 'eager'); 737 738 if (!img.getAttribute('src') && img.dataset && img.dataset.src) { 739 img.setAttribute('src', img.dataset.src); 740 } 741 742 if (img.complete && img.naturalWidth > 0) { 743 resolve(); 744 return; 745 } 746 747 const done = () => { 748 clearTimeout(timer); 749 img.removeEventListener('load', done); 750 img.removeEventListener('error', done); 751 resolve(); 752 }; 753 754 const timer = setTimeout(done, timeout); 755 img.addEventListener('load', done, {once: true}); 756 img.addEventListener('error', done, {once: true}); 757 }))); 758}; 759 760const html2PngBlobToDataUrl = (blob) => new Promise((resolve, reject) => { 761 const reader = new FileReader(); 762 reader.onloadend = () => resolve(reader.result); 763 reader.onerror = reject;
764 reader.readAsDataURL(blob); 765}); 766 767const html2PngInlineImages = async (element) => { 768 const images = Array.from(element.querySelectorAll('img')); 769 770 if (!images.length) { 771 return; 772 } 773 774 await Promise.all(images.map(async img => { 775 const src = img.currentSrc || img.getAttribute('src'); 776 777 if (!src || src.indexOf('data:') === 0 || src.indexOf('blob:') === 0) { 778 return; 779 } 780 781 try { 782 const response = await fetch(new URL(src, window.location.href).href, { 783 cache: 'force-cache', 784 credentials: 'same-origin' 785 }); 786 787 if (!response.ok) { 788 throw new Error('Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ Ð¸Ð·Ð¾Ð±Ñажение: ' + response.status); 789 } 790 791 img.setAttribute('src', await html2PngBlobToDataUrl(await response.blob())); 792 } catch (error) { 793 console.warn('Ðе ÑдалоÑÑ Ð²ÑÑÑоиÑÑ Ð¸Ð·Ð¾Ð±Ñажение пеÑед ÑÐ¾Ñ Ñанением:', { 794 src: src, 795 error: error 796 }); 797 } 798 })); 799}; 800 801const html2PngHasLargeImage = (element) => { 802 return Array.from(element.querySelectorAll('img')).some(img => { 803 const width = img.naturalWidth || img.width || img.offsetWidth; 804 const height = img.naturalHeight || img.height || img.offsetHeight; 805 806 return width >= 100 && height >= 100; 807 }); 808}; 809 810const html2PngIsBlank = async (dataUrl, options = {}) => { 811 const img = new Image(); 812 813 await new Promise((resolve, reject) => { 814 img.onload = resolve; 815 img.onerror = reject; 816 img.src = dataUrl; 817 }); 818 819 const canvas = document.createElement('canvas'); 820 const width = img.naturalWidth || img.width; 821 const height = img.naturalHeight || img.height; 822 823 if (!width || !height) { 824 return true; 825 } 826 827 canvas.width = width; 828 canvas.height = height; 829 830 const context = canvas.getContext('2d', {willReadFrequently: true}); 831 context.drawImage(img, 0, 0); 832 833 const pixels = context.getImageData(0, 0, width, height).data; 834 const step = Math.max(4, Math.floor(Math.sqrt((width * height) / 2500)) * 4); 835 let checked = 0; 836 let visible = 0; 837 const minVisibleRatio = options.hasLargeImage ? 0.01 : 0.001; 838 839 for (let i = 0; i < pixels.length; i += step) { 840 const alpha = pixels[i + 3]; 841 const red = pixels[i]; 842 const green = pixels[i + 1]; 843 const blue = pixels[i + 2]; 844 845 checked++; 846 847 if (alpha > 8 && (red < 245 || green < 245 || blue < 245)) { 848 visible++; 849 } 850 } 851 852 return checked === 0 || visible / checked < minVisibleRatio; 853}; 854 855const html2Png = async (query, isDownload = false) => { 856 const source = html2PngElement(query); 857 858 if (!source) { 859 console.error('ÐÑибка пÑи ÑÐ¾Ñ Ñанении изобÑажениÑ: ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ найден', query); 860 return; 861 } 862 863 const attempts = 3; 864 let lastError = null; 865 866 for (let attempt = 1; attempt <= attempts; attempt++) { 867 const $wrapper = $('<div class="js-draw-saving" style="position: absolute; left: -10000px; top: 0;"></div>'); 868 const $clone = $(source).clone(); 869 $('body').append($wrapper); 870 $wrapper.append($clone); 871 872 const content = $wrapper.children()[0]; 873 874 try { 875 if (document.fonts && document.fonts.ready) { 876 await document.fonts.ready; 877 } 878 879 await html2PngWaitImages(content); 880 await html2PngInlineImages(content); 881 await html2PngWaitImages(content); 882 883 if (content.offsetWidth === 0 || content.offsetHeight === 0) { 884 throw new Error('Ð Ð°Ð·Ð¼ÐµÑ Ð¾Ð±Ð»Ð°ÑÑи Ð´Ð»Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ñавен 0'); 885 } 886 887 const dataUrl = await domtoimage.toPng(content); 888 889 if (await html2PngIsBlank(dataUrl, {hasLargeImage: html2PngHasLargeImage(content)})) { 890 throw new Error('ÐолÑÑилоÑÑ Ð¿ÑÑÑое изобÑажение'); 891 } 892 893 if (isDownload) { 894 const link = document.createElement('a'); 895 link.download = "export_" + Date.now() + ".png"; 896 link.href = dataUrl; 897 link.click(); 898 } 899 900 return dataUrl; 901 } catch (error) { 902 lastError = error; 903 console.warn('ÐовÑÐ¾Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±ÑажениÑ:', { 904 query: typeof query === 'string' ? query : source.className, 905 attempt: attempt, 906 error: error 907 }); 908 await html2PngWait(200 * attempt); 909 } finally { 910 $wrapper.remove(); 911 } 912 } 913 914 console.error('ÐÑибка пÑи ÑÐ¾Ñ Ñанении изобÑажениÑ:', lastError); 915 916 /*return await html2canvas(document.querySelector('.js-draw-saving ' + query), { 917 scrollX: 0, 918 scrollY: -window.scrollY, 919 letterRendering: 1, 920 allowTaint: true, 921 useCORS: true 922 }).then(canvas => { 923 $('.js-draw-saving').remove(); 924 let dataUrl = canvas.toDataURL("image/png"); 925 926 if(isDownload) { 927 const a = document.createElement("a"); 928 document.body.appendChild(a); 929 a.style = "display: none"; 930 a.href = dataUrl; 931 a.download = "export_" + Date.now() + ".png"; 932 a.click(); 933 document.body.removeChild(a); 934 } 935 936 return dataUrl; 937 });*/ 938 939 /*var node = document.querySelector(query); 940 var canvas = document.createElement("canvas"); 941 canvas.height = node.offsetHeight + 30; 942 canvas.width = node.offsetWidth + 30; 943 944 console.log(node.outerHTML) 945 946 return await rasterizeHTML.drawHTML(node.outerHTML, canvas) 947 .then(function (renderResult) { 948 if (navigator.msSaveBlob) { 949 window.navigator.msSaveBlob(canvas.msToBlob(), name); 950 } else { 951 let dataUrl = canvas.toDataURL(); 952 console.log(dataUrl) 953 if(isDownload) { 954 const a = document.createElement("a"); 955 document.body.appendChild(a); 956 a.style = "display: none"; 957 a.href = dataUrl; 958 a.download = "export_" + Date.now() + ".png"; 959 a.click(); 960 document.body.removeChild(a); 961 } 962 return dataUrl; 963 } 964 });*/ 965}; 966 967var lazyLoadInstance = new LazyLoad({});
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.