PageSourceSearch

https://cremax.ru/cr-files/assets/4.4/nodes.js?v=1742573282

js cremax.ru collected 2026-09-28 08:55:07 UTC 102,449 bytes, 2,885 lines download raw bytes

1(function ($) {
2creatium.init.global(function () {
3    var $section = $('.section-layout');
4
5    var $toggle = $section.find('[cr-layout-left-toggle]');
6
7    $toggle.on('click', function () {
8        if (creatium.layout.mobile) {
9            $section.find('[cr-layout-root]').toggleClass('mobile-left-active');
10        } else {
11            if (cr.layout._left_current) {
12                $('body').removeClass('layout-left-active');
13                $section.find('[cr-layout-root]').removeClass('left-active');
14                cr.layout._left_current = 0;
15            } else {
16                $('body').addClass('layout-left-active');
17                $section.find('[cr-layout-root]').addClass('left-active');
18                cr.layout._left_current = cr.layout.left;
19            }
20        }
21
22        $(window).triggerHandler('resize');
23    });
24});
25creatium.init.global(function () {
26    var user_visit = creatium.store.get('user_visit');
27
28    if (user_visit) {
29        user_visit.last = Date.now();
30        user_visit.count++;
31    } else {
32        user_visit = {
33            first: Date.now(),
34            last: Date.now(),
35            lead: null,
36            count: 1,
37        };
38    }
39
40    $(creatium).on('submit-success', function () {
41        user_visit.lead = Date.now();
42        creatium.store.set('user_visit', user_visit);
43    });
44
45    creatium.store.set('user_visit', user_visit);
46
47    $('.section-modal').each(function () {
48        var section_el = this;
49        var $section = $(section_el);
50        var $modal = $section.find('.modal');
51
52        var $document = $(document);
53
54        var once = $section.data('once');
55        var trigger = $section.data('trigger');
56        var conversionlimit = $section.data('conversionlimit');
57
58        if (once && creatium.store.get('is_triggered_' + trigger)) {
59            return;
60        }
61
62        var was_shown = false;
63        $modal.one('show', function () {
64            was_shown = true;
65            creatium.store.set('is_triggered_' + trigger, true);
66        });
67
68        var should_prevent = function () {
69            if (was_shown) return true;
70
71            if (trigger.indexOf('leadback_') === 0) {
72                if (creatium.store.get('is_converted') !== true) return true;
73            } else {
74                if (conversionlimit && creatium.store.get('is_converted')) return true;
75            }
76
77            return false;
78        };
79
80        if (trigger === 'visit') {
81            if (should_prevent()) return;
82
83            creatium.modals.show($modal);
84        } else if (trigger === 'visit_10sec') {
85            setTimeout(function () {
86                if (should_prevent()) return;
87
88                creatium.modals.show($modal);
89            }, 1000 * 10);
90        }  else if (trigger === 'visit_30sec') {
91            setTimeout(function () {
92                if (should_prevent()) return;
93
94                creatium.modals.show($modal);
95            }, 1000 * 30);
96        }  else if (trigger === 'visit_1min') {
97            setTimeout(function () {
98                if (should_prevent()) return;
99
100                creatium.modals.show($modal);
101            }, 1000 * 60);
102        } else if (trigger === 'visit_2min') {
103            setTimeout(function () {
104                if (should_prevent()) return;
105
106                creatium.modals.show($modal);
107            }, 2000 * 60);
108        } else if (trigger === 'visit_3min') {
109            setTimeout(function () {
110                if (should_prevent()) return;
111
112                creatium.modals.show($modal);
113            }, 3000 * 60);
114        } else if (trigger === 'visit_4min') {
115            setTimeout(function () {
116                if (should_prevent()) return;
117
118                creatium.modals.show($modal);
119            }, 4000 * 60);
120        } else if (trigger === 'return_30min') {
121            if (should_prevent()) return;
122
123            if (user_visit.count === 2 && user_visit.last - user_visit.first < 1000 * 60 * 30) {
124                creatium.modals.show($modal);
125            }
126        } else if (trigger === 'return_day') {
127            if (should_prevent()) return;
128
129            if (user_visit.count === 2 && user_visit.last - user_visit.first < 1000 * 60 * 60 * 24) {
130                creatium.modals.show($modal);
131            }
132        } else if (trigger === 'return_week') {
133            if (should_prevent()) return;
134
135            if (user_visit.count === 3 && user_visit.last - user_visit.first < 1000 * 60 * 60 * 24 * 7) {
136                creatium.modals.show($modal);
137            }
138        } else if (trigger === 'leadback_hour') {
139            if (should_prevent()) return;
140
141            if (user_visit.last - user_visit.lead < 1000 * 60 * 60) {
142                creatium.modals.show($modal);
143            }
144        } else if (trigger === 'leadback_day') {
145            if (should_prevent()) return;
146
147            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24) {
148                creatium.modals.show($modal);
149            }
150        } else if (trigger === 'leadback_week') {
151            if (should_prevent()) return;
152
153            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24 * 7) {
154                creatium.modals.show($modal);
155            }
156        } else if (trigger === 'leadback_month') {
157            if (should_prevent()) return;
158
159            if (user_visit.last - user_visit.lead < 1000 * 60 * 60 * 24 * 30) {
160                creatium.modals.show($modal);
161            }
162        } else if (trigger === 'leave') {
163            $document.on('mouseleave', function (event) {
164                if (should_prevent()) return;
165
166                creatium.modals.show($modal);
167            });
168        } else if (trigger === 'scroll') {
169            $document.on('scroll', function (event) {
170                if (should_prevent()) return;
171
172                var rect = section_el.getBoundingClientRect();
173                if (rect.top > 0 && rect.top < window.innerHeight / 2) {
174                    creatium.modals.show($modal);
175                }
176            });
177        } else if (trigger === 'scroll_back') {
178            var scrolled = false;
179
180            $document.on('scroll', function (event) {
181                if (should_prevent()) return;
182
183                var rect = section_el.getBoundingClientRect();
184
185                if (scrolled) {
186                    if (rect.top > 0) {
187                        creatium.modals.show($modal);
188                    }
189                } else {
190                    if (rect.top + rect.height < 0) {
191                        scrolled = true;
192                    }
193                }
194            });
195        } else if (trigger === 'scroll_back_twice') {
196            var scrolled_1 = false;
197            var scrolled_2 = false;
198            var scrolled_3 = false;
199
200            $document.on('scroll', function (event) {
201                if (should_prevent()) return;
202
203                var rect = section_el.getBoundingClientRect();
204
205                if (scrolled_1) {
206                    if (rect.top > 0) {
207                        scrolled_2 = true;
208                    }
209                } else {
210                    if (rect.top + rect.height < 0) {
211                        scrolled_1 = true;
212                    }
213                }
214
215                if (scrolled_2) {
216                    if (scrolled_3) {
217                        if (rect.top > 0) {
218                            creatium.modals.show($modal);
219                        }
220                    } else {
221                        if (rect.top + rect.height < 0) {
222                            scrolled_3 = true;
223                        }
224                    }
225                }
226            });
227        } else if (trigger === 'scroll_end') {
228            $document.on('scroll', function (event) {
229                if (should_prevent()) return;
230
231                if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
232                    creatium.modals.show($modal);
233                }
234            });
235        } else if (trigger === 'form_fail_twice') {
236            var errors_count = 0;
237
238            $(creatium).on('submit-error', function () {
239                if (should_prevent()) return;
240
241                errors_count++;
242
243                if (errors_count === 2) {
244                    $(creatium).one('msg-close', function () {
245                        creatium.modals.show($modal);
246                    });
247                }
248            });
249        } else if (trigger === 'modal_twice') {
250            var modals_count = 0;
251
252            $(creatium).on('modal-hide', function (event, modal) {
253                if (should_prevent()) return;
254
255                // работаем только с теми окнами, которые клиент открывает сам
256                if (modal.$section.hasClass('section-modal')) return;
257
258                modals_count++;
259
260                if (modals_count === 2) {
261                    creatium.modals.show($modal);
262                }
263            });
264        }
265    });
266});
267
268creatium.init.global(function () {
269    var $preloader = $('.section-preloader').addClass('preloader-fading');
270
271    setTimeout(function () {
272        $preloader.hide();
273    }, 300);
274});
275creatium.init.global(function () {
276    var $section = $('.section-sidemenu');
277    if (!$section.length) return;
278
279    if (location.host === 'sections.creatium.site') {
280        var $template = $section.find('[cr-menu-page]');
281        $template.clone().insertBefore($template).addClass('highlight-100');
282        $template.clone().insertBefore($template).addClass('highlight-0');
283        $template.clone().insertBefore($template).addClass('highlight-0');
284        $template.clone().insertBefore($template).addClass('highlight-0');
285
286        return;
287    }
288
289    var $sections = $('.node.section:visible:not(.section-modal, .section-helper, .section-sidemenu, .fixation-top, .fixation-bottom)');
290
291    var $template = $section.find('[cr-menu-page]');
292    $sections.each(function () {
293        var $section = $(this);
294
295        var $dot = $template.clone().insertBefore($template);
296
297        $dot.addClass('highlight-0').data('highlight', 0);
298
299        $dot.on('click', function () {
300            creatium.scrollTo($section);
301        });
302    });
303    $template.remove();
304
305    var $dots = $section.find('[cr-menu-page]');
306
307    var scroll_handler = _.throttle(function () {
308        // Разделяем на 2 цикла, чтобы разделить этапы чтения DOM и записи
309        $sections.each(function (index) {
310            var $section = $(this);
311
312            var rect = this.getBoundingClientRect();
313
314            // В FF, при высоте экрана 437 пикселей, значение bottom
315            // самой нижней секции может быть 437.2166748046875, например
316            var top = Math.round(rect.top);
317            var bottom = Math.round(rect.bottom);
318
319            var win_height = $(window).height();
320
321            var highlight = 0;
322            if (bottom < 0 || top > win_height) highlight = 0;
323            else if (top >= 0 && bottom <= win_height) highlight = 1;
324            else if (top < 0) highlight = bottom / win_height;
325            else if (bottom > win_height) highlight = 1 - top / win_height;
326
327            if (highlight < 0) highlight = 0;
328            if (highlight > 1) highlight = 1;
329
330            $section.data('highlight2', Math.round(highlight * 10) * 10);
331        }).each(function (index) {
332            var $section = $(this);
333            var $dot = $dots.eq(index);
334
335            var highlight = $section.data('highlight2');
336
337            if ($section.data('highlight') !== highlight) {
338                $dot.removeClass('highlight-' + $dot.data('highlight'));
339                $dot.addClass('highlight-' + highlight).data('highlight', highlight);
340            }
341        });
342    }, 100);
343
344    $(document).on('scroll', scroll_handler);
345    scroll_handler();
346
347    if (creatium.scroll.snapping) {
348        creatium.syncInterval(scroll_handler, 500);
349    }
350});
351
352creatium.init.global(function () {
353    creatium.lazy.add($('.section-slider'), function init($section) {
354        if (!window.Swiper) return setTimeout(function () {
355            init($section);
356        }, 50);
357
358        var filter = function () {
359            return $(this).closest('.node')[0] === $section[0];
360        };
361
362        var $container = $section.find('.swiper-container').filter(filter);
363        var $next = $section.find('[cr-slider-next]').filter(filter);
364        var $previous = $section.find('[cr-slider-previous]').filter(filter);
365        var $pages = $section.find('[cr-slider-page]').filter(filter);
366        var $index = $section.find('[cr-slider-index]').filter(filter);
367
368        var params = $container.data();
369
370        var $icons = $section.find('[cr-slider-page_icon]').filter(filter).filter(function () {
371            return $(this).find('>.svgwrap').length > 1;
372        });
373        $icons.find('>.svgwrap').addClass('hidden');
374
375        var $labels = $section.find('[cr-slider-page_label]').filter(filter)
376            .filter(function () {
377                return $(this).find('>.textable').length > 1;
378            });
379        $labels.find('>.textable').addClass('hidden');
380
381        var swiper = new Swiper($container.get(0), {
382            autoHeight: params.fixheight === false,
383            autoplay: params.auto ? {
384                delay: params.pause,
385                stopOnLastSlide: !params.loop,
386            } : false,
387            allowTouchMove: params.touch,
388            effect: params.animated ? 'slide' : 'fade',
389            fadeEffect: { crossFade: true },
390            touchEventsTarget: 'container',
391            mousewheelEventsTarged: 'container',
392            on: {
393                slideChange: function () {
394                    $pages.filter('.is-active').removeClass('is-active');
395                    $pages.eq(swiper.activeIndex).addClass('is-active');
396
397                    setIcon(swiper.oldActiveIndex, swiper.activeIndex);
398                    setLabel(swiper.oldActiveIndex, swiper.activeIndex);
399
400                    $index.text(swiper.activeIndex + 1);
401
402                    swiper.oldActiveIndex = swiper.activeIndex;
403                },
404            },
405        });
406        $section.data('api-swiper', swiper);
407
408        swiper._params = params;
409        swiper.oldActiveIndex = swiper.activeIndex;
410
411        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
412
413        function setIcon(oldIndex, newIndex) {
414            $icons.each(function () {
415                var $svgwraps = $(this).children('.svgwrap');
416                $svgwraps.eq(oldIndex).addClass('hidden');
417                $svgwraps.eq(newIndex).removeClass('hidden');
418            });
419        }
420
421        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
422
423        function setLabel(oldIndex, newIndex) {
424            $labels.each(function () {
425                var $textables = $(this).children('.textable');
426                $textables.eq(oldIndex).addClass('hidden');
427                $textables.eq(newIndex).removeClass('hidden');
428            });
429        }
430
431        $section.on('slidenext', function (event) {
432            if (swiper.isEnd && params.loop) {
433                swiper.slideTo(0);
434            } else {
435                swiper.slideNext();
436            }
437
438            // если слайдер в другом слайдере, чтобы не листались оба
439            event.stopPropagation();
440        });
441
442        $next.on('click', function () {
443            $section.trigger('slidenext');
444        });
445
446        $section.on('slideprev', function (event) {
447            if (swiper.isBeginning && params.loop) {
448                swiper.slideTo(swiper.slides.length - 1);
449            } else {
450                swiper.slidePrev();
451            }
452
453            // если слайдер в другом слайдере, чтобы не листались оба
454            event.stopPropagation();
455        });
456
457        $previous.on('click', function () {
458            $section.trigger('slideprev');
459        });
460
461        $pages.on('click', function () {
462            swiper.slideTo($(this).index());
463        });
464
465        $section.find('.lazy').on('lazyload', _.throttle(function () {
466            swiper.update();
467        }, 500));
468
469        if (swiper.params.autoHeight) {
470            creatium.syncInterval(function () {
471                if (swiper.animating || !swiper.slides.length) return;
472
473                var wrapperHeight = swiper.wrapperEl.clientHeight;
474                var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
475                if (wrapperHeight !== slideHeight) swiper.update();
476            }, 40);
477        }
478    });
479});
480
481creatium.init.local(function ($root) {
482    $root.find('.widget-before-after').each(function () {
483        var $widget = $(this);
484        var $root = $widget.find('.root');
485
486        var $imgs = $root.find('> img');
487        var $handler = $root.find('> .handler');
488
489        $imgs.on('load', _.after($imgs.length, function () {
490            $root.css('height', $root.height());
491
492            var $layerBefore = $root.find('> .layer-before');
493            var $wrapBefore = $layerBefore.find('> .wrap');
494            var $imageBefore = $imgs.eq(0);
495            var imageLeftWidth = $imageBefore.width();
496            var imageLeftHeight = $imageBefore.height();
497            $imageBefore.removeAttr('style').appendTo($wrapBefore);
498
499            var $layerAfter = $root.find('> .layer-after');
500            var $wrapAfter = $layerAfter.find('> .wrap');
501            var $imageAfter = $imgs.eq(1);
502            var imageRightWidth = $imageAfter.width();
503            var imageRightHeight = $imageAfter.height();
504            $imageAfter.removeAttr('style').appendTo($wrapAfter);
505
506            $wrapBefore.add($wrapAfter).css({
507                'width': Math.max(imageLeftWidth, imageRightWidth),
508                'height': Math.max(imageLeftHeight, imageRightHeight),
509                'max-width': 'none',
510            });
511
512            var clickOffset = 0;
513
514            var eventHandler = function (event) {
515                var eventX = event.pageX;
516
517                if (eventX === undefined) {
518                    eventX = event.originalEvent.touches[0].pageX;
519                }
520
521                var rootWidth = $root.width();
522                var rootLeft = $root[0].getBoundingClientRect().left;
523                var wrapWidth = $wrapBefore.width();
524                var wrapLeft = $wrapBefore[0].getBoundingClientRect().left;
525
526                var mouseLeft = eventX - rootLeft - clickOffset;
527
528                if (mouseLeft < 0) mouseLeft = 0;
529                if (mouseLeft > rootWidth) mouseLeft = rootWidth;
530
531                $layerBefore.css('width', mouseLeft);
532                $layerAfter.css('width', rootWidth - mouseLeft);
533
534                $wrapBefore.css('right', - (rootWidth / 2 - mouseLeft));
535                $wrapAfter.css('left', rootWidth / 2 - (mouseLeft));
536
537                $handler.css('left', mouseLeft);
538                var handlerLeft = $handler[0].getBoundingClientRect().left + 2;
539
540                if (handlerLeft < wrapLeft) {
541                    $handler.css('left', mouseLeft + wrapLeft - handlerLeft);
542                }
543
544                if (handlerLeft > (wrapLeft + wrapWidth)) {
545                    $handler.css('left', mouseLeft - (handlerLeft - (wrapLeft + wrapWidth)));
546                }
547
548                event.stopPropagation();
549            };
550
551            $root.on('touchstart', function (event) {
552                eventX = event.originalEvent.touches[0].pageX;
553
554                if ($(event.target).closest($handler).length) {
555                    clickOffset = eventX - $handler[0].getBoundingClientRect().left;
556                } else {
557                    clickOffset = 0;
558                }
559
560                $(document).on('touchmove.beforeafter', eventHandler);
561                $(document).one('touchend', function () {
562                    $(document).off('touchmove.beforeafter');
563                });
564
565                event.preventDefault();
566                event.stopPropagation();
567            });
568
569            if ($root.data('trigger') === 'hover') {
570                $root.on('mousemove', eventHandler);
571                $root.on('mousedown', function (event) {
572                    event.preventDefault();
573                });
574            } else if ($root.data('trigger') === 'drag') {
575                $root.on('mousedown', function (event) {
576                    if ($(event.target).closest($handler).length) {
577                        clickOffset = event.pageX - $handler[0].getBoundingClientRect().left;
578                    } else {
579                        clickOffset = 0;
580                    }
581
582                    $(document).on('mousemove.beforeafter', eventHandler);
583                    $(document).one('mouseup', function () {
584                        $(document).off('mousemove.beforeafter');
585                    });
586
587                    event.preventDefault();
588                    event.stopPropagation();
589                });
590            }
591        }));
592    });
593});
594creatium.init.local(function ($root) {
595    $root.find('.widget-button').each(function () {
596        var $widget = $(this);
597
598        var filter = function () {
599            return $(this).closest('.widget-button')[0] === $widget[0];
600        };
601
602        var $btn = $widget.find('button').filter(filter);
603
604        if ($btn.is('[data-action="slideprev"]')) {
605            $btn.click(function () {
606                $widget.closest('.widget-slider, .widget-tabs, .
606widget-form2, .section-slider').trigger('slideprev');
607            });
608        }
609
610        if ($btn.is('[data-action="slidenext"]')) {
611            $btn.click(function () {
612                $widget.closest('.widget-slider, .widget-tabs, .widget-form2, .section-slider').trigger('slidenext');
613            });
614        }
615
616        const $cartCount = $widget.find('.btn-cart-count');
617        if ($cartCount.length) {
618            var updater = function () {
619                var count = 0;
620
621                _.each(creatium.cart.list, function (item) {
622                    var amount = _.filter(item, { type: 'amount' })[0].value * 1;
623                    count += amount;
624                });
625
626                $cartCount.text(count);
627            };
628
629            updater();
630            $(creatium).on('cart-change', updater);
631        }
632    });
633});
634
635creatium.init.local(function ($root) {
636    $root.find('.widget-cart').each(function () {
637        var $cart = $(this);
638
639        var $cont_full = $cart.find('.js-cart-full').first();
640        var $cont_empty = $cart.find('.js-cart-empty').first();
641
642        var state;
643
644        if (creatium.cart.list.length === 0) {
645            $cont_full.hide();
646            state = 'empty';
647        } else {
648            $cont_empty.hide();
649            state = 'full';
650        }
651
652        var updater = function () {
653            if (creatium.cart.list.length === 0) {
654                $cont_empty.show();
655                $cont_full.hide();
656            } else {
657                $cont_full.show();
658                $cont_empty.hide();
659            }
660        };
661
662        updater();
663        $(creatium).on('cart-change', updater);
664    });
665});
666// TODO Этот код перестал работать еще до 3.3, и никто не заметил - нужно его восстановить
667// creatium.init.local(function ($root) {
668//     $root.find('.widget-cart-image').each(function() {
669//         var $cbox = $(this).find('.colorbox');
670//
671//         if (!$cbox.length) return;
672//
673//         $cbox.colorbox({
674//             maxWidth: '80%',
675//             maxHeight: '80%'
676//         });
677//     });
678// });
679creatium.init.local(function ($root) {
680    var blankgif = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
681
682    $root.find('.widget-cart-list').each(function () {
683        var $widget = $(this);
684
685        var $template = $widget.children('script');
686        var template = $template.text().replace(/<\/_script>/g, '</script>');
687        $template.remove();
688
689        var updater = function () {
690            var $items = $widget.children('.cont');
691
692            creatium.cart.list.forEach(function (item) {
693                var name = _.filter(item, { type: 'title' })[0];
694                var price = _.filter(item, { type: 'price' })[0];
695                var amount = _.filter(item, { type: 'amount' })[0];
696                var photo = _.filter(item, { type: 'photo' })[0];
697
698                var $item = $items.filter(function () {
699                    return $(this).data('item') === item;
700                });
701
702                if ($item.length) {
703                    // Обновление
704
705                    $item.find('[data-role="setamount"]').val(amount.value);
706                    $item.find('[data-role="itemprice"]').html(price.value);
707                } else {
708                    // Добавление
709
710                    var $item = $(template);
711                    $widget.append($item);
712                    $item.data('item', item);
713
714                    $item.find('[data-role="setamount"]').val(amount.value);
715                    $item.find('[data-role="itemprice"]').html(price.value);
716                    $item.find('[data-role="itemname"]').html(name.value);
717                    $item.find('[data-role="itemphoto"]').attr(
718                        'data-lazy-bgimage', photo.value || blankgif
719                    );
720
721                    $item.find('[data-role="removefromcart"]').on('click', function () {
722                        creatium.cart.remove(item);
723                    });
724
725                    $item.find('[data-role="setamount"]').on('change', function () {
726                        var value = $(this).val() * 1;
727                        creatium.cart.setAmount(item, value);
728                    });
729
730                    $item.find('[data-role="increaseamount"]').on('click', function () {
731                        var value = amount.value + 1;
732                        creatium.cart.setAmount(item, value);
733                    });
734
735                    $item.find('[data-role="decreaseamount"]').on('click', function () {
736                        var value = amount.value - 1;
737                        creatium.cart.setAmount(item, value);
738                    });
739
740                    console.time('cart add trigger');
741                    creatium.init.trigger($item[0]);
742                    console.timeEnd('cart add trigger');
743                }
744            });
745
746            $items.each(function () {
747                var $item = $(this);
748
749                var item = $item.data('item');
750
751                if (creatium.cart.list.indexOf(item) < 0) {
752                    // Удаление
753
754                    $item.slideUp(250, function () {
755                        $item.remove();
756                    });
757                }
758            });
759        };
760
761        // Отсрочка нужна, чтобы сначала выполнился creatium.init.global,
762        // а только потом на страницу были добавлены новые компоненты в корзине
763        setTimeout(updater, 10);
764        $(creatium).on('cart-change', updater);
765    });
766});
767creatium.init.local(function ($root) {
768    $root.find('.widget-cart-total').each(function () {
769        var $widget = $(this);
770
771        var updater = function () {
772            var total = 0;
773            var currency;
774
775            _.each(creatium.cart.list, function (item) {
776                var amount = _.filter(item, { type: 'amount' })[0].value * 1;
777                var price = _.filter(item, { type: 'price' })[0].value;
778
779                total += creatium.cart.getPrice(price) * amount;
780                currency = currency || creatium.cart.getCurrency(price);
781            });
782
783            if (!creatium.cart.list.length) {
784                var result = '-';
785            } else {
786                var result = currency.replace('%s%', total);
787            }
788
789            $widget.find('[data-role="carttotal"] span').html(result);
790        };
791
792        updater();
793        $(creatium).on('cart-change', updater);
794    });
795});
796creatium.init.local(function ($root) {
797    $root.find('.widget-cms-table').each(function () {
798        var $widget = $(this);
799        var $root = $widget.find('.cms-table-root');
800
801        var table = $root.data('table');
802        var template = $root.data('template');
803
804        $.ajax(creatium.origin + '/app/cms/0.2/getAll', {
805            type: 'POST',
806            data: {},
807            dataType: 'json',
808            contentType: 'application/json',
809            success: function (data, status, xhr) {
810                console.log('CMS: getAll success', data);
811
812                try {
813                    $root.html(_.template(template, _.find(data.tables, { name: table })));
814                } catch (e) {
815                    console.error('CMS: template error', e);
816
817                    var $alert = $('<div class="alert alert-danger" style="margin: 0;"></div>');
818                    $alert.html(e.toString());
819                    $root.empty().append($alert);
820                }
821            },
822            error: function (data, status, xhr) {
823                console.log('CMS: getAll error', data);
824
825                var $alert = $('<div class="alert alert-danger" style="margin: 0;"></div>');
826                $alert.html('Cannot read data from server');
827                $root.empty().append($alert);
828            },
829        });
830    });
831});
832
833creatium.init.local(function ($root) {
834    $root.find('.widget-comments-fb').each(function () {
835        var $widget = $(this);
836
837        var $fb = $widget.find('.fb');
838
839        if ($fb.length) {
840            var fbjoint = $fb.attr('data-joint') === 'true';
841            var href = 'http://' + location.host.replace(/^www\./, '');
842
843            if (!fbjoint) {
844                href += '/' + location.pathname;
845            }
846
847            $fb.attr('data-href', href);
848            $fb.attr('data-width', $fb.width());
849
850            $('head').append('<meta property="fb:app_id" content="' + $fb.data('apiid') + '"/>');
851            $('<div id="fb-root"></div>').appendTo('body');
852
853            (function(d, s, id) {
854                var js, fjs = d.getElementsByTagName(s)[0];
855                if (d.getElementById(id)) return;
856                js = d.createElement(s); js.id = id;
857                js.src = "//connect.facebook.net/ru_RU/sdk.js#xfbml=1&version=v2.8";
858                fjs.parentNode.insertBefore(js, fjs);
859            }(document, 'script', 'facebook-jssdk'));
860        }
861    });
862});
863
864var inthash = function(str) {
865    return _.reduce(str, function(res, sym, key) {
866        return res + sym.charCodeAt() * Math.pow(key + 5, 5);
867    }, str.length);
868};
869
870creatium.init.local(function ($root) {
871    $root.find('.widget-comments-vk').each(function () {
872        var $widget = $(this);
873
874        var $vk = $widget.find('.vk');
875
876        if ($vk.length && $vk.data('apiid')) {
877            var id = _.uniqueId('vk_comments');
878            $vk.attr('id', id);
879
880            var vkjoint = $vk.attr('data-joint') === 'true';
881            var page_id = 1;
882
883            if (!vkjoint) {
884                page_id = inthash(location.host.replace(/^www\./, '') + '/' + location.pathname);
885            }
886
887            $.getScript("//vk.com/js/api/openapi.js?112", function () {
888                VK.init({
889                    apiId: $vk.data('apiid'),
890                    onlyWidgets: true
891                });
892
893                VK.Widgets.Comments(id, {
894                    limit: 5,
895                    width: $vk.width(),
896                    attach: "*"
897                }, page_id);
898            });
899        }
900    });
901});
902function ourDay(theirDay) {
903    if (theirDay > 0) return theirDay - 1;
904    if (theirDay === 0) return 6;
905}
906
907creatium.init.local(function ($root) {
908    $root.find('.widget-countdown').each(function() {
909        var $widget = $(this);
910        $widget.children('.metahtml').show();
911
912        var $root = $widget.find('[cr-countdown-root]');
913        var settings = $root.data('vals');
914        var variables = $root.data('variables') || {};
915        var now = new Date;
916
917        // Этот код должен быть синхронизирован с кодом в node.js
918        var date;
919        if (settings.type === 'full') {
920            settings.full_date.day++;
921            date = new Date(settings.full_date.year, settings.full_date.month, settings.full_date.day, settings.full_time.hour, settings.full_time.minute);
922        } else if (settings.type === 'month') {
923            settings.month_day++;
924            date = new Date(now.getFullYear(), now.getMonth(), settings.month_day, settings.month_time.hour, settings.month_time.minute);
925            if (date.getTime() < now.getTime()) {
926                date = new Date(now.getFullYear(), now.getMonth() + 1, settings.month_day, settings.month_time.hour, settings.month_time.minute);
927            }
928        } else if (settings.type === 'week') {
929            var add = settings.week_day - ourDay(now.getDay());
930            date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + add, settings.week_time.hour, settings.week_time.minute);
931            if (date.getTime() < now.getTime()) {
932                add = 7 - ourDay(now.getDay()) + settings.week_day;
933                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + add, settings.week_time.hour, settings.week_time.minute);
934            }
935        } else if (settings.type === 'day') {
936            date = new Date(now.getFullYear(), now.getMonth(), now.getDate(), settings.day_time.hour, settings.day_time.minute);
937            if (date.getTime() < now.getTime()) {
938                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, settings.day_time.hour, settings.day_time.minute);
939            }
940        } else if (settings.type === 'fake') {
941            var hash = [settings.fake_days, settings.fake_time.hour, settings.fake_time.minute].join(':');
942            if (creatium.store.get(hash)) {
943                date = new Date(creatium.store.get(hash));
944            } else {
945                date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + settings.fake_days, now.getHours() + settings.fake_time.hour, now.getMinutes() + settings.fake_time.minute);
946                creatium.store.set(hash, date.getTime());
947            }
948        }
949
950        var timezone = settings.type === 'fake' || settings.timezone === 'default' ? null : settings.timezone;
951
952        if (settings.action.type === "show_element") {
953            $('#' + settings.action.element_id).hide();
954        }
955
956        var onExpiry = function() {
957            if (settings.action.type === 'message') {
958                creatium['msg_' + settings.action.message.type](settings.action.message.title, settings.action.message.text);
959            }
960
961            if (settings.action.type === 'redirect') {
962                if (settings.action.url) {
963                    location.href = settings.action.url;
964                }
965            }
966
967            if (settings.action.type === 'show_element') {
968                $('#' + settings.action.element_id).show();
969            }
970
971            if (settings.action.type === 'hide_element') {
972                $('#' + settings.action.element_id).hide();
973            }
974
975            if (settings.action.type === 'show_popup') {
976                creatium.modals.show($widget.find('.modal').filter(function () {
977                    return $(this).closest('.node')[0] === $widget[0];
978                }));
979            }
980
981            if ($widget.data('api-expired') !== true) {
982                $widget.data('api-expired', true);
983                $widget.triggerHandler('api-expiry');
984            }
985        };
986
987        var countdown = keithWoodCountdown(window.creatium.lang);
988        var updater = creatium.watchDom($widget[0]);
989
990        var tick = function () {
991            if ($widget.data('api-expired')) return;
992
993            updater(_.extend(variables, countdown(date, timezone)));
994            $widget.triggerHandler('api-tick');
995
996            if (date < new Date()) onExpiry();
997        };
998
999        tick();
1000        creatium.syncInterval(tick, 1000);
1001
1002        $widget.data('api-until', countdown.getUntil());
1003
1004        $widget.data('api-setUntil', function (date2) {
1005            date = new Date(date2);
1006
1007            if (date.getTime() < new Date().getTime()) return;
1008
1009            timezone = null;
1010            $widget.data('api-until', date);
1011            $widget.data('api-expired', false);
1012            tick();
1013        });
1014    });
1015});
1016
1017creatium.init.local(function ($root) {
1018    $root.find('.widget-defer').each(function () {
1019        var $defer = $(this);
1020
1021        setTimeout(function () {
1022            $defer.show();
1023        }, $defer.data('timeout') * 1000)
1024    });
1025});
1026creatium.init.global(function () {
1027    creatium.syncInterval(function () {
1028        var $active = $(document.activeElement).closest('.widget-field');
1029
1030        if ($active.length ) {
1031            // Чтобы класс is-filled был актуальным
1032            $active.find('input').triggerHandler('input');
1033        }
1034    }, 250);
1035});
1036
1037creatium.init.local(function ($root) {
1038    creatium.lazy.add($root.find('.widget-field'), function ($field) {
1039        var $form = $field.closest('[data-form]');
1040
1041        var vals = $field.find('.metahtml').first().data('vals');
1042
1043        var list = [];
1044        $field.find('[data-item-text][data-item-value]').each(function () {
1045            list.push({
1046                text: $(this).attr('data-item-text'),
1047                value: $(this).attr('data-item-value') * 1 || 0,
1048            });
1049        });
1050
1051        if (!vals) return;
1052
1053        var original;
1054
1055        $field.find('.is-text').each(function () {
1056            var $text = $(this);
1057
1058            $text.find('input, textarea').on('input', function () {
1059                if ($(this).val().length) {
1060                    if (!$text.hasClass('is-filled')) $text.addClass('is-filled');
1061                } else {
1062                    if ($text.hasClass('is-filled')) $text.removeClass('is-filled');
1063                }
1064            });
1065        });
1066
1067        if (["name", "phone", "email", "count", "text", "password", "hidden"].indexOf(vals.type) >= 0) {
1068            original = $field.find('input').val();
1069
1070            $form.on('reset', function () {
1071                $field.find('input').val(original);
1072            });
1073
1074            $field.data('api-setValue', function (value) {
1075                $field.find('input').val(value);
1076            });
1077
1078            if ($field.is('[data-prefill]')) {
1079                original = $field.attr('data-prefill');
1080                $field.data('api-setValue')(original);
1081            }
1082        }
1083
1084        if (vals.type === 'textarea') {
1085            original = $field.find('textarea').val();
1086            $form.on('reset', function () {
1087                $field.find('textarea').val(original);
1088            });
1089
1090            $field.data('api-setValue', function (value) {
1091                $field.find('textarea').val(value);
1092            });
1093
1094            if ($field.is('[data-prefill]')) {
1095                original = $field.attr('data-prefill');
1096                $field.data('api-setValue')(original);
1097            }
1098        }
1099
1100        if (vals.type === 'hackable') {
1101            original = $field.find('[cr-field]').attr('data-value');
1102            $form.on('reset', function () {
1103                $field.find('[cr-field]').attr('data-value', original);
1104            });
1105
1106            var typing = $field.find('[cr-field]').attr('data-type');
1107            $field.data('api-setValue', function (value) {
1108                // Приводим значение к строке
1109                value = value.toString();
1110
1111                // А дальше к нужному типу
1112                if (typing === 'number') {
1113                    value = value * 1 || 0;
1114                } else if (typing === 'boolean') {
1115                    value = value === '1' || value === 'true';
1116                }
1117
1118                $field.find('[cr-field]').attr('data-value', value);
1119            });
1120
1121            if ($field.is('[data-prefill]')) {
1122                original = $field.attr('data-prefill');
1123                $field.data('api-setValue')(original);
1124            }
1125        }
1126
1127        if (vals.type === 'checkbox-list' || vals.type === 'checkbox-visual') {
1128            original = _.map($field.find('input'), function (el) {
1129                return $(el).prop('checked');
1130            });
1131
1132            $form.on('reset', function () {
1133                $field.find('input').each(function (index) {
1134                    $(this).prop('checked', original[index]);
1135                });
1136            });
1137
1138            $field.data('api-setValue', function (value) {
1139                $field.find('input').each(function (index) {
1140                    var item = list[index];
1141
1142                    if (value[item.text] !== undefined) {
1143                        $(this).prop('checked', value[item.text]);
1144                    }
1145                });
1146            });
1147
1148            if ($field.is('[data-prefill]')) {
1149                var prefill = {};
1150
1151                $field.attr('data-prefill').split(',').forEach(function (part) {
1152                    prefill[part.trim()] = true;
1153                });
1154
1155                $field.data('api-setValue')(prefill);
1156
1157                original = _.map($field.find('input'), function (el) {
1158                    return $(el).prop('checked');
1159                });
1160            }
1161        }
1162
1163        if (vals.type === 'checkbox-input') {
1164            original = $field.find('input').prop('checked');
1165            $form.on('reset', function () {
1166                $field.find('input').prop('checked', original);
1167            });
1168
1169            $field.data('api-setValue', function (value) {
1170                $field.find('input').prop('checked', value);
1171            });
1172
1173            if ($field.is('[data-prefill]')) {
1174                original = $field.attr('data-prefill') !== '0';
1175                $field.data('api-setValue')(original);
1176            }
1177        }
1178
1179        if (vals.type === 'privacy-checkbox') {
1180            original = $field.find('input').prop('checked');
1181            $form.on('reset', function () {
1182                $field.find('input').prop('checked', original);
1183            });
1184
1185            $field.data('api-setValue', function (value) {
1186                $field.find('input').prop('checked', value);
1187            });
1188        }
1189
1190        if (vals.type === 'radio-list' || vals.type === 'radio-visual') {
1191            original = _.map($field.find('input'), function (el) {
1192                return $(el).prop('checked');
1193            });
1194
1195            $form.on('reset', function () {
1196                $field.find('input').each(function (index) {
1197                    $(this).prop('checked', original[index]);
1198                });
1199            });
1200
1201            $field.on('change', function (event) {
1202                $field.find('input').filter(function () {
1203                    return this !== event.target;
1204                }).prop('checked', false);
1205            });
1206
1207            $field.data('api-setValue', function (value) {
1208                $field.find('input').prop('checked', false);
1209
1210                $field.find('input').each(function (index) {
1211                    var item = list[index];
1212
1213                    if (item.text === value) {
1214                        $(this).prop('checked', true);
1215                    }
1216                });
1217            });
1218
1219            if ($field.is('[data-prefill]')) {
1220                $field.data('api-setValue')($field.attr('data-prefill'));
1221                original = _.map($field.find('input'), function (el) {
1222                    return $(el).prop('checked');
1223                });
1224            }
1225        }
1226
1227        if (vals.type === 'select-menu') {
1228            $field.find('select option').eq(0).attr('value', '');
1229            $field.find('select option').slice(1).each(function (index) {
1230                $(this).attr('value', index);
1231            });
1232
1233            original = $field.find('select').val();
1234            $form.on('reset', function () {
1235                $field.find('select').val(original);
1236                $field.triggerHandler('change');
1237            });
1238
1239            $field.on('change', function (event) {
1240                $field.find('[cr-field_value]').text($field.find('select option:selected').text());
1241            });
1242
1243            $field.data('api-setValue', function (value) {
1244                if (value) {
1245                    var item = _.find(list, { text: value });
1246                    var index = list.indexOf(item);
1247
1248                    if (index >= 0) {
1249                        $field.find('select').val(index);
1250                    } else {
1251                        $field.find('select').val('');
1252                    }
1253                } else {
1254                    $field.find('select').val('');
1255                }
1256
1257                $field.triggerHandler('change');
1258            });
1259
1260            if ($field.is('[data-prefill]')) {
1261                $field.data('api-setValue')($field.attr('data-prefill'));
1262                original = $field.find('select').val();
1263            }
1264        }
1265
1266        if (vals.type === 'slider') {
1267            var $root = $field.find('[cr-field-input]');
1268            $root.find('style').insertAfter($root);
1269            $root.empty();
1270
1271        
1271    original = $root.attr('value') * 1 || 0;
1272
1273            var $input = $('<input>').val(original).appendTo($root);
1274
1275            var options = {
1276                force_edges: true,
1277                min: vals.min,
1278                max: vals.max,
1279                step: vals.step,
1280                from: original,
1281            };
1282
1283            // Задержка нужна, потому что иначе появляется Forced synchronous layouts,
1284            // и это видно во вкладке Perfomance. Если снова начнет повторяться,
1285            // можно попробовать убрать задержку, или использовать _.setTimeout
1286            // с несколькими произвольными миллисекундами
1287            window.requestAnimationFrame(function init() {
1288                if (!$.fn.ionRangeSlider) {
1289                    return setTimeout(init, 50);
1290                }
1291
1292                $input.ionRangeSlider(options);
1293
1294                if ($field.is('[data-prefill]')) {
1295                    original = $field.attr('data-prefill') * 1 || 0;
1296                    $field.data('api-setValue')(original);
1297                }
1298            });
1299
1300            $form.on('reset', function () {
1301                $input.data("ionRangeSlider").update(options);
1302            });
1303
1304            $field.data('api-setValue', function (value) {
1305                var options2 = _.clone(options);
1306                options2.from = value;
1307                $input.data("ionRangeSlider").update(options2);
1308            });
1309        }
1310
1311        if (vals.type === 'file') {
1312            var $state = $field.find('[cr-field_state]');
1313            $state.data('original-html', $state.html());
1314
1315            var $clean = $field.find('[cr-field_clean]');
1316            $clean.hide();
1317            $clean.on('click', function () {
1318                $field.find(':file').val('');
1319                $state.html($state.data('original-html'));
1320                $field.data('result', null);
1321                $clean.hide();
1322            });
1323
1324            $form.on('reset', function () {
1325                if ($field.is('[data-prefill]')) {
1326                    $field.data('api-setValue')([$field.attr('data-prefill')]);
1327                } else {
1328                    $clean.click();
1329                }
1330            });
1331
1332            $field.on('change', function handler(event) {
1333                if (!$.fn.ajaxSubmit) return setTimeout(function () {
1334                    handler(event);
1335                }, 50);
1336
1337                // на данном этапе форме не нужно знать об изменении
1338                event.stopPropagation();
1339
1340                var $fileinput = $field.find(':file');
1341
1342                var match = $fileinput.val().match(/.+[\/\\](.+)/);
1343                if (!match) return;
1344
1345                var filename = match[1];
1346
1347                // оригинал заменяем копией
1348                $fileinput.clone().insertAfter($fileinput);
1349
1350                if (cr.mini) {
1351                    var $fileform = $('<form>').append($fileinput);
1352                    const formData = new FormData($fileform[0]);
1353
1354                    $state.text(filename + ' (0%)');
1355                    creatium.execute_backend_scenario($field.data('upload-scenario'), formData, {}).then(function (result) {
1356                        $field.data('result', result.url);
1357                        $state.text(filename);
1358                        $clean.show();
1359
1360                        $form.trigger('change');
1361
1362                        $fileform.remove();
1363                    }, function (error) {
1364                        creatium.msg_error(creatium.l10n("Ошибка загрузки!"), error.message);
1365
1366                        $state.html($state.data('original-html'));
1367                        $field.data('result', null);
1368
1369                        $form.trigger('change');
1370
1371                        $fileform.remove();
1372                    });
1373                } else {
1374                    var $fileform = $('<form>').attr({
1375                        'action': creatium.origin + '/app/' + creatium.VERSION + '/file',
1376                        'method': 'POST',
1377                        'enctype': 'multipart/form-data',
1378                    });
1379
1380                    var $pageinput = $('<input>').attr({
1381                        'type': 'hidden',
1382                        'name': 'ImageUploadForm[page]',
1383                        'value': creatium.page_id,
1384                    });
1385
1386                    $fileform.append($fileinput);
1387                    $fileform.append($pageinput);
1388
1389                    $fileform.appendTo('body').hide();
1390
1391                    $fileform.ajaxSubmit({
1392                        dataType: 'json',
1393                        beforeSend: function() {
1394                            return $state.text(filename + ' (0%)');
1395                        },
1396                        uploadProgress: function(event, position, total, percentComplete) {
1397                            return $state.text(filename + ' (' + percentComplete + '%)');
1398                        },
1399                        success: function(result) {
1400                            $field.data('result', result);
1401                            $state.text(filename);
1402                            $clean.show();
1403
1404                            $form.trigger('change');
1405
1406                            $fileform.remove();
1407                        },
1408                        error: function(xhr) {
1409                            creatium.msg_error(creatium.l10n("Ошибка загрузки!"), xhr.status === 400 ? xhr.responseText : null);
1410
1411                            $state.html($state.data('original-html'));
1412                            $field.data('result', null);
1413
1414                            $form.trigger('change');
1415
1416                            $fileform.remove();
1417                        },
1418                    });
1419                }
1420            });
1421
1422            $field.data('api-setValue', function (value) {
1423                var file = value[0];
1424
1425                if (file) {
1426                    var match = file.match(/.+[\/\\](.+)/);
1427                    if (!match) file = null;
1428                }
1429
1430                if (file) {
1431                    var filename = match[1];
1432
1433                    $field.data('result', file);
1434                    $state.text(filename);
1435                    $clean.show();
1436                } else {
1437                    $state.html($state.data('original-html'));
1438                    $field.data('result', null);
1439                }
1440            });
1441
1442            if ($field.is('[data-prefill]')) {
1443                $field.data('api-setValue')([$field.attr('data-prefill')]);
1444            }
1445        }
1446    });
1447});
1448creatium.async.ready(function () {
1449    creatium.init.local(function ($root) {
1450        creatium.lazy.then($root.find('.widget-form2'), function ($widget) {
1451            var filter = function () {
1452                return $(this).closest('.widget')[0] === $widget[0];
1453            };
1454
1455            var $container = $widget.find('.swiper-container').filter(filter);
1456
1457            // если форма не пошаговая
1458            if (!$container.length) return;
1459
1460            var swiper = new Swiper($container.get(0), {
1461                autoHeight: $container.attr('data-fixheight') === 'false',
1462                autoplay: false,
1463                allowTouchMove: false,
1464                effect: $container.attr('data-animated') === 'true' ? 'slide' : 'fade',
1465                fadeEffect: { crossFade: true },
1466                touchEventsTarget: 'container',
1467                mousewheelEventsTarged: 'container',
1468                // Без этой настройки малейшее движение курсора во время клика
1469                // сбрасывает попытку отметить галочку в форме
1470                preventClicks: false,
1471                on: {
1472                    slideChangeTransitionStart: function () {
1473                        // чтобы поля обновились
1474                        $widget.trigger('change');
1475                    }
1476                },
1477            });
1478            $widget.data('api-swiper', swiper);
1479
1480            if ($widget.closest('.modal').length) {
1481                $widget.closest('.modal').on('shown.bs.modal', function () {
1482                    swiper.update();
1483                    $widget.trigger('change');
1484                })
1485            }
1486
1487            $widget.on('slidenext', function (event) {
1488                $widget.trigger('validate', [
1489                    function () {
1490                        swiper.slideNext();
1491                    }
1492                ]);
1493
1494                // если слайдер в другом слайдере, чтобы не листались оба
1495                event.stopPropagation();
1496            });
1497
1498            $widget.on('slideprev', function (event) {
1499                swiper.slidePrev();
1500
1501                // если слайдер в другом слайдере, чтобы не листались оба
1502                event.stopPropagation();
1503            });
1504
1505            // для нормальной инициации внутри модального окна
1506            creatium.lazy.add($widget, function () {
1507                swiper.update();
1508            });
1509
1510            $widget.find('.lazy').on('lazyload', _.throttle(function () {
1511                swiper.update();
1512            }, 500));
1513
1514            if (swiper.params.autoHeight) {
1515                creatium.syncInterval(function () {
1516                    if (swiper.animating || !swiper.slides.length) return;
1517
1518                    var wrapperHeight = swiper.wrapperEl.clientHeight;
1519                    var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
1520                    if (wrapperHeight !== slideHeight) swiper.update();
1521                }, 40);
1522            }
1523        });
1524    });
1525});
1526
1527creatium.init.local(function ($root) {
1528    $root.find('.widget-hamburger').each(function () {
1529        var $widget = $(this);
1530
1531        var filter = function () {
1532            return $(this).closest('.widget-hamburger')[0] === $widget[0];
1533        };
1534
1535        var $toggle = $widget.find('[cr-hamburger-toggle]').filter(filter);
1536        var $container = $widget.find('[cr-hamburger-menu]').filter(filter);
1537
1538        if ($container.hasClass('is-collapsed')) {
1539            creatium.lazy.add($widget, function ($el) {
1540                $container.show();
1541                creatium.lazy.force($container);
1542                $container.hide();
1543            });
1544        }
1545
1546        $toggle.on('click', function () {
1547            if ($container.is(':animated')) return;
1548
1549            $toggle.toggleClass('is-collapsed');
1550            $container.toggleClass('is-collapsed');
1551
1552            $toggle.toggleClass('is-expanded');
1553            $container.toggleClass('is-expanded');
1554
1555            if (scroll_fix) {
1556                $container.toggle();
1557            } else {
1558                $container.slideToggle();
1559            }
1560        });
1561
1562        // Автоскрытие гамбургера по переходу по любой ссылке
1563        // Делается в 3 шага
1564        var scroll_fix = false;
1565
1566        $(creatium).on('before-scroll-to', function () {
1567            if ($container.hasClass('is-expanded')) {
1568                // Отключаем анимацию меню
1569                scroll_fix = true;
1570
1571                // 1. Скрываем меню, чтобы высота фиксированной панели была пересчитана
1572                $toggle.click();
1573            }
1574        });
1575
1576        $(creatium).on('after-scroll-to', function () {
1577            if (scroll_fix) {
1578                // 2. Возвращаем меню, как ни в чем ни бывало
1579                $toggle.click();
1580
1581                // Включаем обратно анимацию меню
1582                scroll_fix = false;
1583
1584                // 3. Теперь скрываем меню с анимацией, красиво
1585                $toggle.click();
1586            }
1587        });
1588    })
1589});
1590
1591creatium.init.local(function ($root) {
1592    $root.find('.widget-hover').each(function () {
1593        var $widget = $(this);
1594
1595        var $hover = $widget.find('[cr-hover]').filter(function () {
1596            return $(this).closest('.widget-hover')[0] === $widget[0];
1597        });
1598
1599        $hover.on('mouseenter', function (event) {
1600            if ($(event.relatedTarget).closest($hover).length) {
1601                // Часть ховера может быть вынесена за пределы компонента,
1602                // и так мы ловим переход курсора с одной части ховера на вынесенную
1603                return;
1604            }
1605
1606            $hover.addClass('hover');
1607            $hover.addClass('animated');
1608
1609            $widget.triggerHandler('api-before-over');
1610
1611            setTimeout(function () {
1612                $hover.removeClass('animated');
1613
1614                $widget.triggerHandler('api-over');
1615            }, $hover.data('duration'));
1616        });
1617
1618        $hover.on('mouseleave', function (event) {
1619            if ($(event.relatedTarget).closest($hover).length) {
1620                // Часть ховера может быть вынесена за пределы компонента,
1621                // и так мы ловим переход курсора с одной части ховера на вынесенную
1622                return;
1623            }
1624
1625            $hover.removeClass('hover');
1626            $hover.addClass('animated');
1627
1628            $widget.triggerHandler('api-before-out');
1629
1630            setTimeout(function () {
1631                $hover.removeClass('animated');
1632
1633                $widget.triggerHandler('api-out');
1634            }, $hover.data('duration'));
1635        });
1636    })
1637});
1638
1639creatium.init.global(function () {
1640    $('.widget-html .code[data-html]').each(function () {
1641        var $code = $(this);
1642
1643        creatium.lazy.add($code, function ($el) {
1644            $el.html($el.data('html'));
1645            $el.removeAttr('data-html');
1646        });
1647    });
1648});
1649
1650creatium.init.local(function init($root) {
1651    if (!window.stackEffects) return setTimeout(function () {
1652        init($root);
1653    }, 50);
1654
1655    $root.find('.widget-image').each(function() {
1656        $(this).find('.stack-image-content').each(function () {
1657            var $imgStack, options;
1658            $imgStack = $(this);
1659            options = $imgStack.attr('stack_hover_effect');
1660            if (options) {
1661                options = JSON.parse(options);
1662                stackEffects.getInstance(options.effectType, $imgStack.get(0), {
1663                    effectType: options.effectType,
1664                    disableScale: options.disableScale,
1665                    style: options.style
1666                });
1667            }
1668            return $imgStack.removeAttr('stack_hover_effect');
1669        });
1670    });
1671});
1672creatium.init.local(function ($root) {
1673    $root.find('.widget-increasingdigits').each(function () {
1674        var searchDigitsPattern = new RegExp("([0-9]+)", "g"),
1675                digitsWrapper = "<span class='digits-wrapper'>$1</span>",
1676                $digitsContainer = $(this).find('.digits');
1677
1678            var animationDuration = parseFloat($digitsContainer.attr('data-animation-duration')) * 1000 || 0;
1679
1680            $digitsContainer.find('*').andSelf().each(function () {
1681                var textNodeId = 3;
1682
1683                $(this)
1684                    .contents()
1685                    .filter(function () {
1686                        return this.nodeType === textNodeId;
1687                    })
1688                        .each(function () {
1689                            var $digitsContainer = $(this).parent(),
1690                                wrappedTextNodeVal = this.textContent.replace(searchDigitsPattern, digitsWrapper);
1691
1692                            $(this).replaceWith(wrappedTextNodeVal);
1693
1694                            $digitsContainer.find('.digits-wrapper').each(function() {
1695                                $(this)
1696                                    .data('data-number', $(this).text())
1697                                    .text('0');
1698                            })
1699                        })
1700            })
1701
1702        creatium.lazy.add($(this), function init($el) {
1703            if (!$.fn.animateNumber) return setTimeout(function () {
1704                init($el);
1705            }, 50);
1706
1707            $el.find('.digits-wrapper').each(function () {
1708                $(this).animateNumber({ number: $(this).data('data-number') }, animationDuration);
1709            })
1710        })
1711    })
1712});
1713
1714
1715
1716creatium.init.local(function ($root) {
1717    $root.find('.widget-list').each(function () {
1718        var $widget = $(this);
1719
1720        $widget.find('.lazy-loader').one('lazyload', function () {
1721            var file = $(this).attr('src');
1722            $widget.find('li').css('background-image', 'url("' + file + '")');
1723        });
1724    })
1725});
1726
1727
1728
1729creatium.init.local(function ($root) {
1730    $root.find('.widget-pagination').each(function () {
1731        var $widget = $(this);
1732
1733        $widget.find('[href="#"]').on('click', function (event) {
1734            // Во избежание прокрутки к верху страницы
1735            event.preventDefault();
1736        });
1737    })
1738});
1739
1740
1741
1742creatium.init.local(function ($root) {
1743    $root.find('.widget-slide-share').each(function() {
1744        var $slideContainer = $(this).find('.slide');
1745        var userInputString = $slideContainer.attr('data-iframe-string');
1746
1747        if (userInputString) {
1748            var match = userInputString.match(/.*?src="(.*?)"/);
1749
1750            if (match) {
1751                var url = match[1];
1752
1753                if (url) {
1754                    $slideContainer.append('<iframe class="slide-share" src=' + url + ' allowfullscreen></iframe>');
1755                }
1756            }
1757        }
1758    })
1759});
1760
1761creatium.async.ready(function () {
1762    creatium.init.local(function ($root) {
1763        creatium.lazy.add($root.find('.widget-slider'), function ($widget) {
1764            var filter = function () {
1765                return $(this).closest('.widget')[0] === $widget[0];
1766            };
1767
1768            var $container = $widget.find('.swiper-container').filter(filter);
1769            var $next = $widget.find('[cr-slider-next]').filter(filter);
1770            var $previous = $widget.find('[cr-slider-previous]').filter(filter);
1771            var $pages = $widget.find('[cr-slider-page]').filter(filter);
1772            var $index = $widget.find('[cr-slider-index]').filter(filter);
1773
1774            var params = $container.data();
1775
1776            var $icons = $widget.find('[cr-slider-page_icon]').filter(filter).filter(function () {
1777                return $(this).find('>.svgwrap').length > 1;
1778            });
1779            $icons.find('>.svgwrap').addClass('hidden');
1780
1781            var $labels = $widget.find('[cr-slider-page_label]').filter(filter)
1782                .filter(function () {
1783                    return $(this).find('>.textable').length > 1;
1784                });
1785            $labels.find('>.textable').addClass('hidden');
1786
1787            var swiper = new Swiper($container.get(0), {
1788            nested: $widget.closest('.swiper-container').length,
1789            autoHeight: params.fixheight === false,
1790            autoplay: params.auto ? {
1791                delay: params.pause,
1792                stopOnLastSlide: !params.loop,
1793            } : false,
1794            allowTouchMove: params.touch,
1795            effect: params.animated ? 'slide' : 'fade',
1796            fadeEffect: { crossFade: true },
1797            touchEventsTarget: 'container',
1798            mousewheelEventsTarged: 'container',
1799            on: {
1800                slideChange: function () {
1801                    $pages.filter('.is-active').removeClass('is-active');
1802                    $pages.eq(swiper.activeIndex).addClass('is-active');
1803
1804                        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
1805                        setImage(swiper.oldActiveIndex, swiper.activeIndex);
1806                        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
1807
1808                        $index.text(swiper.activeIndex + 1);
1809
1810                        swiper.oldActiveIndex = swiper.activeIndex;
1811                    },
1812                },
1813            });
1814            $widget.data('api-swiper', swiper);
1815
1816            swiper._params = params;
1817            swiper.oldActiveIndex = swiper.activeIndex;
1818
1819            setIcon(swiper.oldActiveIndex, swiper.activeIndex);
1820
1821            function setIcon(oldIndex, newIndex) {
1822                $icons.each(function () {
1823                    var $svgwraps = $(this).children('.svgwrap');
1824                    $svgwraps.eq(oldIndex).addClass('hidden');
1825                    $svgwraps.eq(newIndex).removeClass('hidden');
1826                });
1827            }
1828
1829            setImage(swiper.oldActiveIndex, swiper.activeIndex);
1830
1831            function setImage(oldIndex, newIndex) {
1832                $icons.each(function () {
1833                    var $images = $(this).children();
1834                    $images.eq(oldIndex).addClass('hidden');
1835                    $images.eq(newIndex).removeClass('hidden');
1836                });
1837            }
1838
1839            setLabel(swiper.oldActiveIndex, swiper.activeIndex);
1840
1841            function setLabel(oldIndex, newIndex) {
1842                $labels.each(function () {
1843                    var $textables = $(this).children('.textable');
1844                    $textables.eq(oldIndex).addClass('hidden');
1845                    $textables.eq(newIndex).removeClass('hidden');
1846                });
1847            }
1848
1849            $widget.on('slidenext', function (event) {
1850                if (swiper.isEnd && params.loop) {
1851                    swiper.slideTo(0);
1852                } else {
1853                    swiper.slideNext();
1854                }
1855            });
1856
1857            $next.on('click', function () {
1858                $widget.triggerHandler('slidenext');
1859            });
1860
1861            $widget.on('slideprev', function (event) {
1862                if (swiper.isBeginning && params.loop) {
1863                    swiper.slideTo(swiper.slides.length - 1);
1864                } else {
1865                    swiper.slidePrev();
1866                }
1867            });
1868
1869            $previous.on('click', function () {
1870                $widget.triggerHandler('slideprev');
1871            });
1872
1873            $pages.on('click', function () {
1874                swiper.slideTo($(this).index());
1875            });
1876
1877            $widget.find('.lazy').on('lazyload', _.throttle(function () {
1878                swiper.update();
1879            }, 500));
1880
1881            if (swiper.params.autoHeight) {
1882                creatium.syncInterval(function () {
1883                    if (swiper.animating || !swiper.slides.length) return;
1884
1885                    var wrapperHeight = swiper.wrapperEl.clientHeight;
1886                    var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
1887                    if (wrapperHeight !== slideHeight) swiper.update();
1888                }, 40);
1889            }
1890        });
1891    });
1892});
1893
1894creatium.init.local(function ($root) {
1895    creatium.lazy.add($root.find('.widget-slider-gallery'), function init($widget) {
1896        if (!window.Swiper) return setTimeout(function () {
1897            init($widget);
1898        }, 50);
1899
1900        var filter = function () {
1901            return $(this).closest('.widget')[0] === $widget[0];
1902        };
1903
1904        var $container = $widget.find('.swiper-container').filter(filter);
1905        var $next = $widget.find('[cr-slider-next]').filter(filter);
1906        var $previous = $widget.find('[cr-slider-previous]').filter(filter);
1907        var $pages = $widget.find('[cr-slider-page]').filter(filter);
1908        var $index = $widget.find('[cr-slider-index]').filter(filter);
1909
1910        var params = $container.data();
1911
1912        var swiper = new Swiper($container.get(0), {
1913            nested: $widget.closest('.swiper-container').length,
1914            autoHeight: params.fixheight === false,
1915            autoplay: params.auto ? {
1916                delay: params.pause,
1917                stopOnLastSlide: !params.loop,
1918            } : false,
1919            allowTouchMove: params.touch,
1920            effect: params.animated ? 'slide' : 'fade',
1921            fadeEffect: { crossFade: true },
1922            touchEventsTarget: 'container',
1923            mousewheelEventsTarged: 'container',
1924            on: {
1925                slideChange: function () {
1926                    $pages.filter('.is-active').removeClass('is-active');
1927                    $pages.eq(swiper.activeIndex).addClass('is-active');
1928
1929                    $index.text(swiper.activeIndex + 1);
1930
1931                    swiper.oldActiveIndex = swiper.activeIndex;
1932                },
1933            },
1934        });
1935        $widget.data('api-swiper', swiper);
1936
1937        swiper._params = params;
1938        swiper.oldActiveIndex = swiper.activeIndex;
1939
1940        $widget.on('slidenext', function (event) {
1941            if (swiper.isEnd) {
1942                swiper.slideTo(0);
1943            } else {
1944                swiper.slideNext();
1945            }
1946        });
1947
1948        $next.on('click', function () {
1949            $widget.triggerHandler('slidenext');
1950        });
1951
1952        $widget.on('slideprev', function (event) {
1953            if (swiper.isBeginning) {
1954                swiper.slideTo(swiper.slides.length - 1);
1955            } else {
1956                swiper.slidePrev();
1957            }
1958        });
1959
1960        $previous.on('click', function () {
1961            $widget.triggerHandler('slideprev');
1962        });
1963
1964        $pages.on('click', function () {
1965            swiper.slideTo($(this).index());
1966        });
1967
1968        // для нормальной инициации внутри модального окна
1969        creatium.lazy.add($widget, function () {
1970            swiper.update();
1971        });
1972
1973        $widget.find('.lazy').on('lazyload', function () {
1974            swiper.update();
1975        });
1976    });
1977});
1978
1979/*
1980 *  @author Vikky Shostak https://koddr.me
1981 *  @copyright Copyright (c) 2016, Koddr
1982 *  @license http://opensource.org/licenses/MIT The MIT License (MIT)
1983 *  @version 3.2.9 at 12/09/2016 (22:45)
1984 *
1985 *  goodshare.js
1986 *
1987 *  Useful jQuery plugin that will help your website visitors share a link on
1988 *  social networks and microblogs. Easy to install and configuring on any of
1989 *  your website!
1990 *
1991 *  @category jQuery plugin
1992 */
1993;(function ($, window, document, undefined) {
1994  $(document).ready(function () {
1995    /*
1996     *  Variables
1997     */
1998    var metaOGDescription = $('meta[property="og:description"]').attr('content') || '';
1999    var metaOGImage = $('meta[property="og:image"]').attr('content') || '';
2000    /*
2001     *  Main function
2002     */
2003    goodshare = {
2004      init: function (_element, _options) {
2005        /*
2006         *  Default options:
2007         *
2008         *  type = vk
2009         *  url = current browser adress stroke
2010         *  title = current document <title>
2011         *  text = current document <meta property="og:description" ... />
2012         *  image = current document <meta property="og:image" ... />
2013         */
2014        var self = goodshare, options = $.extend({
2015          type: 'vk',
2016          url: location.href,
2017          title: document.title,
2018          text: metaOGDescription,
2019          image: metaOGImage
2020        }, $(_element).data(), _options);
2021        /*
2022         *  Open popup
2023         */
2024        if (self.popup(link = self[options.type](options)) !== null) return false;
2025      },
2026      /*
2027       *  Share link > Vkontakte
2028       *  @see http://vk.com
2029       */
2030      vk: function (_options) {
2031        var options = $.extend({
2032          url: location.href,
2033          title: document.title,
2034          text: metaOGDescription,
2035          image: metaOGImage
2036        }, _options);
2037        return 'http://vk.com/share.php?'
2038          + 'url=' + encodeURIComponent(options.url)
2039          + '&title=' + encodeURIComponent(options.title)
2040          + '&description=' + encodeURIComponent(options.text)
2041          + '&image=' + encodeURIComponent(options.image);
2042      },
2043      /*
2044       *  Share link > Odnoklassniki
2045       *  @see http://ok.ru
2046       */
2047      ok: function (_options) {
2048        var options = $.extend({
2049          url: location.href,
2050          title: document.title
2051        }, _options);
2052        return 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1'
2053          + '&st.comments=' + encodeURIComponent(options.title)
2054          + '&st._surl=' + encodeURIComponent(options.url);
2055      },
2056      /*
2057       *  Share link > Facebook
2058       *  @see http://facebook.com
2059       */
2060      fb: function (_options) {
2061        var options = $.extend({
2062          url: location.href,
2063          title: document.title
2064        }, _options);
2065        return 'https://facebook.com/sharer/sharer.php?'
2066          + 'u=' + encodeURIComponent(options.url);
2067      },
2068      /*
2069       *  Share link > LiveJournal
2070       *  @see http://livejournal.com
2071       */
2072      lj: function (_options) {
2073        var options = $.extend({
2074          url: location.href,
2075          title: document.title,
2076          text: metaOGDescription
2077        }, _options);
2078        return 'http://livejournal.com/update.bml?'
2079          + 'subject=' + encodeURIComponent(options.title)
2080          + '&event=' + encodeURIComponent('<a href="' + options.url + '">' + options.title + '</a> ' + options.text);
2081      },
2082      /*
2083       *  Share link > Twitter
2084       *  @see http://twitter.com
2085       */
2086      tw: function (_options) {
2087        var options = $.extend({
2088          url: location.href,
2089          title: document.title
2090        }, _options);
2091        return 'http://twitter.com/share?'
2092          + 'url=' + encodeURIComponent(options.url)
2093          + '&text=' + encodeURIComponent(options.title);
2094      },
2095      /*
2096       *  Share link > Google Plus
2097       *  @see http://plus.google.com
2098       */
2099      gp: function (_options) {
2100        var options = $.extend({
2101          url: location.href
2102        }, _options);
2103        return 'https://plus.google.com/share?'
2104          + 'url=' + encodeURIComponent(options.url);
2105      },
2106      /*
2107       *  Share link > [email protected]
2108       *  @see http://my.mail.ru
2109       */
2110      mr: function (_options) {
2111        var options = $.extend({
2112          url: location.href,
2113          title: document.title,
2114          text: metaOGDescription,
2115          image: metaOGImage
2116        }, _options);
2117        return 'http://connect.mail.ru/share?'
2118          + 'url=' + encodeURIComponent(options.url)
2119          + '&title=' + encodeURIComponent(options.title)
2120          + '&description=' + encodeURIComponent(options.text)
2121          + '&imageurl=' + encodeURIComponent(options.image);
2122      },
2123      /*
2124       *  Share link > LinkedIn
2125       *  @see http://linkedin.com
2126       */
2127      li: function (_options) {
2128        var options = $.extend({
2129          url: location.href,
2130          title: document.title,
2131          text: metaOGDescription
2132        }, _options);
2133        return 'http://www.linkedin.com/shareArticle?'
2134          + 'url=' + encodeURIComponent(options.url)
2135          + '&text=' + encodeURIComponent(options.title)
2136          + '&summary=' + encodeURIComponent(options.text)
2137          + '&mini=true';
2138      },
2139      /*
2140       *  Share link > tumblr
2141       *  @see http://tumblr.com
2142       */
2143      tm: function (_options) {
2144        var options = $.extend({
2145          url: location.href,
2146          title: document.title,
2147          text: metaOGDescription
2148        }, _options);
2149        return 'https://www.tumblr.com/widgets/share/tool?'
2150          + 'canonicalUrl=' + encodeURIComponent(options.url)
2151          + '&title=' + encodeURIComponent(options.title)
2152          + '&caption=' + encodeURIComponent(options.text)
2153          + '&posttype=link';
2154      },
2155      /*
2156       *  Share link > Blogger
2157       *  @see https://www.blogger.com
2158       */
2159      bl: function (_options) {
2160        var options = $.extend({
2161          url: location.href,
2162          title: document.title
2163        }, _options);
2164        return 'https://www.blogger.com/blog-this.g?'
2165          + 'u=' + encodeURIComponent(options.url)
2166          + '&n=' + encodeURIComponent(options.title);
2167      },
2168      /*
2169       *  Share link > Pinterest
2170       *  @see http://www.pinterest.com
2171       */
2172      pt: function (_options) {
2173        var options = $.extend({
2174          url: location.href,
2175          title: document.title,
2176          image: $('meta[property="og:image"]').attr('content')
2177        }, _options);
2178        return 'https://www.pinterest.com/pin/create/button/?'
2179          + 'url=' + encodeURIComponent(options.url)
2180          + '&media=' + encodeURIComponent(options.image)
2181          + '&description=' + encodeURIComponent(options.title);
2182      },
2183      /*
2184       *  Share link > Evernote
2185       *  @see http://www.evernote.com
2186       */
2187      en: function (_options) {
2188        var options = $.extend({
2189          url: location.href,
2190          title: document.title,
2191          text: metaOGDescription
2192        }, _options);
2193        return 'https://www.evernote.com/clip.action?'
2194          + 'url=' + encodeURIComponent(options.url)
2195          + '&title=' + encodeURIComponent(options.title)
2196          + '&body=' + encodeURIComponent(options.text + '<br/><a href="' + options.url + '">' + options.title + '</a>');
2197      },
2198      /*
2199       *  Share link > Digg
2200       *  @see http://www.digg.com
2201       */
2202      di: function (_options) {
2203        var options = $.extend({
2204          url: location.href,
2205          title: document.title
2206        }, _options);
2207        return 'http://digg.com/submit?'
2208          + 'url=' + encodeURIComponent(options.url)
2209          + '&title=' + encodeURIComponent(options.title);
2210      },
2211      /*
2212       *  Share link > Reddit
2213       *  @see http://www.reddit.com
2214       */
2215      rd: function (_options) {
2216        var options = $.extend({
2217          url: location.href,
2218          title: document.title
2219        }, _options);
2220        return 'http://www.reddit.com/submit?'
2221          + 'url=' + encodeURIComponent(options.url)
2222          + '&title=' + encodeURIComponent(options.title);
2223      },
2224      /*
2225       *  Share link > Delicious
2226       *  @see https://delicious.com
2227       */
2228      de: function (_options) {
2229        var options = $.extend({
2230          url: location.href,
2231          title: document.title
2232        }, _options);
2233        return 'https://delicious.com/save?'
2234          + 'url=' + encodeURIComponent(options.url)
2235          + '&title=' + encodeURIComponent(options.title);
2236      },
2237      /*
2238       *  Share link > StumbleUpon
2239       *  @see http://www.stumbleupon.com
2240       */
2241      su: function (_options) {
2242        var options = $.extend({
2243          url: location.href,
2244          title: document.title
2245        }, _options);
2246        return 'http://www.stumbleupon.com/submit?'
2247          + 'url=' + encodeURIComponent(options.url)
2248          + '&title=' + encodeURIComponent(options.title);
2249      },
2250      /*
2251       *  Share link > Pocket
2252       *  @see https://getpocket.com
2253       */
2254      po: function (_options) {
2255        var options = $.extend({
2256          url: location.href,
2257          title: document.title
2258        }, _options);
2259        return 'https://getpocket.com/save?'
2260          + 'url=' + encodeURIComponent(options.url)
2261          + '&title=' + encodeURIComponent(options.title);
2262      },
2263      /*
2264       *  Share link > Surfingbird
2265       *  @see http://www.surfingbird.ru
2266       */
2267      sb: function (_options) {
2268        var options = $.extend({
2269          url: location.href,
2270          title: document.title,
2271          text: metaOGDescription
2272        }, _options);
2273        return 'http://surfingbird.ru/share?'
2274          + 'url=' + encodeURIComponent(options.url)
2275          + '&title=' + encodeURIComponent(options.title)
2276          + '&description=' + encodeURIComponent(options.text);
2277      },
2278      /*
2279       *  Share link > LiveInternet
2280       *  @see http://www.liveinternet.ru
2281       */
2282      lr: function (_options) {
2283        var options = $.extend({
2284          url: location.href,
2285          title: document.title
2286        }, _options);
2287        return 'http://www.liveinternet.ru/journal_post.php?action=n_add&'
2288          + 'cnurl=' + encodeURIComponent(options.url)
2289          + '&cntitle=' + encodeURIComponent(options.title);
2290      },
2291      /*
2292       *  Share link > Buffer
2293       *  @see http://buffer.com
2294       */
2295      bf: function (_options) {
2296        var options = $.extend({
2297          url: location.href,
2298          title: document.title
2299        }, _options);
2300        return 'https://buffer.com/add?'
2301          + 'url=' + encodeURIComponent(options.url)
2302          + '&text=' + encodeURIComponent(options.title);
2303      },
2304      /*
2305       *  Share link > Instapaper
2306       *  @see https://www.instapaper.com
2307       */
2308      ip: function (_options) {
2309        var options = $.extend({
2310          url: location.href,
2311          title: document.title
2312        }, _options);
2313        return 'https://www.instapaper.com/edit?'
2314          + 'url=' + encodeURIComponent(options.url)
2315          + '&title=' + encodeURIComponent(options.title);
2316      },
2317      /*
2318       *  Share link > Readability
2319       *  @see http://www.readability.com
2320       */
2321      ra: function (_options) {
2322        var options = $.extend({
2323          url: location.href
2324        }, _options);
2325        return 'http://www.readability.com/save?'
2326          + 'url=' + encodeURIComponent(options.url);
2327      },
2328      /*
2329       *  Share link > Xing
2330       *  @see https://www.xing.com
2331       */
2332      xi: function (_options) {
2333        var options = $.extend({
2334          url: location.href
2335        }, _options);
2336        return 'https://www.xing.com/spi/shares/new?'
2337          + 'url=' + encodeURIComponent(options.url);
2338      },
2339      /*
2340       *  Share link > WordPress
2341       *  @see https://www.wordpress.com
2342       */
2343      wp: function (_options) {
2344        var options = $.extend({
2345          url: location.href,
2346          title: document.title,
2347          text: metaOGDescription,
2348          image: metaOGImage
2349        }, _options);
2350        return 'https://wordpress.com/wp-admin/press-this.php?'
2351          + 'u=' + encodeURIComponent(options.url)
2352          + '&t=' + encodeURIComponent(options.title)
2353          + '&s=' + encodeURIComponent(options.text)
2354          + '&i=' + encodeURIComponent(options.image)
2355          + '&v=2'
2356      },
2357      /*
2358       *  Share link > Baidu
2359       *  @see http://www.baidu.com
2360       */
2361      bd: function (_options) {
2362        var options = $.extend({
2363          url: location.href,
2364          title: document.title,
2365          text: metaOGDescription
2366        }, _options);
2367        return 'http://cang.baidu.com/do/add?'
2368          + 'it=' + encodeURIComponent(options.title)
2369          + '&iu=' + encodeURIComponent(options.url)
2370          + '&dc=' + encodeURIComponent(options.text)
2371          + '&fr=ien';
2372      },
2373      /*
2374       *  Share link > Renren
2375       *  @see http://www.renren.com
2376       */
2377      rr: function (_options) {
2378        var options = $.extend({
2379          url: location.href,
2380          title: document.title
2381        }, _options);
2382        return 'http://share.renren.com/share/buttonshare.do?'
2383          + 'link=' + encodeURIComponent(options.url)
2384          + '&title=' + encodeURIComponent(options.title);
2385      },
2386      /*
2387       *  Share link > Weibo
2388       *  @see http://www.weibo.com
2389       */
2390      wb: function (_options) {
2391        var options = $.extend({
2392          url: location.href,
2393          title: document.title
2394        }, _options);
2395        return 'http://service.weibo.com/share/share.php?'
2396          + 'url=' + encodeURIComponent(options.url)
2397          + '&title=' + encodeURIComponent(options.title);
2398      },
2399      /*
2400       *  Mobile > Share link > Telegram
2401       *  @see https://telegram.org/faq
2402       *  @category iOS, Android devices
2403       */
2404      tg: function (_options) {
2405        var options = $.extend({
2406          url: location.href,
2407          title: document.title
2408        }, _options);
2409        return 'tg://msg?'
2410          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2411      },
2412      /*
2413       *  Mobile > Share link > Viber
2414       *  @see http://www.viber.com/ru/developers/share_on_viber
2415       *  @category iOS, Android devices
2416       */
2417      vi: function (_options) {
2418        var options = $.extend({
2419          url: location.href,
2420          title: document.title
2421        }, _options);
2422        return 'viber://forward?'
2423          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2424      },
2425      /*
2426       *  Mobile > Share link > WhatsApp
2427       *  @see http://whatsapp-sharing.com
2428       *  @category iOS, Android devices
2429       */
2430      wa: function (_options) {
2431        var options = $.extend({
2432          url: location.href,
2433          title: document.title
2434        }, _options);
2435        return 'whatsapp://send?'
2436          + 'text=' + encodeURIComponent(options.title + ' ' + options.url);
2437      },
2438      /*
2439       *  Mobile > Share link > LINE
2440       *  @see https://media.line.me/howto/en/
2441       *  @category iOS, Android devices
2442       */
2443      ln: function (_options) {
2444        var options = $.extend({
2445          url: location.href,
2446          title: document.title
2447        }, _options);
2448        return 'line://msg/text/'
2449          + encodeURIComponent(options.title + ' ' + options.url);
2450      },
2451      /*
2452       *  Popup window
2453       */
2454      popup: function (url) {
2455        return window.open(url, '', 'left=' + (screen.width - 630) / 2 + ',top=' + (screen.height - 440) / 2 + ',toolbar=0,status=0,scrollbars=0,menubar=0,location=0,width=630,height=440');
2456      }
2457    };
2458    /*
2459     *  Function getCount()
2460     *  Set count to all elements with data-counter attribute.
2461     *
2462     *  @example $(document).getCount(); // Get all counters
2463     */
2464    $.fn.getCount = function () {
2465      /*
2466       *  Function roundCount()
2467       *  Return rounded and pretty value of share count.
2468       *
2469       *  @example roundCount(response.shares) // Rounded value of Facebook counter
2470       */
2471      var roundCount = function (number) {
2472        if (number > 999 && number <= 999999) var result = number / 1000 + 'k';
2473        else if (number > 999999) var result = '>1M';
2474        else var result = number;
2475        return result;
2476      };
2477      /*
2478       *  Function existCount()
2479       *  Check exist counter element.
2480       *
2481       *  @example existCount('[data-counter="fb"]') // Checked exist Facebook counter element
2482       */
2483      var existCount = function (element) {
2484        return ($(element).length > 0);
2485      };
2486      /*
2487       *  Share counter > Vkontakte
2488       *  @see http://vk.com/dev
2489       */
2490      if (existCount('[data-counter="vk"]')) {
2491        $.getJSON('https://vk.com/share.php?act=count&index=1&url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2492        });
2493        if (!window.VK) VK = {};
2494        VK.Share = {
2495          count: function (index, count) {
2496            $('[data-counter="vk"]').text(roundCount(count));
2497          }
2498        };
2499      }
2500      ;
2501      /*
2502       *  Share counter > Facebook
2503       *  @see https://developers.facebook.com
2504       */
2505      if (existCount('[data-counter="fb"]')) {
2506        $.getJSON('https://graph.facebook.com/?id=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2507          if (response.share === undefined) $('[data-counter="fb"]').text('0');
2508          else $('[data-counter="fb"]').text(roundCount(response.share.share_count));
2509        });
2510      }
2511      ;
2512      /*
2513       *	Share counter > Odnoklassniki
2514       *	@see https://apiok.ru
2515       */
2516      if (existCount('[data-counter="ok"]')) {
2517        $.getJSON('https://connect.ok.ru/dk?st.cmd=extLike&uid=1&ref=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2518        });
2519        if (!window.ODKL) ODKL = {};
2520        ODKL.updateCount = function (index, count) {
2521          $('[data-counter="ok"]').text(roundCount(count));
2522        };
2523      }
2524      ;
2525      /*
2526       *  Share counter > Google Plus
2527       *  @see https://developers.google.com/+/
2528       */
2529      if (existCount('[data-counter="gp"]')) {
2530        $.ajax({
2531          type: 'POST',
2532          url: 'https://clients6.google.com/rpc',
2533          processData: true,
2534          contentType: 'application/json',
2535          data: JSON.stringify({
2536            'method': 'pos.plusones.get',
2537            'id': location.href,
2538            'params': {
2539              'nolog': true,
2540              'id': location.href,
2541              'source': 'widget',
2542              'userId': '@viewer',
2543              'groupId': '@self'
2544            },
2545            'jsonrpc': '2.0',
2546            'key': 'p',
2547            'apiVersion': 'v1'
2548          }),
2549          success: function (response) {
2550            $('[data-counter="gp"]').text(roundCount(response.result.metadata.globalCounts.count));
2551          }
2552        });
2553      }
2554      ;
2555      /*
2556       *  Share counter > [email protected]
2557       *  @see http://api.mail.ru
2558       */
2559      if (existCount('[data-counter="mr"]')) {
2560        $.getJSON('https://connect.mail.ru/share_count?url_list=' + encodeURIComponent(location.href) + '&callback=1&func=?', function (response) {
2561          var url = encodeURIComponent(location.href);
2562          for (var url in response) {
2563            if (response.hasOwnProperty(url)) {
2564              var count = response[url].shares;
2565              break;
2566            }
2567          }
2568          if ($.isEmptyObject(response)) $('[data-counter="mr"]').text('0');
2569          else $('[data-counter="mr"]').text(roundCount(count));
2570        });
2571      }
2572      ;
2573      /*
2574       *  Share counter > LinkedIn
2575       *  @see https://developer.linkedin.com
2576       */
2577      if (existCount('[data-counter="li"]')) {
2578        $.getJSON('https://www.linkedin.com/countserv/count/share?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2579          $('[data-counter="li"]').text(roundCount(response.count));
2580        });
2581      }
2582      /*
2583       *  Share counter > tumblr
2584       *  @see https://www.tumblr.com/developers
2585       */
2586      if (existCount('[data-counter="tm"]')) {
2587        $.getJSON('https://api.tumblr.com/v2/share/stats?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2588          $('[data-counter="tm"]').text(roundCount(response.response.note_count));
2589        });
2590      }
2591      ;
2592      /*
2593       *  Share counter > Pinterest
2594       *  @see https://developers.pinterest.com
2595       */
2596      if (existCount('[data-counter="pt"]')) {
2597        $.getJSON('https://api.pinterest.com/v1/urls/count.json?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2598          $('[data-counter="pt"]').text(roundCount(response.count));
2599        });
2600      }
2601      ;
2602      /*
2603       *  Share counter > Reddit
2604       *  @see https://www.reddit.com/dev/api
2605       */
2606      if (existCount('[data-counter="rd"]')) {
2607        $.getJSON('https://www.reddit.com/api/info.json?url=' + encodeURIComponent(location.href) + '&jsonp=?', function (response) {
2608          var count = response.data.children;
2609          if (count.length === 0) $('[data-counter="rd"]').text('0');
2610          else $('[data-counter="rd"]').text(roundCount(count[0].data.score));
2611        });
2612      }
2613      ;
2614      /*
2615       *  Share counter > StumbleUpon
2616       *  @see http://help.stumbleupon.com
2617       */
2618      if (existCount('[data-counter="su"]')) {
2619        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2620          + encodeURIComponent('select * from html where url="http://www.stumbleupon.com/services/1.01/badge.getinfo?url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2621          var count = $.parseJSON(response.query.results.html.body);
2622          if (count.result.views === undefined) $('[data-counter="su"]').text('0');
2623          else $('[data-counter="su"]').text(roundCount(count.result.views));
2624        });
2625      }
2626      ;
2627      /*
2628       *  Share counter > Pocket
2629       *  @see https://widgets.getpocket.com/v1/button?count=horizontal&url=[URL_HERE]
2630       */
2631      if (existCount('[data-counter="po"]')) {
2632        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2633          + encodeURIComponent('select * from html where url="https://widgets.getpocket.com/v1/button?count=horizontal&url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2634          $('[data-counter="po"]').text(roundCount(response.query.results.html.body.div.a.span.em.content));
2635        });
2636      }
2637      ;
2638      /*
2639       *  Share counter > Buffer
2640       *  @see https://buffer.com/developers
2641       */
2642      if (existCount('[data-counter="bf"]')) {
2643        $.getJSON('https://api.bufferapp.com/1/links/shares.json?url=' + encodeURIComponent(location.href) + '&callback=?', function (response) {
2644          $('[data-counter="bf"]').text(roundCount(response.shares));
2645        });
2646      }
2647      ;
2648      /*
2649       *  Share counter > Xing
2650       *  @see https://www.xing-share.com/app/share?op=get_share_button;counter=top;url=[URL_HERE]
2651       */
2652      if (existCount('[data-counter="xi"]')) {
2653        $.getJSON('https://query.yahooapis.com/v1/public/yql?q='
2654          + encodeURIComponent('select * from html where url="https://www.xing-share.com/app/share?op=get_share_button;counter=top;url=' + location.href + '" and xpath="*"') + '&format=json&callback=?', function (response) {
2655          $('[data-counter="xi"]').text(roundCount(response.query.results.html.body.div[0].div[0].span.content));
2656        });
2657      }
2658      ;
2659    };
2660    /*
2661     *  Init click.
2662     */
2663    $(document).on('click', '.goodshare', function (event) {
2664      event.preventDefault();
2665      goodshare.init(this);
2666    });
2667    /*
2668     *  Init share counters.
2669     */
2670    $(document).getCount();
2671  });
2672})(jQuery, window, document);
2673creatium.init.local(function ($root) {
2674    $root.find('.widget-spoiler').each(function () {
2675        var $widget = $(this);
2676
2677        var filter = function () {
2678            return $(this).closest('.widget-spoiler')[0] === $widget[0];
2679        };
2680
2681        var $toggle = $widget.find('[cr-spoiler-toggle]').filter(filter);
2682        var $container = $widget.find('[cr-spoiler-container]').filter(filter);
2683
2684        if ($container.hasClass('is-collapsed')) {
2685            creatium.lazy.add($widget, function ($el) {
2686                $container.show();
2687                creatium.lazy.force($container);
2688                $container.hide();
2689            });
2690        }
2691
2692        $widget.data('api-isCollapsed', $container.hasClass('is-collapsed'));
2693
2694        $widget.on('toggle', function (event) {
2695            // Чтобы внешние спойлеры не реагировали
2696            event.stopPropagation();
2697
2698            $widget.triggerHandler('api-before-toggle');
2699
2700            if ($widget.data('api-prevent')) {
2701                $widget.data('api-prevent', false);
2702                return;
2703            }
2704
2705            $toggle.toggleClass('is-collapsed');
2706            $container.toggleClass('is-collapsed');
2707
2708            $toggle.toggleClass('is-expanded');
2709            $container.toggleClass('is-expanded');
2710
2711            $container.stop().slideToggle().promise().always(function () {
2712                $widget.data('api-isCollapsed', !$widget.data('api-isCollapsed'));
2713
2714                $widget.triggerHandler('api-toggle');
2715            });
2716        });
2717
2718        $toggle.on('click', function (event) {
2719            $widget.trigger('toggle');
2720
2721            // На случай вложенных $toggle
2722            event.stopPropagation();
2723        });
2724    })
2725});
2726
2727creatium.init.local(function ($root) {
2728    creatium.lazy.add($root.find('.widget-stories-panel'), function ($widget) {
2729        $widget.find('[cr-stories-panel-highlight]').on('click', function handler(event) {
2730            var index = $(event.currentTarget).index();
2731
2732            var swiper = $('.modal[data-type="stories"]:visible').data('api-swiper');
2733
2734            if (swiper) swiper.slideTo(index);
2735            else setTimeout(handler.bind(this, event), 10);
2736        });
2737    });
2738});
2739creatium.init.local(function ($root) {
2740    creatium.lazy.add($root.find('.widget-tabs'), function init($widget) {
2741        if (!window.Swiper) return setTimeout(function () {
2742            init($widget);
2743        }, 50);
2744
2745        var filter = function () {
2746            return $(this).closest('.widget')[0] === $widget[0];
2747        };
2748
2749        var $container = $widget.find('.swiper-container').filter(filter);
2750        var $next = $widget.find('[cr-slider-next]').filter(filter);
2751        var $previous = $widget.find('[cr-slider-previous]').filter(filter);
2752        var $pages = $widget.find('[cr-slider-page]').filter(filter);
2753        var $index = $widget.find('[cr-slider-index]').filter(filter);
2754
2755        var params = $container.data();
2756
2757        var $icons = $widget.find('[cr-slider-page_icon]').filter(filter).filter(function () {
2758            return $(this).find('>.svgwrap').length > 1;
2759        });
2760        $icons.find('>.svgwrap').addClass('hidden');
2761
2762        var $labels = $widget.find('[cr-slider-page_label]').filter(filter)
2763            .filter(function () {
2764                return $(this).find('>.textable').length > 1;
2765            });
2766        $labels.find('>.textable').addClass('hidden');
2767
2768        var swiper = new Swiper($container.get(0), {
2769            nested: $widget.closest('.swiper-container').length,
2770            autoHeight: params.fixheight === false,
2771            autoplay: params.auto ? {
2772                delay: params.pause,
2773                stopOnLastSlide: !params.loop,
2774            } : false,
2775            allowTouchMove: params.touch,
2776            effect: params.animated ? 'slide' : 'fade',
2777            fadeEffect: { crossFade: true },
2778            touchEventsTarget: 'container',
2779            mousewheelEventsTarged: 'container',
2780            on: {
2781                slideChange: function () {
2782                    $pages.filter('.is-active').removeClass('is-active');
2783                    $pages.eq(swiper.activeIndex).addClass('is-active');
2784
2785                    setIcon(swiper.oldActiveIndex, swiper.activeIndex);
2786                    setImage(swiper.oldActiveIndex, swiper.activeIndex);
2787                    setLabel(swiper.oldActiveIndex, swiper.activeIndex);
2788
2789                    $index.text(swiper.activeIndex + 1);
2790
2791                    swiper.oldActiveIndex = swiper.activeIndex;
2792                },
2793            },
2794        });
2795        $widget.data('api-swiper', swiper);
2796
2797        swiper._params = params;
2798        swiper.oldActiveIndex = swiper.activeIndex;
2799
2800        setIcon(swiper.oldActiveIndex, swiper.activeIndex);
2801
2802        function setIcon(oldIndex, newIndex) {
2803            $icons.each(function () {
2804                var $svgwraps = $(this).children('.svgwrap');
2805                $svgwraps.eq(oldIndex).addClass('hidden');
2806                $svgwraps.eq(newIndex).removeClass('hidden');
2807            });
2808        }
2809
2810        setImage(swiper.oldActiveIndex, swiper.activeIndex);
2811
2812        function setImage(oldIndex, newIndex) {
2813            $icons.each(function () {
2814                var $images = $(this).children();
2815                $images.eq(oldIndex).addClass('hidden');
2816                $images.eq(newIndex).removeClass('hidden');
2817            });
2818        }
2819
2820        setLabel(swiper.oldActiveIndex, swiper.activeIndex);
2821
2822        function setLabel(oldIndex, newIndex) {
2823            $labels.each(function () {
2824                var $textables = $(this).children('.textable');
2825                $textables.eq(oldIndex).addClass('hidden');
2826                $textables.eq(newIndex).removeClass('hidden');
2827            });
2828        }
2829
2830        $widget.on('slidenext', function (event) {
2831            if (swiper.isEnd && params.loop) {
2832                swiper.slideTo(0);
2833            } else {
2834                swiper.slideNext();
2835            }
2836        });
2837
2838        $next.on('click', function () {
2839            $widget.triggerHandler('slidenext');
2840        });
2841
2842        $widget.on('slideprev', function (event) {
2843            if (swiper.isBeginning && params.loop) {
2844                swiper.slideTo(swiper.slides.length - 1);
2845            } else {
2846                swiper.slidePrev();
2847            }
2848        });
2849
2850        $previous.on('click', function () {
2851            $widget.triggerHandler('slideprev');
2852        });
2853
2854        $pages.on('click', function () {
2855            swiper.slideTo($(this).index());
2856        });
2857
2858        $widget.find('.lazy').on('lazyload', _.throttle(function () {
2859            swiper.update();
2860        }, 500));
2861
2862        if (swiper.params.autoHeight) {
2863            creatium.syncInterval(function () {
2864                if (swiper.animating || !swiper.slides.length) return;
2865
2866                var wrapperHeight = swiper.wrapperEl.clientHeight;
2867                var slideHeight = swiper.slides[swiper.activeIndex].clientHeight;
2868                if (wrapperHeight !== slideHeight) swiper.update();
2869            }, 40);
2870        }
2871    });
2872});
2873
2874creatium.init.local(function ($root) {
2875    $root.find('.widget-video').each(function () {
2876        var $widget = $(this);
2877
2878        var $modal = $widget.closest('.modal');
2879        $modal.on('hide', function() {
2880            var $iframeWrap = $widget.find('.video-wrapper');
2881            return $iframeWrap.attr('src', $iframeWrap.attr('src').replace('autoplay=1', 'autoplay=0'));
2882        });
2883    });
2884});
2885})($);

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.