PageSourceSearch

https://klubki-v-korzinke.ru/wa-apps/shop/plugins/buy1click2/js/buy1click2.js?v=1.5.9

js klubki-v-korzinke.ru collected 2026-10-04 00:13:50 UTC 93,509 bytes, 1,981 lines download raw bytes

1(function ($) {
2    $(function () {
3        let config = window.shop_buy1click2_config;
4        const dadata = window.shop_buy1click2_dadata;
5        let services = {};
6
7        var Button = function ($button) {
8            var self = {
9                init: function () {
10                    $button.addClass('buy1click2-open-button_init');
11
12                    $button.on('click', function () {
13                        self.fetchForm();
14                    });
15
16                    var $form = self.getForm();
17
18                    if ($form) {
19                        $($form.get(0).elements).on('change', function () {
20                            self.updateVisible();
21                            self.updateDisabled();
22                        });
23                    }
24
25                    self.updateVisible();
26                    self.updateDisabled();
27                },
28                isInit: function () {
29                    return $button.hasClass('buy1click2-open-button_init');
30                },
31                getType: function () {
32                    return $button.data('type');
33                },
34                getProfileId: function () {
35                    return $button.data('profile');
36                },
37                getForm: function () {
38                    if (self.getType() != 'item') {
39                        return null;
40                    }
41
42                    var $form = $($button.get(0).form);
43
44                    if ($form.length !== 0) {
45                        return $form;
46                    }
47
48                    $form = $();
49
50                    $('input[name="product_id"]').each(function () {
51                        if ($(this).val() != $button.data('product_id')) {
52                            return;
53                        }
54
55                        $form = $form.add($(this.form));
56
57                        return false;
58                    });
59
60                    if ($form.length === 1) {
61                        return $form;
62                    }
63
64                    return null;
65                },
66                getFormProperty: function (property) {
67                    var $form = self.getForm();
68
69                    if ($form == null) {
70                        return null;
71                    }
72
73                    var element_property = $form.get(0).elements[property];
74
75                    if (!element_property) {
76                        return null;
77                    }
78
79                    if (Object.prototype.isPrototypeOf.call(HTMLCollection.prototype, element_property)) {
80                        return $(element_property).filter(':checked').val();
81                    } else {
82                        return element_property.value;
83                    }
84                },
85                getSkuID: function () {
86                    if (self.getType() != 'item') {
87                        return null;
88                    }
89
90                    var sku_id = self.getFormProperty('sku_id');
91
92                    if (sku_id) {
93                        return sku_id;
94                    }
95
96                    sku_id = $button.data('sku_id');
97
98                    if (sku_id) {
99                        return sku_id;
100                    }
101
102                    return $button.data('default_sku_id');
103                },
104                getProductID: function () {
105                    if (self.getType() != 'item') {
106                        return null;
107                    }
108
109                    var product_id = self.getFormProperty('product_id');
110
111                    if (product_id) {
112                        return product_id;
113                    }
114
115                    product_id = $button.data('product_id');
116
117                    if (product_id) {
118                        return product_id;
119                    }
120
121                    return null;
122                },
123                getOrderCountMin: function () {
124                    let order_count_min = parseFloat($button.data('order_count_min'));
125
126                    if (order_count_min) {
127                        return order_count_min;
128                    }
129
130                    return null;
131                },
132                getQuantity: function () {
133                    if (self.getType() != 'item') {
134                        return null;
135                    }
136
137                    const order_count_min = self.getOrderCountMin() || 0;
138                    const quantity = self.getFormProperty('quantity') || 0;
139
140                    return Math.max(quantity, order_count_min);
141                },
142                getFeatures: function () {
143                    var $form = self.getForm();
144
145                    if ($form == null) {
146                        return null;
147                    }
148
149                    var nameRegexp = /^features\[(\d+)]$/;
150                    var features = [];
151                    var elements = $form.first().serializeArray();
152
153                    for (var i = 0; i < elements.length; i++) {
154                        var element = elements[i];
155                        var matches = nameRegexp.exec(element.name);
156
157                        if (!matches) {
158                            continue;
159                        }
160
161                        var feature_id = matches[1];
162                        var feature_value_id = element.value;
163                        features.push({
164                            feature_id: feature_id,
165                            feature_value_id: feature_value_id
166                        });
167                    }
168
169                    if (features.length == 0) {
170                        return null;
171                    }
172
173                    return features;
174                },
175                getServices: function () {
176                    let $form = self.getForm();
177
178                    if ($form == null) {
179                        return null;
180                    }
181
182                    let service_ids = $($form.get(0).elements['services[]']);
183
184                    if (!service_ids.length) {
185                        return [];
186                    }
187
188                    let services = [];
189
190                    service_ids.each(function () {
191                        if (!this.checked) {
192                            return;
193                        }
194
195                        let service_id = this.value;
196                        let service_variant_id = $($form.get(0).elements['service_variant[' + service_id + ']']).val();
197                        services.push({
198                            service_id: service_id,
199                            service_variant_id: service_variant_id
200                        });
201                    });
202
203                    return services;
204                },
205                isDisabled: function () {
206                    var is_loading = $button.data('is_loading');
207
208                    if (is_loading) {
209                        return true;
210                    }
211
212                    var sku_available = $button.data('sku_available');
213
214                    if (!sku_available) {
215                        return false;
216                    }
217
218                    var features = self.getFeatures();
219                    var sku_id = self.getSkuID();
220                    var key = null;
221
222                    if (features) {
223                        key = features.map(function (feature) {
224                            return feature.feature_id + ':' + feature.feature_value_id + ';';
225                        }).join('');
226                    } else if (sku_id) {
227                        key = sku_id;
228                    }
229
230                    if (key) {
231                        return !sku_available[key];
232                    }
233
234                    return true;
235                },
236                isVisible: function () {
237                    const skus_show_by_price_range = $button.data('skus_show_by_price_range');
238
239                    if (!skus_show_by_price_range) {
240                        return true;
241                    }
242
243                    const sku_id = self.getSkuID();
244
245                    if (sku_id) {
246                        return skus_show_by_price_range[sku_id];
247                    }
248
249                    return true;
250                },
251                loading: function () {
252                    $button.data('is_loading', true);
253                    $button.addClass('buy1click2-open-button_loading');
254                    self.updateDisabled();
255                },
256                loadingEnd: function () {
257                    $button.data('is_loading', false);
258                    $button.removeClass('buy1click2-open-button_loading');
259                    self.updateDisabled();
260                },
261                updateDisabled: function () {
262                    $button.prop('disabled', self.isDisabled());
263                },
264                updateVisible: function () {
265                    const value = self.isVisible() ? 'block' : 'none';
266                    $button.css('display', value);
267                },
268                fetchForm: function () {
269                    self.loading();
270
271                    var promise = null;
272                    var profile_id = self.getProfileId();
273
274                    if (self.getType() == 'item') {
275                        const sku_id = self.getSkuID();
276                        const features = self.getFeatures();
277                        const product_id = self.getProductID();
278
279                        if (features) {
280                            promise = FormStorage.fetchByItemFeatures(
281                                profile_id,
282                                product_id,
283                                features,
284                                self.getServices(),
285                                self.getQuantity()
286                            );
287                        } else if (sku_id) {
288                            promise = FormStorage.fetchByItemSkuID(
289                                profile_id,
290                                sku_id,
291                                self.getServices(),
292                                self.getQuantity()
293                            );
294                        } else if (product_id) {
295                            promise = FormStorage.fetchByItemProductID(
296                                profile_id,
297                                product_id,
298                                self.getServices(),
299                                self.getQuantity()
300                            );
301                        }
302                    } else {
303                        promise = FormStorage.fetchByCart(profile_id);
304                    }
305
306                    promise.then(function () {
307                        self.loadingEnd();
308                    }, function () {
309                        self.loadingEnd();
310                    });
311                }
312            };
313
314            return self;
315        };
316
317        var FormStorage = (function () {
318            var self = {
319                current_fetch: null,
320                fetch: function (data) {
321                    if (self.current_fetch != null) {
322                        return;
323                    }
324
325                    return $.ajax({
326                        url: config.form_url,
327                        type: 'post',
328                        data: data,
329                        dataType: 'json',
330                        beforeSend: function (xhr) {
331                            self.current_fetch = xhr;
332                        }
333                    }).then(function (response) {
334                        self.current_fetch = null;
335
336                        var $form = $(response.data.html).filter('.buy1click2-form');
337                        var form = Form($form);
338                        form.init(response.data.state);
339                        form.reachGoal('open_form');
340
341                        return response;
342                    }, function () {
343                        self.current_fetch = null;
344                    });
345                },
346                fetchByItemSkuID: function (profile_id, sku_id, services, quantity) {
347                    return self.fetch({
348                        type: 'item',
349                        profile: profile_id,
350                        item: {
351                            sku_id: sku_id,
352                            quantity: quantity,
353                            services: services
354                        }
355                    });
356                },
357                fetchByItemFeatures: function (profile_id, product_id, features, services, quantity) {
358                    return self.fetch({
359                        type: 'item',
360                        profile: profile_id,
361                        item: {
362                            product_id: product_id,
363                            quantity: quantity,
364                            features: features,
365                            services: services
366                        }
367                    });
368                },
369                fetchByItemProductID: function (profile_id, product_id, services, quantity) {
370                    return self.fetch({
371                        type: 'item',
372                        profile: profile_id,
373                        item: {
374                            product_id: product_id,
375                            quantity: quantity,
376                            services: services
377                        }
378                    });
379                },
380                fetchByCart: function (profile_id) {
381                    return self.fetch({
382                        type: 'cart',
383                        profile: profile_id
384                    });
385                }
386            };
387
388            return self;
389        })();
390
391        var Form = function ($form) {
392            var self = {
393                ping_interval_id: null,
394                current_update: null,
395                current_send: null,
396                mobile_media: '(max-width: 520px)',
397                scroll_position: 0,
398                init: function (state) {
399                    self.setState(state);
400
401                    /*
402                        Яндекс.Советник восстанавливает удалённые из body элементы.
403                        Из-за этого, после закрытия формы, она появлась снова
404                        при включенном плагине Яндекс.Советник.
405                        Решено было добавить обёртку в body, внутри которой будем мы будем манипулировать DOM.
406                        На изменения DOM в такой обёртке Яндекс.Советник реагировать не будет.
407                     */
408                    let $container = $('.buy1click2-container');
409
410                    if (!$container.length) {
411                        $container = $('<div class="buy1click2-container"></div>');
412                        $(document.body).append($container);
413                    }
414
415                    $container.append($form);
416                    let $html = $('html');
417
418                    if (window.matchMedia(self.mobile_media).matches) {
419                        self.scroll_position = $(window).scrollTop();
420                        $html.css('top', -self.scroll_position + 'px');
421                    }
422
423                    $html.addClass('buy1click2-body');
424
425                    $form.on('mousedown', function (e) {
426                        var is_outside_scrollbar_area = window.innerWidth - e.pageX > 20;
427
428                        if (is_outside_scrollbar_area && $(e.target).closest('.buy1click2-form__content').length === 0 && e.button === 0) {
429                            self.close();
430                        }
431                    });
432
433                    $form.find('.buy1click2-form__close-button').on('click', function () {
434                        self.close();
435                    });
436
437                    self.Items.init();
438                    self.ContactInfo.init();
439                    self.Shipping.init();
440                    self.Payments.init();
441                    self.Coupon.init();
442                    self.Comment.init();
443                    self.Policy.init();
444                    self.Captcha.init();
445                    self.Submit.init();
446                    // self.ContactConfirmation.init();
447
448                    self.ping_interval_id = setInterval(function () {
449                        self.ping();
450                    }, 10 * 1000);
451
452                    self.refresh();
453                },
454                getState: function () {
455                    return $form.data('state');
456                },
457                setState: function (state) {
458                    $form.data('state', state);
459                },
460                render: function (html) {
461                    $form.find('.buy1click2-form__content').replaceWith($(html).find('.buy1click2-form__content'));
462                },
463                close: function () {
464                    return $.ajax({
465                        url: config.close_form_url,
466                        type: 'post',
467                        data: {
468                            state: JSON.stringify(self.getState())
469                        },
470                        dataType: 'json'
471                    }).then(function () {
472                        self.destroy();
473                        $form.remove();
474                        let $html = $('html');
475                        $html.removeClass('buy1click2-body');
476
477                        if (window.matchMedia(self.mobile_media).matches) {
478                            $html.css('top', '');
479                            $(window).scrollTop(self.scroll_position);
480                        }
481                    });
482                },
483                destroy: function () {
484                    clearInterval(self.ping_interval_id);
485                },
486                ping: function () {
487                    return $.ajax({
488                        url: config.ping_form_url,
489                        type: 'post',
490                        data: {
491                            state: JSON.stringify(self.getState())
492                        },
493                        dataType: 'json'
494                    });
495                },
496                update: function (external) {
497                    external = external || false;
498                    self.abortUpdate();
499
500                    if (self.current_send != null) {
501                        return;
502                    }
503
504                    return $.ajax({
505                        url: config.update_form_url,
506                        type: 'post',
507                        data: {
508                            state: JSON.stringify(self.getState()),
509                            external: external
510                        },
511                        dataType: 'json',
512                        beforeSend: function (xhr) {
513                            self.current_update = xhr;
514                        }
515                    }).then(function (response) {
516                        self.current_update = null;
517
518                        if (response.data.state) {
519                            var state = response.data.state;
520                            state.errors = response.data.state.errors;
521                            self.setState(state);
522                            self.Items.render(response.data.html);
523                            self.ContactInfo.render(response.data.html);
524                            self.Shipping.render(response.data.html, external);
525                            self.Payments.render(response.data.html);
526                            self.Coupon.render(response.data.state.session.coupon_active);
527                            self.Confirmation.render(response.data.html);
528                            self.Submit.updateState();
529                        }
530                    }, function (xhr, text_status, error_thrown) {
531                        if (text_status == 'abort') {
532                            return;
533                        }
534
535                        self.Shipping.loadingEnd();
536                        self.Payments.loadingEnd();
537                        self.Confirmation.loadingEnd();
538                        console.error(error_thrown);
539                    });
540                },
541                abortUpdate: function () {
542                    if (self.current_update != null) {
543                        self.current_update.abort();
544                        self.current_update = null;
545                    }
546                },
547                send: function () {
548                    if (self.current_send != null) {
549                        return;
550                    }
551
552                    self.abortUpdate();
553
554                    self.Submit.loading();
555                    self.Submit.disable();
556                    var dfd = $.Deferred();
557
558                    setTimeout(function () {
559                        $.ajax({
560                            url: config.send_form_url,
561                            type: 'post',
562                            data: $.extend({
563                                state: JSON.stringify(self.getState())
564                            }, self.Captcha.getData()),
565                            dataType: 'json',
566                            beforeSend: function (xhr) {
567                                self.current_send = xhr;
568                            }
569                        }).then(function (response) {
570                            if (response.data.redirect_url) {
571                                self.reachGoal('send_form');
572
573                                if (window.shop_buy1step_jquery) {
574                                    window.shop_buy1step_jquery('.buy1step-form').each(function (index, _form) {
575                                        var form = window.shop_buy1step_jquery(_form).data('buy1step');
576
577                                        if (form && form.destroyExitConfirm) {
578                                            form.destroyExitConfirm();
579                                        }
580                                    });
581                                }
582
583                                window.location = response.data.redirect_url;
584
585                                return;
586                            }
587
588                            self.current_send = null;
589
590                            self.Submit.loadingEnd();
591                            self.render(response.data.html);
592                            self.destroy();
593                            self.init(response.data.state);
594
595                            var state = self.getState();
596
597                            if (state.errors.confirm_channel) {
598                                self.ContactConfirmation.init();
599                            } else {
600                                self.reachGoal('send_fail_form');
601                            }
602                        }, function (xhr, text_status, error_thrown) {
603                            self.current_send = null;
604
605                            self.Shipping.loadingEnd();
606                            self.Payments.loadingEnd();
607                            self.Confirmation.loadingEnd();
608                            self.Submit.loadingEnd();
609                            self.Submit.enable();
610                            console.error(error_thrown);
611                            alert('Произошла ошибка. Попробуйте ещё раз.');
612                        }).then(dfd.resolve, dfd.reject);
613                    }, 0);
614
615                    return dfd;
616                },
617                sendChannelAddress: function (channel_type) {
618                    if (self.current_send != null) {
619                        return;
620                    }
621
622                    var address = self.ContactConfirmation.getChannelAddressInput().val();
623
624                    self.abortUpdate();
625
626                    self.ContactConfirmation.loading();
627                    self.ContactConfirmation.disableButton();
628
629                    setTimeout(function () {
630                        $.ajax({
631                            url: config.send_channel_address_url,
632                            type: 'post',
633                            data: {
634                                state: JSON.stringify(self.getState()),
635                                channel_type: channel_type,
636                                address: address
637                            },
638                            dataType: 'json',
639                            beforeSend: function (xhr) {
640                                self.current_send = xhr;
641                            }
642                        }).then(function (response) {
643                            self.current_send = null;
644
645                            self.ContactConfirmation.loadingEnd();
646                            self.ContactConfirmation.enableButton();
647                            self.ContactConfirmation.hideErrors();
648
649                            if (response.errors && response.errors.length !== 0) {
650                                self.ContactConfirmation.handleErrors(response.errors);
651
652                                return;
653                            }
654
655                            if (response.data && response.data.success) {
656                                self.ContactInfo.setField(response.data.channel_type, response.data.address);
657                            }
658
659                            self.ContactConfirmation.setCodeStep(channel_type);
660                        }, function (xhr, text_status, error_thrown) {
661                            self.current_send = null;
662
663                            self.ContactConfirmation.loadingEnd();
664                            self.ContactConfirmation.enableButton();
665                            self.ContactConfirmation.hideErrors();
666
667                            console.error(error_thrown);
668                            alert('Произошла ошибка. Попробуйте ещё раз.');
669                        });
670                    }, 0);
671                },
672                sendChannelCode: function (channel_type) {
673                    if (self.current_send != null) {
674                        return;
675                    }
676
677                    var code = self.ContactConfirmation.getCodeInput().val();
678
679                    if (code.trim() === '') {
680                        self.ContactConfirmation.handleErrors([{
681                            id: 'empty_code_error',
682                            text: 'Чтобы завершить оформление заказа, введите проверочный код.'
683                        }]);
684
685                        return;
686                    }
687
688                    self.abortUpdate();
689
690                    self.ContactConfirmation.loading();
691                    self.ContactConfirmation.disableButton();
692
693                    setTimeout(function () {
694                        $.ajax({
695                            url: config.send_channel_code_url,
696                            type: 'post',
697                            data: {
698                                state: JSON.stringify(self.getState()),
699                                channel_type: channel_type,
700                                code: code
701                            },
702                            dataType: 'json',
703                            beforeSend: function (xhr) {
704                                self.current_send = xhr;
705                            }
706                        }).then(function (response) {
707                            self.current_send = null;
708
709                            self.ContactConfirmation.hideErrors();
710
711                            if (response.errors && response.errors.length !== 0) {
712                                self.ContactConfirmation.loadingEnd();
713                                self.ContactConfirmation.enableButton();
714                                self.ContactConfirmation.handleErrors(response.errors);
715
716                                return;
717                            }
718
719                            self.send();
720                        }, function (xhr, text_status, error_thrown) {
721                            self.current_send = null;
722
723                            self.ContactConfirmation.loadingEnd();
724                            self.ContactConfirmation.enableButton();
725                            self.ContactConfirmation.hideErrors();
726                            console.error(error_thrown);
727                            alert('Произошла ошибка. Попробуйте ещё раз.');
728                        });
729                    }, 0);
730                },
731                refresh: function () {
732                    $form.find('input:text:not(.buy1click2-input-text)').addClass('buy1click2-input-text');
733                    $form.find('select:not(.buy1click2-select)').addClass('buy1click2-select');
734
735                    $form.find('select.buy1click2-select, :checkbox.buy1click2-checkbox').styler();
736                    $form.find('select.buy1click2-select, :checkbox.buy1click2-checkbox').each(function () {
737                        var $this = $(this);
738
739                        setTimeout(function () {
740                            $this.trigger('refresh');
741                        }, 0);
742                    });
743                    $form.find(':checkbox.buy1click2-checkbox').off('refresh.styler').on('refresh.styler', function () {
744                        $(this).closest('.jq-checkbox').find('.jq-checkbox__div').html(
745                            '<svg class="buy1click2-svg-icon buy1click2-checkbox__icon" width="12" height="9"><use class="buy1click2-svg-icon__content" xlink:href="' + config.wa_url + 'wa-apps/shop/plugins/buy1click2/svg/icon.sprite.svg#checkbox-arrow" fill="#F2994A" /></svg>');
746                    });
747
748                    $form.find('select.buy1click2-select').off('refresh.styler').on('refresh.styler', function () {
749                        $(this).closest('.jq-selectbox').find('.jq-selectbox__trigger').html(
750                            '<svg class="buy1click2-svg-icon" width="8" height="5"><use class="buy1click2-svg-icon__content" xlink:href="' + config.wa_url + 'wa-apps/shop/plugins/buy1click2/svg/icon.sprite.svg#arrow" fill="#333333" /></svg>');
751                    });
752                },
753                reachGoal: function (target) {
754                    var settings = self.getState().settings;
755                    var ymCounterNumber = settings.form_target_ym_counter;
756
757                    if (ymCounterNumber) {
758                        var ymCounter = window['yaCounter' + ymCounterNumber];
759                        var ymTarget = settings['form_target_ym_' + target];
760
761                        if (ymCounter && ymTarget) {
762                            ymCounter.reachGoal(ymTarget);
763                        }
764                    }
765
766                    var gaTargetCategory = settings['form_target_ga_category_' + target];
767                    var gaTargetAction = settings['form_target_ga_action_' + target];
768
769                    var _gtag = null;
770
771                    if (window.gtag) {
772                        _gtag = window.gtag;
773                    } else if (window.getEcommercePluginInstance) {
774                        var ecommerce = window.getEcommercePluginInstance();
775
776                        if (ecommerce && ecommerce._google_enhanced_ecommerce) {
777                            _gtag = ecommerce._google_enhanced_ecommerce._pushToDataLayer;
778                        }
779                    }
780
781                    if (_gtag && (gaTargetAction || gaTargetCategory)) {
782                        _gtag('event', gaTargetAction, {
783                            event_category: gaTargetCategory
784                        });
785                    }
786                },
787                Items: (function () {
788                    return {
789                        is_updated: false,
790                        init: function () {
791                            self.Items.is_updated = false;
792                            self.refresh();
793
794                            $('.buy1click2-item__services').each(function () {
795                                const $services = $(this);
796                                let item_id = self.Items.getItemID($services);
797                                services[item_id] = self.getState().cart.items[item_id]['services'];
798
799                                $services.find('input[type="checkbox"]').on('click', function () {
800                                    self.Items.handleService($(this), item_id);
801                                    self.Items.setServices(item_id, services[item_id]);
802                                    self.Items.is_updated = true;
803                                    self.update();
804                                });
805
806                                $services.find('.service-variants').on('change', function () {
807                                    let serviceId = $(this).data('service-id');
808                                    let $parent = $(this).closest('.service-' + serviceId);
809                                    let $checkbox = $parent.find('input[type="checkbox"]');
810
811                                    self.Items.handleService($checkbox, item_id);
812                                    self.Items.setServices(item_id, services[item_id]);
813                                    self.Items.is_updated = true;
814                                    self.update();
815                                });
816                            });
817
818                            $form.find('.buy1click2-item-quantity').each(function () {
819                                var change_quantity_timeout = null;
820                                var $quantity = $(this);
821                                var item_id = self.Items.getItemID($quantity);
822                                var $input = $quantity.find('.buy1click2-item-quantity__input');
823
824                                $quantity.find('.buy1click2-item-quantity__minus').on('click', function () {
825                                    const item = self.Items.getItem(item_id);
826                                    const new_quantity = +item.quantity - +item.order_count_step;
827                                    let quantity = Math.max(0, new_quantity);
828                                    self.Items.setQuantity(item_id, quantity);
829                                    $input.val(quantity);
830
831                                    self.abortUpdate();
832                                    clearTimeout(change_quantity_timeout);
833                                    change_quantity_timeout = setTimeout(function () {
834                                        $input.trigger('change');
835                                    }, 500);
836                                });
837
838                                $quantity.find('.buy1click2-item-quantity__plus').on('click', function () {
839                                    const item = self.Items.getItem(item_id);
840                                    let quantity = +item.quantity + +item.order_count_step;
841                                    self.Items.setQuantity(item_id, quantity);
842                                    $input.val(quantity);
843
844                                    self.abortUpdate();
845                                    clearTimeout(change_quantity_timeout);
846                                    change_quantity_timeout = setTimeout(function () {
847                                        $input.trigger('change');
848                                    }, 500);
849                                });
850
851                                $input.on('change', function () {
852                                    clearTimeout(change_quantity_timeout);
853
854                                    let quantity = parseFloat($input.val()) || 0;
855                                    self.Items.setQuantity(item_id, quantity);
856                                    $input.val(quantity);
857
858                                    self.Items.is_updated = true;
859                                    self.Shipping.is_updated = true;
860                                    self.Shipping.loading();
861                                    self.Payments.loading();
862                                    self.Confirmation.loading();
863                                    self.update();
864                                });
865                            });
866
867                            $form.toggleClass('buy1click2-form_min-total-error', self.Items.isMinTotalError());
868                            $form.toggleClass('buy1click2-form_available-error', self.Items.isAvailableError());
869                        },
870                        render: function (html) {
871                            if (!self.Items.is_updated) {
872                                return;
873                            }
874
875                            $form.find('.buy1click2-form__items').replaceWith($(html).find('.buy1click2-form__items'));
876                            self.Items.init();
877                        },
878                        getItems: function () {
879                            var state = self.getState();
880
881                            return state.cart.items;
882                        },
883                        setItems: function (items) {
884                            var state = self.getState();
885                            state.cart.items = items;
886                            self.setState(state);
887                        },
888                        isMinTotalError: function () {
889                            var state = self.getState();
890
891                            return !!state.errors.min_order;
892                        },
893                        isAvailableError: function () {
894                            var state = self.getState();
895
896                            return !!state.errors.available;
897                        },
898                        getItemID: function ($elm) {
899                            return $elm.closest('.buy1click2-item').data('item_id');
900                        },
901                        getItem: function (item_id) {
902                            var items = self.Items.getItems();
903
904                            return items[item_id] ? items[item_id] : null;
905                        },
906                        setItem: function (item_id, item) {
907                            var items = self.Items.getItems();
908                            items[item_id] = item;
909                            self.Items.setItems(items);
910                        },
911                        getQuantity: function (item_id) {
912                            var item = self.Items.getItem(item_id);
913
914                            return item ? item.quantity : null;
915                        },
916                        setQuantity: function (item_id, quantity) {
917                            var item = self.Items.getItem(item_id);
918
919                            if (item == null) {
920                                return;
921                            }
922
923                            item.quantity = quantity;
924                            self.Items.setItem(item_id, item);
925                        },
926                        handleService: function ($input, item_id) {
927                            let service_id = $input.val();
928                            let service_variant_id = $input
929                                .closest('.service-' + service_id)
930                                .find('[name="service_variant[' + service_id + ']"]')
931                                .val();
932
933                            if (services[item_id] === undefined) {
934                                services[item_id] = [];
935                            }
936
937                            let index = services[item_id].findIndex(s => s.service_id == service_id);
938
939                            if (index == -1) {
940                                services[item_id].push({
941                                    service_id: service_id,
942                                    service_variant_id: service_variant_id
943                                });
944                            } else {
945                                services[item_id][index]['service_variant_id'] = service_variant_id;
946                                services[item_id][index]['enabled'] 
946= $input.is(':checked') ? 1 : 0;
947                            }
948                        },
949                        setServices: function (item_id, services) {
950                            let item = self.Items.getItem(item_id);
951
952                            if (item == null) {
953                                return;
954                            }
955
956                            item.services = services;
957                            self.Items.setItem(item_id, item);
958                        }
959                    };
960                })(),
961                ContactInfo: (function () {
962                    return {
963                        is_updated: false,
964                        is_change_country: false,
965                        is_change_city: false,
966                        is_change_address: false,
967                        init: function () {
968                            self.ContactInfo.is_updated = false;
969                            self.ContactInfo.initDatePickers();
970                            self.ContactInfo.initDadata();
971
972                            $form.find('select.buy1click2-select, input.buy1click2-radio:checked').each(function () {
973                                let $input = $(this);
974                                let $field = $input.closest('.buy1click2-form-field');
975                                let field_id = $field.data('field_id');
976
977                                if (!field_id) {
978                                    return;
979                                }
980
981                                let value = $input.val();
982                                self.ContactInfo.setField(field_id, value);
983                            });
984
985                            $form.find('.buy1click2-input-text, .buy1click2-textarea, select.buy1click2-select, input.buy1click2-radio, input.buy1click2-checkbox').on('change', function (e) {
986                                var $input = $(e.target);
987                                var $field = $input.closest('.buy1click2-form-field');
988                                var field_id = $field.data('field_id');
989
990                                if (!field_id) {
991                                    return;
992                                }
993
994                                setTimeout(function () {
995                                    var value = $input.val();
996
997                                    if ($input.prop('type') === 'checkbox') {
998                                        value = $input.prop('checked');
999                                    }
1000
1001                                    if (field_id.indexOf('additional_field_') === 0) {
1002                                        var state = self.getState();
1003
1004                                        if (state.session.additional_fields.length !== undefined) {
1005                                            state.session.additional_fields = {};
1006                                        }
1007
1008                                        state.session.additional_fields[field_id.replace(/^additional_field_/, '')] = value;
1009                                        self.setState(state);
1010
1011                                        return;
1012                                    }
1013
1014                                    self.ContactInfo.setField(field_id, value);
1015                                    var is_address_field = field_id.indexOf('address_') === 0;
1016
1017                                    if (!is_address_field) {
1018                                        return;
1019                                    }
1020
1021                                    if (field_id == 'address_country') {
1022                                        self.ContactInfo.is_change_country = true;
1023                                    }
1024
1025                                    if (field_id == 'address_region') {
1026                                        self.ContactInfo.clearAddressCity();
1027                                        self.ContactInfo.clearAddressStreet();
1028                                        self.ContactInfo.clearPostalCode();
1029                                    }
1030
1031                                    if (field_id == 'address_city') {
1032                                        self.ContactInfo.clearAddressStreet();
1033                                        self.ContactInfo.is_change_city = false;
1034                                    }
1035
1036                                    if (field_id == 'address_street') {
1037                                        self.ContactInfo.is_change_address = false;
1038                                    }
1039
1040                                    self.Shipping.is_updated = true;
1041                                    self.Shipping.loading();
1042                                    self.Payments.loading();
1043                                    self.Confirmation.loading();
1044                                    self.update();
1045                                }, 0);
1046                            });
1047
1048                            $form.find('.buy1click2-form-field_masked').each(function () {
1049                                var $field = $(this);
1050                                var mask = $field.data('mask');
1051
1052                                if (mask) {
1053                                    var $field_input = $field.find('input');
1054                                    var current_val = $field_input.val();
1055
1056                                    if (current_val) {
1057                                        var prefix = mask.replace(/\D/g, '');
1058                                        var prefix_regexp = new RegExp('^' + prefix);
1059                                        var without_prefix = current_val.replace(prefix_regexp, '');
1060                                        $field_input.val(without_prefix);
1061                                    }
1062
1063                                    $field.find('.buy1click2-form-field__input').inputmask(mask + '', {
1064                                        definitions: {
1065                                            '#': {
1066                                                validator: '[0-9]'
1067                                            }
1068                                        },
1069                                        clearIncomplete: true
1070                                    });
1071                                    $field_input.val(without_prefix);
1072                                }
1073                            });
1074                        },
1075                        initDatePickers: function () {
1076                            $form.find('.js-datepicker').each(function () {
1077                                let $input = $(this),
1078                                    alt_field_selector = $input.data('alt');
1079
1080                                if (alt_field_selector) {
1081                                    const $alt_field = $form.find(alt_field_selector);
1082
1083                                    let options = {
1084                                        changeMonth: true,
1085                                        changeYear: true
1086                                    };
1087
1088                                    if ($alt_field.length) {
1089                                        options = $.extend(options, {
1090                                            altField: $alt_field,
1091                                            altFormat: 'yy-mm-dd'
1092                                        });
1093                                    }
1094
1095                                    $input.datepicker(options);
1096                                }
1097                            });
1098                        },
1099                        initDadata: function () {
1100                            if (dadata.api_key.length && dadata.use_address_city_hints) {
1101                                const $city = self.ContactInfo.getInputByFieldId('address_city');
1102
1103                                $city.suggestions({
1104                                    token: dadata.api_key,
1105                                    type: 'ADDRESS',
1106                                    bounds: 'city-settlement',
1107                                    constraints: {
1108                                        locations: { country: '*' }
1109                                    },
1110                                    onSelect: function (suggestion) {
1111                                        self.ContactInfo.is_change_city = true;
1112                                        self.ContactInfo.updateCountryByDadata(suggestion.data.country_iso_code);
1113                                        self.ContactInfo.updateRegionByDadata(suggestion.data.region_kladr_id);
1114                                        self.ContactInfo.updateCity(`${suggestion.data.city}${suggestion.data.settlement ? `, ${suggestion.data.settlement}` : ''}`);
1115                                        self.ContactInfo.updatePostalCode(suggestion.data.postal_code);
1116                                    }
1117                                });
1118                            }
1119
1120                            if (dadata.api_key.length && dadata.address_street_field_id.length) {
1121                                const $city = self.ContactInfo.getInputByFieldId('address_city');
1122                                const $address = self.ContactInfo.getInputByFieldId(dadata.address_street_field_id);
1123
1124                                if ($address.length) {
1125                                    $address.suggestions({
1126                                        token: dadata.api_key,
1127                                        type: 'ADDRESS',
1128                                        bounds: $city.length ? 'street-flat' : undefined,
1129                                        onSelect: function (suggestion) {
1130                                            self.ContactInfo.is_change_address = true;
1131                                            self.ContactInfo.updateCountryByDadata(suggestion.data.country_iso_code);
1132                                            self.ContactInfo.updateRegionByDadata(suggestion.data.region_kladr_id);
1133                                            self.ContactInfo.updateCity(`${suggestion.data.city}${suggestion.data.settlement ? ` ${suggestion.data.settlement}` : ''}`);
1134                                            self.ContactInfo.updatePostalCode(suggestion.data.postal_code);
1135                                            $address.val(suggestion.value).trigger('change');
1136                                        }
1137                                    });
1138
1139                                    let updateCityConstraints = function () {
1140                                        let city = $city.val();
1141
1142                                        $address.suggestions('setOptions', {
1143                                            restrict_value: city !== '',
1144                                            constraints: {
1145                                                locations: {
1146                                                    country: '*',
1147                                                    city: city
1148                                                }
1149                                            }
1150                                        });
1151                                    };
1152
1153                                    updateCityConstraints();
1154
1155                                    $city.on('suggestions-select suggestions-change suggestions-invalidateselection change', function () {
1156                                        updateCityConstraints();
1157                                    });
1158                                }
1159                            }
1160
1161                            if (dadata.api_key.length && dadata.use_company_hints) {
1162                                const $inn = self.ContactInfo.getInputByFieldId(dadata.company_inn_field_id);
1163                                const $company_name = self.ContactInfo.getInputByFieldId(dadata.company_name_field_id);
1164                                const $legal_address = self.ContactInfo.getInputByFieldId(dadata.company_legal_address_field_id);
1165                                const $kpp = self.ContactInfo.getInputByFieldId(dadata.company_kpp_field_id);
1166                                const $ogrn = self.ContactInfo.getInputByFieldId(dadata.company_ogrn_field_id);
1167                                const $fields = {
1168                                    inn: $inn,
1169                                    company_name: $company_name,
1170                                    legal_address: $legal_address,
1171                                    kpp: $kpp,
1172                                    ogrn: $ogrn
1173                                };
1174
1175                                Object.values($fields).forEach(($field) => {
1176                                    self.ContactInfo.initPartySuggestions($field, $fields);
1177                                });
1178
1179                                const $bank_bic = self.ContactInfo.getInputByFieldId(dadata.bank_bic_field_id);
1180                                const $bank_name = self.ContactInfo.getInputByFieldId(dadata.bank_name_field_id);
1181                                const $bank_correspondent_account = self.ContactInfo.getInputByFieldId(dadata.bank_correspondent_account_field_id);
1182
1183                                const $bank_fields = {
1184                                    bic: $bank_bic,
1185                                    name: $bank_name,
1186                                    correspondent_account: $bank_correspondent_account
1187                                };
1188
1189                                Object.values($bank_fields).forEac
1189h(($field) => {
1190                                    self.ContactInfo.initBankSuggestions($field, $bank_fields);
1191                                });
1192                            }
1193                        },
1194                        updateCountryByDadata: function (country_iso2) {
1195                            country_iso2 = country_iso2.toLowerCase();
1196                            let $select = $form.find('.buy1click2-country-field select');
1197                            $select.find('option').filter(function () {
1198                                return $(this).data('iso2') === country_iso2;
1199                            }).first().each(function () {
1200                                $select.val($(this).prop('value'))
1201                                    .trigger('refresh')
1202                                    .trigger('change');
1203                            });
1204                        },
1205                        updateRegionByDadata: function (region_kladr_id) {
1206                            if (!region_kladr_id) {
1207                                return;
1208                            }
1209
1210                            const region_kladr_id_str = region_kladr_id.toString();
1211                            const region_code_str = region_kladr_id_str.slice(0, 2);
1212                            const region_code = Number(region_code_str);
1213                            self.ContactInfo.updateRegion(region_code);
1214                        },
1215                        updateRegion: function (region_code) {
1216                            $form.find('.buy1click2-region-field select, .buy1click2-region-field input').val(region_code)
1217                                .trigger('refresh')
1218                                .trigger('change');
1219                        },
1220                        updateCity: function (city) {
1221                            const $address_city = self.ContactInfo.getInputByFieldId('address_city');
1222                            $address_city.val(city).trigger('change');
1223                        },
1224                        updatePostalCode: function (code) {
1225                            if (!dadata.postal_code_field_id) {
1226                                return;
1227                            }
1228
1229                            const $postal_code = self.ContactInfo.getInputByFieldId(dadata.postal_code_field_id);
1230                            $postal_code.val(code).trigger('change');
1231                        },
1232                        initPartySuggestions: function ($input, $fields) {
1233                            if (!$input.length) {
1234                                return;
1235                            }
1236
1237                            $input.suggestions({
1238                                token: dadata.api_key,
1239                                type: 'PARTY',
1240                                onSelect: function (suggestion) {
1241                                    if ($fields['inn'].length && suggestion.data.inn) {
1242                                        $fields['inn'].val(suggestion.data.inn).trigger('change');
1243                                    }
1244
1245                                    if ($fields['company_name'].length && suggestion.data.name.short_with_opf) {
1246                                        $fields['company_name'].val(suggestion.data.name.short_with_opf).trigger('change');
1247                                    }
1248
1249                                    if ($fields['legal_address'].length && suggestion.data.address.value) {
1250                                        $fields['legal_address'].val(suggestion.data.address.value).trigger('change');
1251                                    }
1252
1253                                    if ($fields['kpp'].length && suggestion.data.kpp) {
1254                                        $fields['kpp'].val(suggestion.data.kpp).trigger('change');
1255                                    }
1256
1257                                    if ($fields['ogrn'].length && suggestion.data.ogrn) {
1258                                        $fields['ogrn'].val(suggestion.data.ogrn).trigger('change');
1259                                    }
1260                                }
1261                            });
1262                        },
1263                        initBankSuggestions: function ($input, $fields) {
1264                            if (!$input.length) {
1265                                return;
1266                            }
1267
1268                            $input.suggestions({
1269                                token: dadata.api_key,
1270                                type: 'BANK',
1271                                onSelect: function (suggestion) {
1272                                    if ($fields['bic'].length && suggestion.data.bic) {
1273                                        $fields['bic'].val(suggestion.data.bic).trigger('change');
1274                                    }
1275
1276                                    if ($fields['name'].length && suggestion.data.name.payment) {
1277                                        $fields['name'].val(suggestion.data.name.payment).trigger('change');
1278                                    }
1279
1280                                    if ($fields['correspondent_account'].length && suggestion.data.correspondent_account) {
1281                                        $fields['correspondent_account'].val(suggestion.data.correspondent_account).trigger('change');
1282                                    }
1283                                }
1284                            });
1285                        },
1286                        getInputByFieldId: function (field_id) {
1287                            return $form
1288                                .find('.buy1click2-form__field[data-field_id="' + field_id + '"]')
1289                                .find('.buy1click2-input-text');
1290                        },
1291                        render: function (html) {
1292                            if (!self.ContactInfo.is_updated) {
1293                                if (!self.ContactInfo.is_change_country) {
1294                                    return;
1295                                }
1296
1297                                self.ContactInfo.is_change_country = false;
1298                                $form.find('.buy1click2-region-field').replaceWith($(html).find('.buy1click2-region-field'));
1299                                self.ContactInfo.init();
1300
1301                                return;
1302                            }
1303
1304                            $form.find('.buy1click2-form__contact-info').replaceWith(
1305                                $(html).find('.buy1click2-form__contact-info'));
1306                            self.ContactInfo.init();
1307                            self.refresh();
1308                        },
1309                        renderRegion: function (html) {
1310                            $form.find('.buy1click2-region-field').replaceWith($(html).find('.buy1click2-region-field'));
1311                            self.ContactInfo.init();
1312                        },
1313                        getField: function (field_id) {
1314                            var state = self.getState();
1315
1316                            if (field_id.indexOf('address_') === 0) {
1317                                field_id = field_id.replace(/^address_/, '');
1318
1319                                return state.contact_info.shipping_address[field_id];
1320                            }
1321
1322                            return state.contact_info[field_id] ? state.contact_info[field_id] : null;
1323                        },
1324                        setField: function (field_id, value) {
1325                            var state = self.getState();
1326
1327                            if (field_id.indexOf('address_') === 0) {
1328                                field_id = field_id.replace(/^address_/, '');
1329                                state.contact_info.shipping_address[field_id] = value;
1330                            } else {
1331                                state.contact_info[field_id] = value;
1332                            }
1333
1334                            self.setState(state);
1335                        },
1336                        clearAddressCity: function () {
1337                            if (self.ContactInfo.is_change_city || self.ContactInfo.is_change_address) {
1338                                return;
1339                            }
1340
1341                            self.ContactInfo.getInputByFieldId('address_city').val('');
1342                            self.ContactInfo.setField('address_city', '');
1343                        },
1344                        clearAddressStreet: function () {
1345                            if (self.ContactInfo.is_change_address) {
1346                                return;
1347                            }
1348
1349                            if (!dadata.address_street_field_id.length) {
1350                                return;
1351                            }
1352
1353                            const $address_street = self.ContactInfo.getInputByFieldId(dadata.address_street_field_id);
1354
1355                            if (!$address_street.length) {
1356                                return;
1357                            }
1358
1359                            $address_street.val('');
1360                            self.ContactInfo.setField(dadata.address_street_field_id, '');
1361                        },
1362                        clearPostalCode: function () {
1363                            if (self.ContactInfo.is_change_city || self.ContactInfo.is_change_address) {
1364                                return;
1365                            }
1366
1367                            if (!dadata.postal_code_field_id.length) {
1368                                return;
1369                            }
1370
1371                            const $postal_code = self.ContactInfo.getInputByFieldId(dadata.postal_code_field_id);
1372
1373                            if (!$postal_code.length) {
1374                                return;
1375                            }
1376
1377                            $postal_code.val('');
1378                            self.ContactInfo.setField(dadata.postal_code_field_id, '');
1379                        }
1380                    };
1381                })(),
1382                Shipping: (function () {
1383                    return {
1384                        is_updated: false,
1385                        init: function (external) {
1386                            external = external || false;
1387
1388                            self.Shipping.is_updated = false;
1389                            self.Shipping.updateChecked();
1390
1391                            $form.find('.buy1click2-form__shipping :radio').on('change', function () {
1392                                self.Shipping.updateChecked();
1393                                self.Payments.loading();
1394                                self.Confirmation.loading();
1395                                self.update(true);
1396                            });
1397
1398                            $form.find('.buy1click2-shipping').on('click', function (e) {
1399                                if ($(e.target).closest('.jq-selectbox').length) {
1400                                    e.preventDefault();
1401                                }
1402                            });
1403
1404                            $form.find('select.buy1click2-shipping__rates').on('change', function () {
1405                                var $shipping = $(this).closest('.buy1click2-shipping');
1406
1407                                if ($shipping.data('shipping_id') != self.Shipping.getSelectedShippingID()) {
1408                                    $shipping.find(':radio').prop('checked', true).trigger('change');
1409                                } else {
1410                                    self.Shipping.updateChecked();
1411                                    self.Confirmation.loading();
1412                                    self.update(true);
1413                                }
1414                            });
1415
1416                            $form.find('.buy1click2-shipping__custom-fields').on('change', function () {
1417                                var $$form = $(this);
1418                                var params = $('<form/>').append($$form.clone()).serializeArray().reduce(function (params, elem) {
1419                                    var name = elem.name.replace(/^params\[(.*)]$/, '$1');
1420                                    var names = name.split('.');
1421
1422                                    // Костыль..
1423                                    if (names.length == 2) {
1424                                        params[names[0]] = params[names[0]] || {};
1425                                        params[names[0]][names[1]] = elem.value;
1426                                    } else {
1427                                        params[name] = elem.value;
1428                                    }
1429
1430                                    return params;
1431                                }, {});
1432
1433                                self.Shipping.setShippingParams(params);
1434                            });
1435
1436                            if (external) {
1437                                self.Confirmation.loading();
1438                            } else {
1439                                self.Shipping.is_updated = true;
1440                            }
1441
1442                            self.update(true);
1443                        },
1444                        render: function (html, external) {
1445                            if (!self.Shipping.is_updated) {
1446                                return;
1447                            }
1448
1449                            $form.find('.buy1click2-form__shipping').replaceWith($(html).find('.buy1click2-form__shipping'));
1450                            self.Shipping.init(external);
1451                            self.refresh();
1452                        },
1453                        loading: function () {
1454                            $form.find('.buy1click2-form__shipping').addClass('buy1click2-form__shipping_loading');
1455                        },
1456                        loadingEnd: function () {
1457                            $form.find('.buy1click2-form__shipping').removeClass('buy1click2-form__shipping_loading');
1458                        },
1459                        getSelectedShippingID: function () {
1460                            var state = self.getState();
1461
1462                            return state.session.selected_shipping_id;
1463                        },
1464                        setSelectedShippingID: function (shipping_id) {
1465                            var state = self.getState();
1466                            state.session.selected_shipping_id = shipping_id;
1467                            self.setState(state);
1468                        },
1469                        getSelectedShippingRateID: function () {
1470                            var state = self.getState();
1471
1472                            return state.session.selected_shipping_rate_id;
1473                        },
1474                        setSelectedShippingRateID: function (shipping_rate_id) {
1475                            var state = self.getState();
1476                            state.session.selected_shipping_rate_id = shipping_rate_id;
1477                            self.setState(state);
1478                        },
1479                        setSelectedShippingRateType: function (shipping_rate_type) {
1480                            let state = self.getState();
1481                            state.session.selected_shipping_rate_type = shipping_rate_type;
1482                            self.setState(state);
1483                        },
1484                        getShippingParams: function () {
1485                            var state = self.getState();
1486
1487                            return state.session.shipping_params;
1488                        },
1489                        setShippingParams: function (shipping_params) {
1490                            var state = self.getState();
1491                            state.session.shipping_params = shipping_params;
1492                            self.setState(state);
1493                        },
1494                        updateChecked: function () {
1495                            $form.find('.buy1click2-shipping_checked')
1496                                .removeClass('buy1click2-shipping_checked');
1497                            var $shipping = $form.find('.buy1click2-form__shipping :radio:checked')
1498                                .closest('.buy1click2-shipping');
1499                            $shipping.addClass('buy1click2-shipping_checked');
1500                            self.Shipping.setSelectedShippingID($shipping.data('shipping_id'));
1501                            var $rate = $shipping.find('select.buy1click2-shipping__rates :selected');
1502                            self.Shipping.setSelectedShippingRateID($rate.data('rate_id'));
1503                            self.Shipping.setSelectedShippingRateType($rate.data('type'));
1504
1505                            var settings = self.getState().settings;
1506
1507                            $form.find('.buy1click2-shipping').each(function () {
1508                                var $shipping = $(this);
1509                                var $rate = $shipping.find('select.buy1click2-shipping__rates :selected');
1510
1511                                var rate_rate = settings.ignore_shipping_rate_in_total == '1'
1512                                    ? ''
1513                                    : $rate.data('rate');
1514
1515                                var rate_compare_rate = settings.ignore_shipping_rate_in_total == '1'
1516                                    ? ''
1517                                    : $rate.data('compare_rate');
1518
1519                                $shipping.find('.buy1click2-shipping__rate').html(rate_rate)
1520                                    .toggleClass('buy1click2-shipping__rate_empty', !rate_rate);
1521                                $shipping.find('.buy1click2-shipping__compare-rate').html(rate_compare_rate)
1522                                    .toggleClass('buy1click2-shipping__compare-rate_empty', !rate_compare_rate);
1523                                $shipping.find('.buy1click2-shipping__est-delivery').html($rate.data('est_delivery'))
1524                                    .toggleClass('buy1click2-shipping__est-delivery_empty', !$rate.data('est_delivery'));
1525                                $shipping.find('.buy1click2-shipping__comment').html($rate.data('comment'))
1526                                    .toggleClass('buy1click2-shipping__comment_empty', !$rate.data('comment'));
1527                            });
1528                        },
1529                        isSelectedError: function () {
1530                            var state = self.getState();
1531
1532                            if (
1533                                state.settings.form_shipping === 'disabled'
1534                                || state.settings.form_shipping_allow_checkout_without_shipping
1535                            ) {
1536                                return false;
1537                            }
1538
1539                            return !self.Shipping.getSelectedShippingID();
1540                        }
1541                    };
1542                })(),
1543                Payments: (function () {
1544                    return {
1545                        init: function () {
1546                            self.Payments.updateChecked();
1547
1548                            $form.find('.buy1click2-form__payments :radio').on('change', function () {
1549                                self.Payments.updateChecked();
1550
1551                                if (config.is_increase_plugin_enabled) {
1552                                    self.Confirmation.loading();
1553                                    self.update(true);
1554                                } else {
1555                                    self.Payments.updateSelectedText();
1556                                }
1557                            });
1558                        },
1559                        render: function (html) {
1560                            $form.find('.buy1click2-form__payments').replaceWith($(html).find('.buy1click2-form__payments'));
1561                            self.Payments.init();
1562                        },
1563                        loading: function () {
1564                            $form.find('.buy1click2-form__payments').addClass('buy1click2-form__payments_loading');
1565                        },
1566                        loadingEnd: function () {
1567                            $form.find('.buy1click2-form__payments').removeClass('buy1click2-form__payments_loading');
1568                        },
1569                        getSelectedPaymentID: function () {
1570                            var state = self.getState();
1571
1572                            return state.session.selected_payment_id;
1573                        },
1574                        setSelectedPaymentID: function (payment_id) {
1575                            var state = self.getState();
1576                            state.session.selected_payment_id = payment_id;
1577                            self.setState(state);
1578                        },
1579                        updateChecked: function () {
1580                            $form.find('.buy1click2-payment_checked')
1581                                .removeClass('buy1click2-payment_checked');
1582                            var $payment = $form.find('.buy1click2-form__payments :radio:checked')
1583                                .closest('.buy1click2-payment');
1584                            $payment.addClass('buy1click2-payment_checked');
1585                            self.Payments.setSelectedPaymentID($payment.data('payment_id'));
1586                        },
1587                        updateSelectedText: function () {
1588                            const $selectedPayment = $form.find('.buy1click2-total-box__selected-payment');
1589
1590                            if (!$selectedPayment.length) {
1591                                return;
1592                            }
1593
1594                            $selectedPayment.text(
1595                                $form.find('.buy1click2-payment_checked')
1596                                    .find('.buy1click2-payment__name')
1597                                    .text()
1598                            );
1599                        }
1600                    };
1601                })(),
1602                Confirmation: (function () {
1603                    return {
1604                        loading: function () {
1605                            $form.find('.buy1click2-form__total-box').addClass('buy1click2-form__total-box_loading');
1606                        },
1607                        loadingEnd: function () {
1608                            $form.find('.buy1click2-form__total-box').removeClass('buy1click2-form__total-box_loading');
1609                        },
1610                        render: function (html) {
1611                            $form.find('.buy1click2-form__total-box').replaceWith(
1612                                $(html).find('.buy1click2-form__total-box'));
1613                        }
1614                    };
1615                })(),
1616                Coupon: (function () {
1617                    return {
1618                        init: function () {
1619                            $form.find('.buy1click2-form__coupon').on('change', function () {
1620                                var $input = $(this);
1621                                self.Coupon.setCoupon($input.val());
1622                                self.Shipping.is_updated = true;
1623                                self.Shipping.loading();
1624                                self.Payments.loading();
1625                                self.Confirmation.loading();
1626                                self.update();
1627                            });
1628                        },
1629                        render: function (status) {
1630                            this.setCouponActive(status);
1631                            const $input = $form.find('.buy1click2-form__coupon');
1632                            const $divStatus = $form.find('.buy1click2-form__coupon-status');
1633                            const active = 'buy1click2-form__coupon-active';
1634                            const notFound = 'buy1click2-form__coupon-not-found';
1635
1636                            if (status === null) {
1637                                $input.removeClass(active + ' ' + notFound);
1638                                $divStatus.empty();
1639
1640                                return;
1641                            }
1642
1643                            if (status) {
1644                                $input.removeClass(notFound).addClass(active);
1645                                $divStatus.text('Купон активирован');
1646                            } else {
1647                                $input.removeClass(active).addClass(notFound);
1648                                $divStatus.empty();
1649                            }
1650                        },
1651                        getCoupon: function () {
1652                            var state = self.getState();
1653
1654                            return state.session.coupon;
1655                        },
1656                        setCoupon: function (coupon) {
1657                            var state = self.getState();
1658                            state.session.coupon = coupon;
1659                            self.setState(state);
1660                        },
1661                        setCouponActive: function (status) {
1662                            let state = self.getState();
1663                            state.session.coupon_active = status;
1664                            self.setState(state);
1665                        }
1666                    };
1667                })(),
1668                Comment: (function () {
1669                    return {
1670                        init: function () {
1671                            $form.find('.buy1click2-form__comment-input').on('change', function () {
1672                                var $input = $(this);
1673                                self.Comment.setComment($input.val());
1674                            });
1675                        },
1676                        getComment: function () {
1677                            var state = self.getState();
1678
1679                            return state.session.comment;
1680                        },
1681                        setComment: function (comment) {
1682                            var state = self.getState();
1683                            state.session.comment = comment;
1684                            self.setState(state);
1685                        }
1686                    };
1687                })(),
1688                Policy: (function () {
1689                    return {
1690                        init: function () {
1691                            $form.find('.buy1click2-form__policy :checkbox').on('change', function (e) {
1692                                self.Policy.setChecked(e.target.checked);
1693                                self.Submit.updateState();
1694                            });
1695                        },
1696                        getChecked: function () {
1697                            var state = self.getState();
1698
1699                            return state.session.is_checked_policy;
1700                        },
1701                        setChecked: function (is_checked_policy) {
1702                            var state = self.getState();
1703                            state.session.is_checked_policy = is_checked_policy;
1704                            self.setState(state);
1705                        }
1706                    };
1707                })(),
1708                Captcha: (function () {
1709                    return {
1710                        init: function () {
1711                            if (window.onloadWaRecaptchaCallback) {
1712                                try {
1713                                    window.onloadWaRecaptchaCallback();
1714                                } catch (e) {
1715                                    console.log(e);
1716                                }
1717                            }
1718                        },
1719                        getData: function () {
1720                            var data = {};
1721
1722                            $form.find('.buy1click2-form__captcha input, .buy1click2-form__captcha textarea').each(
1723                                function () {
1724                                    var $input = $(this);
1725                                    data[$input.attr('name')] = $input.val();
1726                                });
1727
1728                            return data;
1729                        }
1730                    };
1731                })(),
1732                Submit: (function () {
1733                    return {
1734                        init: function () {
1735                            self.Submit.updateState();
1736                            $form.find('.buy1click2-form__submit-button').on('click', function () {
1737                                self.send();
1738                            });
1739                        },
1740                        loading: function () {
1741                            $form.find('.buy1click2-form__submit-button').addClass('buy1click2-form-button_loading');
1742                        },
1743                        loadingEnd: function () {
1744                            $form.find('.buy1click2-form__submit-button').removeClass('buy1click2-form-button_loading');
1745                        },
1746                        getButton: function () {
1747                            return $form.find('.buy1click2-form__submit-button');
1748                        },
1749                        updateState: function () {
1750                            if (
1751                                self.Policy.getChecked()
1752                                && !self.Items.isMinTotalError()
1753                                && !self.Items.isAvailableError()
1754                                && !self.Shipping.isSelectedError()
1755                            ) {
1756                                self.Submit.enable();
1757                            } else {
1758                                self.Submit.disable();
1759                            }
1760                        },
1761                        disable: function () {
1762                            self.Submit.getButton().prop('disabled', true);
1763                        },
1764                        enable: function () {
1765                            self.Submit.getButton().prop('disabled', false);
1766                        }
1767                    };
1768                })(),
1769                ContactConfirmation: (function () {
1770                    return {
1771                        step: '',
1772                        init: function () {
1773                            self.ContactConfirmation.setAddressStep(self.ContactConfirmation.getChannelType());
1774                        },
1775                        initResendCode: function (channel_type) {
1776                            self.ContactConfirmation.getReSendCodeLink()
1777                                .off('click')
1778                                .on('click', function (event) {
1779                                    event.preventDefault();
1780
1781                                    self.sendChannelAddress(channel_type);
1782                                });
1783                        },
1784                        setAddressStep: function (channel_type) {
1785                            self.step = 'address';
1786
1787                            $form.toggleClass('buy1click2-form_step-address', true);
1788                            $form.toggleClass('buy1click2-form_step-code', false);
1789
1790                            self.ContactConfirmation.getChannelAddressInput().prop('readonly', false);
1791                            self.ContactConfirmation.getButton()
1792                                .off('click')
1793                                .on('click', function () {
1794                                    self.sendChannelAddress(channel_type);
1795                                });
1796
1797                            self.ContactConfirmation.getButton().find('.buy1click2-form-button-label').text('Выслать код');
1798                        },
1799                        setCodeStep: function (channel_type) {
1800                            self.step = 'code';
1801
1802                            $form.toggleClass('buy1click2-form_step-address', false);
1803                            $form.toggleClass('buy1click2-form_step-code', true);
1804
1805                            self.ContactConfirmation.getChannelAddressInput().prop('readonly', true);
1806                            self.ContactConfirmation.getCodeInput()
1807                                .closest('.buy1click2-form-field')
1808                                .removeClass('buy1click2-form-field_hidden');
1809                            self.ContactConfirmation.getButton()
1810                                .off('click')
1811                                .on('click', function () {
1812                                    self.sendChannelCode(channel_type);
1813                                });
1814
1815                            self.ContactConfirmation.initResendCode(channel_type);
1816
1817                            var is_last_channel = self.ContactConfirmation.getIsLastChannel();
1818
1819                            self.ContactConfirmation.getButton()
1820                                .find('.buy1click2-form-button-label')
1821                                .text(is_last_channel ? 'Завершить оформление' : 'Готово');
1822
1823                            self.ContactConfirmation.startReSendTimer(60);
1824                        },
1825                        startReSendTimer: function (timer_seconds) {
1826                            var $timer = $form.find('.buy1click2-form__re-send-timer-wrapper');
1827                            var $timer_time = $timer.find('.buy1click2-form__re-send-timer-time');
1828                            var $re_send_button = self.ContactConfirmation.getReSendCodeLink();
1829
1830                            /**
1831                             * @param {int} time
1832                             * @return {string}
1833                             */
1834                            var formatTime = function (time) {
1835                                if (!(time >= 0)) {
1836                                    return '';
1837                                }
1838
1839                                var minutes = Math.floor(time / 60);
1840                                var seconds = time - (minutes * 60);
1841
1842                                if (minutes < 10) {
1843                                    minutes = '0' + minutes;
1844                                }
1845
1846                                if (seconds < 10) {
1847                                    seconds = '0' + seconds;
1848                                }
1849
1850                                return minutes + ':' + seconds;
1851                            };
1852
1853                            $timer.removeClass('buy1click2-form__re-send-timer-wrapper_hidden');
1854                            $re_send_button.addClass('buy1click2-form__re-send-link_hidden');
1855
1856                            var start_timestamp = (new Date()).getTime();
1857                            var timer_interval = setInterval(function () {
1858                                var seconds_remains = parseInt(Math.floor((start_timestamp - (new Date()).getTime()) / 1000) + timer_seconds);
1859
1860                                if (seconds_remains >= 0) {
1861                                    $timer_time.text(formatTime(seconds_remains));
1862                                } else {
1863                                    clearInterval(timer_interval);
1864                                    $timer.addClass('buy1click2-form__re-send-timer-wrapper_hidden');
1865                                    $re_send_button.removeClass('buy1click2-form__re-send-link_hidden');
1866                                }
1867                            }, 100);
1868                        },
1869                        getButton: function () {
1870                            return $form.find('.buy1click2-form__submit-contact-confirmation-button');
1871                        },
1872                        getChannelAddressInput: function () {
1873                            return $form.find('.buy1click2-form__confirmation-channel-address');
1874                        },
1875                        getCodeInput: function () {
1876                            return $form.find('.buy1click2-form__confirmation-channel-code');
1877                        },
1878                        getChannelType: function () {
1879                            var state = self.getState();
1880
1881                            return state.session.confirmation_channel_type;
1882                        },
1883                        getIsLastChannel: function () {
1884                            var state = self.getState();
1885
1886                            return state.session.confirmation_channel_is_last_channel;
1887                        },
1888                        loading: function () {
1889                            $form.find('.buy1click2-form__submit-contact-confirmation-button').addClass('buy1click2-form-button_loading');
1890                        },
1891                        loadingEnd: function () {
1892                            $form.find('.buy1click2-form__submit-contact-confirmation-button').removeClass('buy1click2-form-button_loading');
1893                        },
1894                        disableButton: function () {
1895                            self.ContactConfirmation.getButton().prop('disabled', true);
1896                        },
1897                        enableButton: function () {
1898                            self.ContactConfirmation.getButton().prop('disabled', false);
1899                        },
1900                        getReSendCodeLink: function () {
1901                            return $form.find('.buy1click2-form__re-send-link');
1902                        },
1903                        handleErrors: function (errors) {
1904                            self.ContactConfirmation.hideErrors();
1905
1906                            errors.forEach(function (error) {
1907                                var is_channel_error = (error.id === 'channel_error' && self.step === 'address')
1908                                  || error.id === 'timeout_error'
1909                                  || error.id === 'source_error'
1910                                  || error.id === 'send_error';
1911
1912                                var is_code_error = (error.id === 'channel_error' && self.step === 'code')
1913                                  || error.id === 'storage_error'
1914                                  || error.id === 'code_attempts_error'
1915                                  || error.id === 'empty_code_error'
1916                                  || error.id === 'code_error';
1917
1918                                var error_selector = '';
1919
1920                                if (is_channel_error) {
1921                                    error_selector = '.buy1click2-form__channel-error';
1922                                } else if (is_code_error) {
1923                                    error_selector = '.buy1click2-form__code-error';
1924                                } else {
1925                                    console.warn(error);
1926
1927                                    return;
1928                                }
1929
1930                                $form.find(error_selector)
1931                                    .text(error.text)
1932                                    .removeClass('buy1click2-form__error_hidden');
1933                            });
1934                        },
1935                        hideErrors: function () {
1936                            $form.find('.buy1click2-form__error').addClass('buy1click2-form__error_hidden');
1937                        },
1938                        getCurrentChannelType() {
1939                            return self.ContactConfirmation.getChannelAddressInput().data('type');
1940                        }
1941                    };
1942                })()
1943            };
1944
1945            return self;
1946        };
1947
1948        var initButton = function ($button) {
1949            var button = Button($button);
1950
1951            if (!button.isInit()) {
1952                button.init();
1953            }
1954        };
1955
1956        var initButtons = function () {
1957            $('.buy1click2-open-button').each(function () {
1958                var $button = $(this);
1959
1960                setTimeout(function () {
1961                    initButton($button);
1962                }, 0);
1963            });
1964        };
1965
1966        window.shop_buy1click2 = {
1967            Button: Button,
1968            FormStorage: FormStorage,
1969            Form: Form,
1970            initButtons: initButtons
1971        };
1972
1973        $(document).ajaxComplete(function () {
1974            setTimeout(function () {
1975                window.shop_buy1click2.initButtons();
1976            }, 0);
1977        });
1978
1979        window.shop_buy1click2.initButtons();
1980    });
1981})(jQuery);

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.