PageSourceSearch

https://adeniumhit.ru/assets/templates/site/js/cart.js?v=1.359

js adeniumhit.ru collected 2026-10-08 13:53:41 UTC 46,117 bytes, 1,258 lines download raw bytes

1$(document).ready(function() {
2    const default_city = 'Москва',
3          default_index = 101000,
4          form = $('#msOrder'),
5          index = form.find('input[name="index"]'),
6          city = form.find('input[name="city"]'),
7          street = form.find('input[name="street"]'),
8          building = form.find('input[name="building"]'),
9          headerHeight = $('header').outerHeight() + 20,
10          rupost_point = $('#msOrder').find('input[name="pvz_rupost"]'),
11          yandex_point = $('#msOrder').find('input[name="pvz_yandex"]'),
12          ozon_point = $('#msOrder').find('input[name="pvz_ozon"]'),
13          ozonAjaxUrl = '/ozon-ajax';
14      
15    let ozonMap = null,
16        ozonMapObjects = [],
17        ozonMapTimer = null,
18        ozonPhoneTimer = null,
19        ozonLastViewport = null,
20        ozonLastZoom = null,
21        ozonMapRequest = null,
22        ozonSelectTimers = [],
23        ozonPopupOpening = false,
24        ozonPopup = null,
25        ozonPhoneValid = false,
26        ozonValidatedPhone = '',
27        ozonPhoneChecking = false;
28    
29    $('input[name="phone"]').mask('+7 (999) 999-99-99');
30    function DisableDeliveries() {        
31        $('#msOrder input[name="delivery"]').not(':checked').closest('.grid-label').addClass('disabled-label');
32        setTimeout(() => {            
33            $('#msOrder input[name="delivery"]').not(':checked').closest('.grid-label').removeClass('disabled-label');                
34        }, 1500);
35    }
36    
37    function clearAddress() {
38        index.val('').trigger('change');
39        city.val('').trigger('change');
40        street.val('').trigger('change');
41        building.val('').trigger('change');
42        $('.delivery-widget-selected').remove();
43        $('.delivery-widget-cost').remove();
44    }
45
46    /*function getDeliveryStatus() {
47        let delivery = $('#msOrder input[name="delivery"]:checked').val();
48        $.post(document.location.href, {action: 'getDeliveryStatus', delivery:delivery}, function(data) {
49            if (!$('.delivery-widget-cost').length) {
50                $(`<div class="delivery-widget-cost"><b>Стоимость доставки: </b> ${data} ₽</div>`).insertAfter('.delivery-widget-selected');
51            } else {
52                $('.delivery-widget-cost').html(`<b>Стоимость доставки: </b> ${data} ₽`);
53            }
54        });
55    }*/
56
57    //Колбэк виджета Почта РФ    
58    function msrpData(data) {
59        //console.log(data);
60        index.val(data.indexTo).trigger('change');
61        setTimeout(() => {
62            city.val(data.cityTo).trigger('change');
63        }, 300);
64        if (data.location) {
65            setTimeout(() => {
66                street.val(data.location + ', ' + data.addressTo).trigger('change'); 
67            }, 450);
68        } else {
69            setTimeout(() => {
70                street.val(data.addressTo).trigger('change'); 
71            }, 450);
72        }
73        setTimeout(() => {
74            rupost_point.val(data.id).trigger('change');
75        }, 600);
76        if (!$('.delivery-widget-selected').length) {
77            $(`<div class="delivery-widget-selected">${data.indexTo}, ${data.cityTo}, ${data.addressTo}</div>`).insertAfter('#rupost-widget');
78        } else {
79            $('.delivery-widget-selected').text(data.indexTo +', '+ data.cityTo +', '+ data.addressTo);
80        }  
81        setTimeout(() => {
82            $('html, body').animate({ scrollTop: ($('#rupost-widget').offset().top - headerHeight)}, 600);
83        }, 500);
84        setTimeout(() => {
85            $.post(document.location.href, {action: 'getDeliveryStatus', delivery:31}, function(data) {
86                let resp = JSON.parse(data, true);
87                if (resp.intime) {
88                    if (!$('.delivery-widget-cost').length) {
89                        $(`<div class="delivery-widget-cost"><b>Примерная стоимость доставки: </b> ${resp.cost} ₽ (фактическая стоимость доставки может отличаться и оплачивается при получении)</div>`).insertAfter('.delivery-widget-selected');
90                    } else {
91                        $('.delivery-widget-cost').html(`<b>Примерная стоимость доставки: </b> ${resp.cost} ₽ (фактическая стоимость доставки может отличаться и оплачивается при получении)`);
92                    }
93                } else {
94                    if (!$('.delivery-widget-cost').length) {
95                        $(`<div class="delivery-widget-cost">Данный способ доставки не рекомендуется, так как сроки доставки превышают 11 суток и в таком случае мы не гарантируем сохранение качеств растений.</div>`).insertAfter('.delivery-widget-selected');
96                    } else {
97                        $('.delivery-widget-cost').html(`Данный способ доставки не рекомендуется, так как сроки доставки превышают 11 суток и в таком случае мы не гарантируем сохранение качеств растений.`);
98                    }
99                }            
100            });
101        }, 500);
102        /*if (typeof miniShop2 != 'undefined') {
103            miniShop2.Order.getcost();
104            miniShop2.Callbacks.Order.getcost.response.success = function(response) {
105                let delivery = $('input[name="delivery"]:checked').val();
106                if (delivery == 31) {
107                    if (!$('.delivery-widget-cost').length) {
108                        $(`<div class="delivery-widget-cost"><b>Стоимость доставки: </b> ${response.data.delivery_cost.toFixed(2)} ₽</div>`).insertAfter('.delivery-widget-selected');
109                    } else {
110                        $('.delivery-widget-cost').html(`<b>Стоимость доставки: </b> ${response.data.delivery_cost.toFixed(2)} ₽`);
111                    }
112                }
113            };         
114        }*/
115    }
116    
117    //Колбэк Яндекс виджет
118    document.addEventListener('YaNddWidgetPointSelected', function (data){
119        console.log(data);        
120        index.val(data.detail.address.postal_code).trigger('change');
121        setTimeout(() => {
122            yandex_point.val(data.detail.id).trigger('change');
123        }, 300);
124        setTimeout(() => {
125            city.val(data.detail.address.locality).trigger('change');
126        }, 450);
127        setTimeout(() => {
128            street.val(data.detail.address.street).trigger('change');
129        }, 600);
130        setTimeout(() => {
131            building.val(data.detail.address.house).trigger('change');
132        }, 750);
133        if (!$('.delivery-widget-selected').length) {
134            $(`<div class="delivery-widget-selected">${data.detail.address.locality}, ${data.detail.address.street}, ${data.detail.address.house}</div>`).insertAfter('#yandex-widget');
135        } else {
136            $('.delivery-widget-selected').text(data.detail.address.locality +', '+ data.detail.address.street +', '+ data.detail.address.house);
137        }       
138        setTimeout(() => {
139            $('html, body').animate({ scrollTop: ($('#yandex-widget').offset().top - headerHeight)}, 600);
140        }, 500);  
141        if (typeof miniShop2 != 'undefined') {
142            setTimeout(() => {
143                miniShop2.Order.getcost();
144            }, 800);
145            miniShop2.Callbacks.Order.getcost.response.success = function(response) {
146                let delivery = $('input[name="delivery"]:checked').val();
147                if (delivery == 58) {
148                    if (!$('.delivery-widget-cost').length) {
149                        $(`<div class="delivery-widget-cost"><b>Стоимость доставки: </b> ${response.data.delivery_cost.toFixed(2)} ₽</div>`).insertAfter('.delivery-widget-selected');
150                    } else {
151                        $('.delivery-widget-cost').html(`<b>Стоимость доставки: </b> ${response.data.delivery_cost.toFixed(2)} ₽`);
152                    }
153                }
154            };
155        }
156    });    
157
158    function startYandexWidget() {
159        let total_weight = total_cost = total_count = 0;
160        $('.cart__item').each(function() {
161            let weight = parseInt($(this).find('.basket__pruduct-item').attr('data-weight')) != 0 ? parseInt($(this).find('.basket__pruduct-item').attr('data-weight')) : 500,
162                price = parseInt($(this).find('.cart-item__cost').text()),
163                count = parseInt($(this).find('input[name="count"]').val());
164
165            total_weight += (weight * count);
166            total_cost += price;
167        }).promise().done(function() {
168            window.YaDelivery.createWidget({
169                containerId: 'yandex-widget',         // Идентификатор HTML-элемента (контейнера), в котором будет отображаться виджет
170                params: {
171                    city: default_city,                     // Город, отображаемый на карте при запуске
172                    size:{                              // Размеры виджета
173                        "height": "450px",              // Высота
174                        "width": "100%"                 // Ширина
175                    },
176                    source_platform_station: "2c5e91f8-073f-4dad-801e-0780ab1c768e",  // Станция отгрузки
177                    physical_dims_weight_gross: total_weight,  // Вес отправления
178                    delivery_price: "", // Стоимость доставки
179                    delivery_term: "",          // Срок доставки
180                    show_select_button: true,           // Отображение кнопки выбора ПВЗ (false — скрыть кнопку, true — показать кнопку)
181                    filter: {
182                        type: [                         // Тип способа доставки
183                            "pickup_point",             // Пункт выдачи заказа
184                        ],
185                        is_yandex_branded: false,       // Тип пункта выдачи заказа (false — Партнерские ПВЗ, true — ПВЗ Яндекса)
186                        payment_methods: [              // Способ оплаты
187                            "already_paid",             // Доступен для доставки предоплаченных заказов
188                        ],
189                        payment_methods_filter: "or"    // Фильтр по типам оплаты
190                    }
191                },
192            });
193            $(document).on('click', '.widget__list-button', function(e) {
194                e.preventDefault();
195            });            
196        });        
197    }
198    
199    function startRPWidget() {
200        let total_weight = total_cost = total_count = 0;
201        $('.cart__item').each(function() {
202            let weight = parseInt($(this).find('.basket__pruduct-item').attr('data-weight')) != 0 ? parseInt($(this).find('.basket__pruduct-item').attr('data-weight')) : 500,
203                price = parseInt($(this).find('.cart-item__cost').text()),
204                count = parseInt($(this).find('input[name="count"]').val());
205
206            total_weight += (weight * count);
207            total_cost += price;
208        }).promise().done(function() {
209            ecomStartWidget({
210                id: 52185,
211                startZip: default_index,
212                start_location: default_city,
213                weight: total_weight,
214                sumoc: total_cost * 100,
215                callbackFunction: msrpData,
216                containerId: 'rupost-widget'
217              });
218        });        
219    }
220    
221    //Ozon start
222    function clearOzonSelectTimers() {
223        $.each(ozonSelectTimers, function(k, timer) {
224            clearTimeout(timer);
225        });
226    
227        ozonSelectTimers = [];
228    }
229    function showOzonError(message) {
230        $('.ozon-delivery__error').text(message || '');
231    }
232    
233    function getOzonPhone() {
234        return $.trim(form.find('input[name="phone"]').val() || '');
235    }
236    
237    function normalizeOzonPhone(phone) {
238        return String(phone || '').replace(/\D/g, '');
239    }
240    
241    function isOzonPhoneComplete() {
242        return normalizeOzonPhone(getOzonPhone()).length === 11;
243    }
244    
245    function setOzonDeliveryAvailable(available) {
246        let item = $('#delivery_60').closest('.grid-label');
247    
248        item.toggleClass('ozon-phone-disabled', !available);
249    }
250    
251    function checkOzonPhone(callback, showError = true) {
252        let phone = getOzonPhone(),
253            normalizedPhone = normalizeOzonPhone(phone);
254    
255        if (!isOzonPhoneComplete()) {
256            ozonPhoneValid = false;
257            ozonValidatedPhone = '';
258    
259            setOzonDeliveryAvailable(false);
260    
261            if (typeof callback === 'function') {
262                callback(false);
263            }
264    
265            return;
266        }
267    
268        //Этот номер уже успешно проверяли
269        if (ozonPhoneValid && ozonValidatedPhone === normalizedPhone) {
270            setOzonDeliveryAvailable(true);
271            if (typeof callback === 'function') {
272                callback(true);
273            }
274            return;
275        }
276    
277        if (ozonPhoneChecking) {
278            return;
279        }
280    
281        ozonPhoneChecking = true;
282    
283        $.ajax({
284            url: ozonAjaxUrl,
285            type: 'POST',
286            dataType: 'json',
287            data: {
288                action: 'check',
289                phone: phone
290            }
291        }).done(function(response) {
292    
293            if (response.success && response.available) {
294                ozonPhoneValid = true;
295                ozonValidatedPhone = normalizedPhone;
296                
297                setOzonDeliveryAvailable(true);
298                
299                if (typeof callback === 'function') {
300                    callback(true);
301                }
302                return;
303            }
304    
305            ozonPhoneValid = false;
306            ozonValidatedPhone = '';
307    
308            setOzonDeliveryAvailable(false);
309    
310            if (showError) {
311                Swal.fire({
312                    icon: 'warning',
313                    title: 'Номер не подходит',
314                    html: 'Для Ozon Доставки укажите номер телефона, привязанный к вашему аккаунту Ozon.'
315                });
316            }
317    
318            if (typeof callback === 'function') {
319                callback(false);
320            }
321    
322        }).fail(function(xhr) {
323    
324            console.log('Ozon check error:', xhr.responseText);
325    
326            ozonPhoneValid = false;
327            ozonValidatedPhone = '';
328    
329            setOzonDeliveryAvailable(false);
330    
331            if (showError) {
332                Swal.fire({
333                    icon: 'error',
334                    title: 'Ошибка проверки',
335                    text: 'Не удалось проверить номер телефона в Ozon. Попробуйте ещё раз.'
336                });
337            }
338    
339            if (typeof callback === 'function') {
340                callback(false);
341            }
342    
343        }).always(function() {
344            ozonPhoneChecking = false;
345        });
346    }
347    
348    function startOzonWidget() {
349        let phone = getOzonPhone();
350    
351        showOzonError('');
352        $('#ozon-widget').addClass('loading');
353    
354        if (!phone) {
355            $('#ozon-widget').removeClass('loading');
356            showOzonError('Укажите номер телефона');
357            return;
358        }
359    
360        checkOzonPhone(function(valid) {
361    
362            if (!valid) {
363                $('#ozon-widget').removeClass('loading');
364                return;
365            }
366    
367            initOzonMap();
368    
369        }, true);
370    }
371    
372    function initOzonMap() {
373        if (ozonMap) {
374            setTimeout(() => {
375                ozonMap.invalidateSize();
376                loadOzonMapPoints();
377            }, 300);
378    
379            return;
380        }
381    
382        ozonMap = L.map('ozon-map', {
383            center: [55.755864, 37.617698],
384            zoom: 14,
385            zoomControl: false,
386            scrollWheelZoom: true
387        });
388        
389        L.control.zoom({
390            position: 'bottomright'
391        }).addTo(ozonMap);
392        
393        document.getElementById('ozon-map').addEventListener('wheel', function(e) {
394            e.preventDefault();
395        }, {
396            passive: false
397        });
398        
399        ozonPopup = L.popup({
400            offset: [0, -30]
401        });
402
403        L.maplibreGL({
404            style: 'https://tiles.openfreemap.org/styles/bright'
405        }).addTo(ozonMap);
406    
407        ozonMap.on('dragend', function() {
408            clearTimeout(ozonMapTimer);
409        
410            ozonMapTimer = setTimeout(function() {
411                loadOzonMapPoints();
412            }, 300);
413        });
414        
415        ozonMap.on('zoomend', function() {
416            clearTimeout(ozonMapTimer);
417        
418            ozonMapTimer = setTimeout(function() {
419                loadOzonMapPoints();
420            }, 300);
421        });
422    
423        $('#ozon-widget').removeClass('loading');
424    
425        setTimeout(() => {
426            ozonMap.invalidateSize();
427            loadOzonMapPoints(true);
428        }, 300);
429    }
430    
431    function getOzonViewport() {
432        if (!ozonMap) {
433            return false;
434        }
435    
436        let bounds = ozonMap.getBounds();
437    
438        return {
439            left_bottom: {
440                lat: bounds.getSouth(),
441                long: bounds.getWest()
442            },
443            right_top: {
444                lat: bounds.getNorth(),
445                long: bounds.getEast()
446            }
447        };
448    }
449    
450    function loadOzonMapPoints(force = false) {
451        if (!ozonMap) {
452            $('#ozon-widget').removeClass('loading');
453            return;
454        }
455    
456        let viewport = getOzonViewport(),
457            zoom = ozonMap.getZoom();
458    
459        if (!viewport) {
460            $('#ozon-widget').removeClass('loading');
461            return;
462        }
463    
464        if (ozonMapRequest) {
465            ozonMapRequest.abort();
466        }
467    
468        $('#ozon-widget').addClass('loading');
469    
470        ozonMapRequest = $.ajax({
471            url: ozonAjaxUrl,
472            type: 'POST',
473            dataType: 'json',
474            data: {
475                action: 'map',
476                zoom: zoom,
477                viewport: viewport
478            }
479        }).done(function(response) {
480            if (!response.success) {
481                showOzonError(response.message || 'Не удалось загрузить ПВЗ Ozon');
482                return;
483            }
484    
485            showOzonError('');
486            renderOzonClusters(response.clusters || []);
487        }).fail(function(xhr, status) {
488            if (status === 'abort') {
489                return;
490            }
491    
492            showOzonError('Ошибка загрузки ПВЗ Ozon');
493        }).always(function() {
494            ozonMapRequest = null;
495            $('#ozon-widget').removeClass('loading');
496        });
497    }
498    
499    function clearOzonMapObjects() {
500        if (!ozonMap) {
501            return;
502        }
503    
504        $.each(ozonMapObjects, function(k, object) {
505            ozonMap.removeLayer(object);
506        });
507    
508        ozonMapObjects = [];
509    }
510    
511    function renderOzonClusters(clusters) {
512        clearOzonMapObjects();
513    
514        if (!clusters.length) {
515            showOzonError('В этой области ПВЗ Ozon не найдены');
516            return;
517        }
518    
519        $.each(clusters, function(k, cluster) {
520            let coordinate = cluster.coordinate || {},
521                lat = parseFloat(String(coordinate.lat).replace(',', '.')),
522                long = parseFloat(String(coordinate.long).replace(',', '.')),
523                ids = cluster.map_point_ids || [],
524                count = parseInt(cluster.points_count, 10);
525    
526            if (isNaN(lat) || isNaN(long)) {
527                console.log('Ozon: неправильные координаты', cluster);
528                return;
529            }
530    
531            if (isNaN(count) || count <= 0) {
532                count = ids.length;
533            }
534    
535            if (ids.length == 1 && count <= 1) {
536                addOzonPoint([lat, long], ids[0]);
537            } else {
538                addOzonCluster([lat, long], cluster, count);
539            }
540        });
541    }
542    
543    function getOzonPointIcon(selected = false) {
544        return L.divIcon({
545            className: '',
546            html: `<div class="ozon-map-marker ${selected ? 'selected' : ''}"></div>`,
547            iconSize: [26, 34],
548            iconAnchor: [13, 34],
549            popupAnchor: [0, -34]
550        });
551    }
552    
553    function addOzonPoint(coords, mapPointId) {
554        let selected = String(ozon_point.val()) === String(mapPointId),
555            marker = L.marker(coords, {
556                icon: getOzonPointIcon(selected)
557            });
558    
559        marker.ozonPointId = String(mapPointId);
560    
561        marker.on('click', function() {
562            loadOzonPointInfo(mapPointId, marker);
563        });
564    
565        marker.addTo(ozonMap);
566        ozonMapObjects.push(marker);
567    }
568    
569    function updateOzonSelectedMarker(mapPointId) {
570        $.each(ozonMapObjects, function(k, object) {
571            if (!object.ozonPointId) {
572                return;
573            }
574    
575            object.setIcon(
576                getOzonPointIcon(
577                    String(object.ozonPointId) === String(mapPointId)
578                )
579            );
580        });
581    }
582    
583    function addOzonCluster(coords, cluster, count) {
584        let icon = L.divIcon({
585                className: '',
586                html: `<div class="ozon-map-cluster">${count}</div>`,
587                iconSize: [42, 42],
588                iconAnchor: [21, 21]
589            }),
590            marker = L.marker(coords, {
591                icon: icon
592            });
593    
594        marker.on('click', function() {
595            let ids = cluster.map_point_ids || [],
596                viewport = cluster.viewport || {},
597                zoom = ozonMap.getZoom();
598    
599            if (ids.length > 1 && (cluster.is_same_building || zoom >= 18)) {
600                loadOzonClusterPoints(ids, marker);
601                return;
602            }
603    
604            if (viewport.left_bottom && viewport.right_top) {
605                let south = parseFloat(String(viewport.left_bottom.lat).replace(',', '.')),
606                    west = parseFloat(String(viewport.left_bottom.long).replace(',', '.')),
607                    north = parseFloat(String(viewport.right_top.lat).replace(',', '.')),
608                    east = parseFloat(String(viewport.right_top.long).replace(',', '.'));
609    
610                let bounds = L.latLngBounds(
611                    [south, west],
612                    [north, east]
613                );
614    
615                /*
616                 * Иногда Ozon возвращает практически нулевой viewport.
617                 * fitBounds тогда визуально ничего не меняет.
618                 */
619                if (
620                    Math.abs(north - south) < 0.00001
621                    && Math.abs(east - west) < 0.00001
622                ) {
623                    if (ids.length > 1) {
624                        loadOzonClusterPoints(ids, marker);
625                    }
626    
627                    return;
628                }
629    
630                ozonMap.fitBounds(bounds, {
631                    padding: [30, 30],
632                    maxZoom: 18
633                });
634            } else if (ids.length > 1) {
635                loadOzonClusterPoints(ids, marker);
636            } else {
637                ozonMap.setView(
638                    coords,
639                    Math.min(zoom + 2, 19)
640                );
641            }
642        });
643    
644        marker.addTo(ozonMap);
645        ozonMapObjects.push(marker);
646    }
647    
648    function loadOzonClusterPoints(ids, marker) {
649        if (!ids.length) {
650            return;
651        }
652    
653        marker.bindPopup('Загрузка...').openPopup();
654    
655        let requests = [];
656    
657        $.each(ids, function(k, mapPointId) {
658            requests.push(
659                $.ajax({
660                    url: ozonAjaxUrl,
661                    type: 'POST',
662                    dataType: 'json',
663                    data: {
664                        action: 'point',
665                        map_point_id: mapPointId
666                    }
667                })
668            );
669        });
670    
671        $.when.apply($, requests).done(function() {
672            let responses = requests.length == 1
673                    ? [arguments]
674                    : arguments,
675                html = '<div class="ozon-cluster-points">';
676    
677            $.each(responses, function(k, result) {
678                let response = result[0];
679    
680                if (!response || !response.success || !response.point) {
681                    return;
682                }
683    
684                let point = response.point;
685    
686                html += `
687                    <div class="ozon-cluster-point">
688                        <div class="ozon-mp-title">
689                            <b>${point.name || 'Ozon'}</b>
690                        </div>
691                        <div class="ozon-mp-address">
692                            ${point.address || ''}
693                        </div>
694                        ${point.description ? `
695                            <div class="ozon-mp-desc">
696                                ${point.description}
697                            </div>
698                        ` : ''}
699                        <button type="button" class="btn btn-primary js-ozon-map-select" data-id="${point.map_point_id}">
700                            Выбрать
701                        </button>
702                    </div>
703                `;
704            });
705    
706            html += '</div>';
707    
708            marker.setPopupContent(html);
709        }).fail(function() {
710            marker.setPopupContent('Не удалось получить информацию о ПВЗ');
711        });
712    }
713
714    function loadOzonPointInfo(mapPointId, marker) {
715        if (!ozonMap || !ozonPopup) {
716            return;
717        }
718    
719        ozonPopup
720            .setLatLng(marker.getLatLng())
721            .setContent('Загрузка...')
722            .openOn(ozonMap);
723    
724        $.ajax({
725            url: ozonAjaxUrl,
726            type: 'POST',
727            dataType: 'json',
728            data: {
729                action: 'point',
730                map_point_id: mapPointId
731            }
732        }).done(function(response) {
733            if (!response.success) {
734                ozonPopup.setContent(
735                    response.message || 'Не удалось получить информацию о ПВЗ'
736                );
737                return;
738            }
739    
740            let point = response.point,
741                html = `
742                    <div class="ozon-map-point">
743                        <div class="ozon-mp-title"><b>${point.name || 'Ozon'}</b></div>
744                        <div class="ozon-mp-address">${point.address || ''}</div>
745                        ${point.description ? `<div class="ozon-mp-desc">${point.description}</div>` : ''}
746                        ${point.storage_period ? `<div class="ozon-mp-period">Срок хранения: ${point.storage_period}</div>` : ''}
747                        <button type="button" class="btn btn-primary js-ozon-map-select" data-id="${point.map_point_id}">
748                            Выбрать
749                        </button>
750                    </div>
751                `;
752    
753            ozonPopup.setContent(html);
754        }).fail(function() {
755            ozonPopup.setContent('Ошибка получения информации о ПВЗ');
756        });
757    }
758    
759    $(document).on('click', '.js-ozon-map-select', function(e) {
760        e.preventDefault();
761    
762        let button = $(this),
763            mapPointId = button.attr('data-id');
764    
765        if (!mapPointId) {
766            return;
767        }
768    
769        button.prop('disabled', true);
770    
771        $.ajax({
772            url: ozonAjaxUrl,
773            type: 'POST',
774            dataType: 'json',
775            data: {
776                action: 'selectPoint',
777                map_point_id: mapPointId
778            }
779        }).done(function(response) {
780            if (!response.success) {
781                showOzonError(response.message || 'Не удалось выбрать ПВЗ Ozon');
782                return;
783            }
784    
785            let point = response.point;
786            clearOzonSelectTimers();
787
788            ozon_point.val(point.map_point_id);
789            updateOzonSelectedMarker(point.map_point_id);
790            
791            form.find('input[name="phone"]').prop('readonly', true);
792            $('.ozon-phone-control').remove();
793            form.find('input[name="phone"]')
794                .closest('.input-parent')
795                .append(
796                    '<div class="ozon-phone-control">' +
797                        '<span>Номер зафиксирован для Ozon Доставки</span>' +
798                        '<button type="button" class="ozon-change-phone">Изменить номер</button>' +
799                    '</div>'
800                );
801            
802            $('.delivery-widget-selected').remove();
803            $('.delivery-widget-cost').remove();
804            
805            $(`<div class="delivery-widget-selected"></div>`)
806                .text((point.name ? point.name + ': ' : '') + (point.address || ''))
807                .insertAfter('#ozon-widget');
808            
809            if (ozonMap) {
810                ozonMap.closePopup();
811            }
812            ozonSelectTimers.push(setTimeout(() => {
813                street.val(point.street || point.address || '').trigger('change');
814            }, 300));
815            
816            ozonSelectTimers.push(setTimeout(() => {
817                city.val(point.city || '').trigger('change');
818            }, 600));
819            
820            ozonSelectTimers.push(setTimeout(() => {
821                ozon_point.trigger('change');
822            }, 900));
823            
824            ozonSelectTimers.push(setTimeout(() => {
825                calculateOzonDelivery();
826            }, 1300));
827        }).fail(function() {
828            showOzonError('Ошибка выбора ПВЗ Ozon');
829        }).always(function() {
830            button.prop('disabled', false);
831        });
832    });
833    
834    function calculateOzonDelivery() {
835        let phone = getOzonPhone();
836    
837        if (!phone || !ozon_point.val()) {
838            return;
839        }
840    
841        $('.cart-body').addClass('loading');
842    
843        $.ajax({
844            url: ozonAjaxUrl,
845            type: 'POST',
846            dataType: 'json',
847            data: {
848                action: 'checkout',
849                phone: phone
850            }
851        }).done(function(response) {
852            if (!response.success) {
853                showOzonError(response.message || 'Не удалось рассчитать Ozon Доставку');
854                return;
855            }
856    
857            showOzonError('');
858    
859            $('.delivery-widget-cost').remove();
860    
861            $(`<div class="delivery-widget-cost"><b>Стоимость доставки: </b> ${parseFloat(response.client_cost).toFixed(2)} ₽</div>`)
862                .insertAfter('.delivery-widget-selected');
863    
864            if (typeof miniShop2 != 'undefined') {
865                miniShop2.Order.getcost();
866            }
867        }).fail(function() {
868            showOzonError('Ошибка расчёта Ozon Доставки');
869        }).always(function() {
870            $('.cart-body').removeClass('loading');
871        });
872    }
873    
874    function searchOzonAddress() {
875        let query = $.trim($('#ozon-map-search').val());
876    
877        if (!query) {
878            return;
879        }
880    
881        $('#ozon-map-search-btn').prop('disabled', true);
882        showOzonError('');
883    
884        $.ajax({
885            url: 'https://nominatim.openstreetmap.org/search',
886            type: 'GET',
887            dataType: 'json',
888            data: {
889                q: query,
890                format: 'json',
891                limit: 1,
892                countrycodes: 'ru'
893            }
894        }).done(function(response) {
895            if (!response.length) {
896                showOzonError('Адрес не найден');
897                return;
898            }
899    
900            let lat = parseFloat(response[0].lat),
901                long = parseFloat(response[0].lon);
902    
903            if (isNaN(lat) || isNaN(long)) {
904                showOzonError('Не удалось определить координаты');
905                return;
906            }
907    
908            ozonLastViewport = null;
909            ozonLastZoom = null;
910    
911            ozonMap.setView([lat, long], 14);
912    
913            setTimeout(() => {
914                loadOzonMapPoints(true);
915            }, 300);
916        }).fail(function() {
917            showOzonError('Ошибка поиска адреса');
918        }).always(function() {
919            $('#ozon-map-search-btn').prop('disabled', false);
920        });
921    }
922    
923    $(document).on('click', '.ozon-change-phone', function(e) {
924        e.preventDefault();
925    
926        $.post(ozonAjaxUrl, {
927            action: 'invalidate'
928        });
929    
930        clearOzonSelectTimers();
931    
932        ozonPhoneValid = false;
933        ozonValidatedPhone = '';
934    
935        ozon_point.val('').trigger('change');
936    
937        $('.delivery-widget-selected').remove();
938        $('.delivery-widget-cost').remove();
939    
940        if (ozonMap) {
941            ozonMap.closePopup();
942        }
943    
944        updateOzonSelectedMarker('');
945    
946        form.find('input[name="phone"]')
947            .prop('readonly', false)
948            .focus();
949    
950        $('.ozon-phone-control').remove();
951    
952        setOzonDeliveryAvailable(false);
953    
954        showOzonError(
955            'После изменения номера необходимо заново выбрать пункт выдачи Ozon.'
956        );
957    });
958
959    $(document).on('click', '#ozon-map-search-btn', function() {
960        searchOzonAddress();
961    });
962    
963    $(document).on('keydown', '#ozon-map-search', function(e) {
964        if (e.key === 'Enter') {
965            e.preventDefault();
966            searchOzonAddress();
967        }
968    });
969    
970    $(document).on('blur', '#msOrder input[name="phone"]', function() {
971        if (!isOzonPhoneComplete()) {
972            ozonPhoneValid = false;
973            ozonValidatedPhone = '';
974            setOzonDeliveryAvailable(false);
975            return;
976        }
977    
978        checkOzonPhone(function(valid) {}, true);
979    });
980    
981    $(document).on('input', '#msOrder input[name="phone"]', function() {
982        let currentPhone = normalizeOzonPhone(getOzonPhone());
983        if (ozonValidatedPhone && currentPhone !== ozonValidatedPhone) {
984            ozonPhoneValid = false;
985            ozonValidatedPhone = '';
986            setOzonDeliveryAvailable(false);
987        }
988        
989        if ($('input[name="delivery"]:checked').val() != 60) {
990            return;
991        }
992    
993        clearTimeout(ozonPhoneTimer);
994    
995        ozonPhoneTimer = setTimeout(function() {
996            $.post(ozonAjaxUrl, {
997                action: 'invalidate'
998            });
999    
1000            ozon_point.val('');
1001            $('.delivery-widget-selected').remove();
1002            $('.delivery-widget-cost').remove();
1003    
1004            startOzonWidget();
1005        }, 700);
1006    });
1007    
1008    $(document).on('click', '.delivery_60.ozon-phone-disabled label', function(e) {
1009        e.preventDefault();
1010        e.stopImmediatePropagation();
1011    
1012        if (!isOzonPhoneComplete()) {
1013            Swal.fire({
1014                icon: 'info',
1015                title: 'Укажите номер телефона',
1016                html: 'Для Ozon Доставки сначала укажите номер телефона, привязанный к вашему аккаунту Ozon.'
1017            });
1018    
1019            form.find('input[name="phone"]').focus();
1020    
1021            return false;
1022        }
1023    
1024        checkOzonPhone(function(valid) {
1025    
1026            if (valid) {
1027                // После успешной проверки выбираем Ozon программно.
1028                $('#delivery_60')
1029                    .prop('checked', true)
1030                    .trigger('change');
1031            }
1032    
1033        }, true);
1034    
1035        return false;
1036    });
1037
1038    $(document).on('change', 'input[name="delivery"]', function() {
1039        let delivery = $('input[name="delivery"]:checked').val();
1040    
1041        $('.delivery-widget-selected').remove();
1042        $('.delivery-widget-cost').remove();
1043    
1044        if (delivery == 58) {
1045            clearAddress();
1046    
1047            rupost_point.val('').trigger('change');
1048            ozon_point.val('').trigger('change');
1049    
1050            startYandexWidget();
1051    
1052            setTimeout(() => {
1053                $('#rupost-widget').hide().html('');
1054                $('#ozon-widget').hide();
1055                $('#yandex-widget').show().addClass('loading');
1056                $('html, body').animate({scrollTop: $('#yandex-widget').offset().top - headerHeight}, 600);
1057            }, 1000);
1058    
1059            setTimeout(() => {
1060                startYandexWidget();
1061            }, 3000);
1062    
1063            setTimeout(() => {
1064                $('#yandex-widget').removeClass('loading');
1065            }, 5000);
1066    
1067            $('.yandex_check').show();
1068            $('.rupost_check').hide();
1069            $('.ozon_check').hide();
1070    
1071        } else if (delivery == 31) {
1072            clearAddress();
1073    
1074            yandex_point.val('').trigger('change');
1075            ozon_point.val('').trigger('change');
1076    
1077            startRPWidget();
1078    
1079            setTimeout(() => {
1080                $('#yandex-widget').hide().html('');
1081                $('#ozon-widget').hide();
1082                $('#rupost-widget').show().addClass('loading');
1083                $('html, body').animate({scrollTop: $('#rupost-widget').offset().top - headerHeight}, 600);
1084            }, 1000);
1085    
1086            setTimeout(() => {
1087                $('#rupost-widget').removeClass('loading');
1088            }, 3000);
1089    
1090            $('.rupost_check').show();
1091            $('.yandex_check').hide();
1092            $('.ozon_check').hide();
1093    
1094        } else if (delivery == 60) {
1095            rupost_point.val('').trigger('change');
1096            yandex_point.val('').trigger('change');
1097    
1098            $('#yandex-widget').hide().html('');
1099            $('#rupost-widget').hide().html('');
1100            $('#ozon-widget').show();
1101    
1102            $('.ozon_check').show();
1103            $('.yandex_check').hide();
1104            $('.rupost_check').hide();
1105    
1106            setTimeout(() => {
1107                startOzonWidget();
1108                $('html, body').animate({scrollTop: $('#ozon-widget').offset().top - headerHeight}, 600);
1109            }, 500);
1110    
1111        } else {
1112            rupost_point.val('').trigger('change');
1113            yandex_point.val('').trigger('change');
1114            ozon_point.val('').trigger('change');
1115    
1116            $('#yandex-widget').hide().html('');
1117            $('#rupost-widget').hide().html('');
1118            $('#ozon-widget').hide();
1119    
1120            $('.yandex_check').hide();
1121            $('.rupost_check').hide();
1122            $('.ozon_check').hide();
1123        }
1124    
1125        DisableDeliveries();
1126    });
1127    /*$(document).on('change', 'input[name="delivery"]', function() {
1128        clearAddress();        
1129        if ($('input[name="delivery"]:checked').val() == 58) {
1130            rupost_point.val('').trigger('change');
1131            startYandexWidget();
1132            setTimeout(() => {
1133                $('#rupost-widget').hide();
1134                $('#rupost-widget').html('');
1135                $('#yandex-widget').show().addClass('loading');
1136                $('html, body').animate({ scrollTop: $('#yandex-widget').offset().top - headerHeight}, 600);
1137            }, 1000);
1138            setTimeout(() => {
1139                startYandexWidget();
1140            }, 3000);
1141            setTimeout(() => {
1142                $('#yandex-widget').removeClass('loading');
1143            }, 5000);
1144            $('.yandex_check').show();
1145            $('.rupost_check').hide();
1146        } else if ($('input[name="delivery"]:checked').val() == 31) {
1147            yandex_point.val('').trigger('change');
1148            startRPWidget();
1149            setTimeout(() => {
1150                $('#yandex-widget').hide();
1151                $('#yandex-widget').html('');
1152                $('#rupost-widget').show().addClass('loading');
1153                $('html, body').animate({ scrollTop: $('#rupost-widget').offset().top - headerHeight}, 600);
1154            }, 1000);
1155            setTimeout(() => {
1156                $('#rupost-widget').removeClass('loading');
1157            }, 3000);
1158            $('.rupost_check').show();
1159            $('.yandex_check').hide();
1160        } else {
1161            rupost_point.val('').trigger('change');
1162            yandex_point.val('').trigger('change');
1163            $('#yandex-widget').hide();
1164            $('#yandex-widget').html('');
1165            $('#rupost-widget').hide();
1166            $('#rupost-widget').html('');
1167            $('.yandex_check').hide();
1168            $('.rupost_check').hide();            
1169        }
1170        DisableDeliveries();
1171    });*/
1172    
1173    if ($('input[name="delivery"]:checked').val() == 58) {
1174        setTimeout(() => {
1175            startYandexWidget();
1176            $('#yandex-widget').show();
1177            $('html, body').animate({ scrollTop: $('#yandex-widget').offset().top - headerHeight}, 600);
1178        }, 1000);
1179    }
1180    if ($('input[name="delivery"]:checked').val() == 31) {
1181        setTimeout(() => {
1182            startRPWidget();
1183            $('#rupost-widget').show();
1184            $('html, body').animate({ scrollTop: $('#rupost-widget').offset().top - headerHeight}, 600);
1185        }, 1000);
1186    }
1187    if ($('input[name="delivery"]:checked').val() == 60) {
1188        setTimeout(() => {
1189            $('#ozon-widget').show();
1190            startOzonWidget();
1191            $('html, body').animate({scrollTop: $('#ozon-widget').offset().top - headerHeight}, 600);
1192        }, 1000);
1193    }
1194    
1195    function toggleCheckoutOptions() {
1196        let receiver = $.trim(form.find('input[name="receiver"]').val()),
1197            phone = $.trim(form.find('input[name="phone"]').val()),
1198            disabled = !receiver || !phone;
1199    
1200        $('#deliveries label, #payments label').toggleClass('inactive-label', disabled);
1201    
1202        if (!disabled) {
1203            $('.checkout-required-message').remove();
1204        }
1205    }
1206    
1207    function showCheckoutRequiredMessage(label) {
1208        let fields = [];
1209    
1210        if (!$.trim(form.find('input[name="receiver"]').val())) {
1211            fields.push('ФИО');
1212        }
1213    
1214        if (!$.trim(form.find('input[name="phone"]').val())) {
1215            fields.push('телефон');
1216        }
1217    
1218        $('.checkout-required-message').remove();
1219    
1220        let message = $('<div class="checkout-required-message"></div>')
1221            .text('Сначала заполните: ' + fields.join(', '))
1222            .hide();
1223    
1224        label.after(message);
1225    
1226        message.fadeIn(200);
1227    
1228        clearTimeout(window.checkoutRequiredTimer);
1229    
1230        window.checkoutRequiredTimer = setTimeout(function() {
1231            message.fadeOut(200, function() {
1232                $(this).remove();
1233            });
1234        }, 4000);
1235    }
1236    
1237    toggleCheckoutOptions();
1238    
1239    $(document).on('input change', '#msOrder input[name="receiver"], #msOrder input[name="phone"]', function() {
1240        toggleCheckoutOptions();
1241    });
1242    
1243    $(document).on('click', '#deliveries label.inactive-label, #payments label.inactive-label', function(e) {
1244        e.preventDefault();
1245        e.stopImmediatePropagation();
1246    
1247        showCheckoutRequiredMessage($(this));
1248    
1249        return false;
1250    });
1251    if (isOzonPhoneComplete()) {
1252        checkOzonPhone(function(valid) {
1253            setOzonDeliveryAvailable(valid);
1254        }, false);
1255    } else {
1256        setOzonDeliveryAvailable(false);
1257    }
1258});

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.