PageSourceSearch

https://doitinpublic.com/awesomeotters/wp-content/plugins/salon-booking-system/js/salon.js?ver=20180117

js doitinpublic.com collected 2026-10-08 07:24:30 UTC 28,089 bytes, 770 lines download raw bytes

1Number.prototype.formatMoney = function (c, d, t) {
2    var n = this,
3        c = isNaN(c = Math.abs(c)) ? 2 : c,
4        d = d == undefined ? "." : d,
5        t = t == undefined ? "," : t,
6        s = n < 0 ? "-" : "",
7        i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
8        j = (j = i.length) > 3 ? j % 3 : 0;
9    return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
10};
11
12if (jQuery.widget !== undefined && jQuery.ui.tooltip !== undefined) {
13    jQuery.widget.bridge('uitooltip', jQuery.ui.tooltip); // Resolve name collision between jQuery UI and Twitter Bootstrap
14}
15
16jQuery(function ($) {
17    sln_init($);
18    if(salon.has_stockholm_transition == 'yes'){
19        $('body').on("click",'a[target!="_blank"]:not(.no_ajax):not(.no_link)', function(){setTimeout(function(){sln_init(jQuery);}, 2000)});
20    }
21});
22
23function sln_init($) {
24    if ($('#salon-step-services').length || $('#salon-step-secondary').length) {
25        sln_serviceTotal($);
26    }
27    if ($('#salon-step-date').length) {
28        sln_stepDate($);
29    } else {
30        if ($('#salon-step-details').length) {
31            $('a.tec-link').click(function (e) {
32                e.preventDefault();
33                var href = $(this).attr('href');
34                var locHref = window.location.href;
35                var hrefGlue = (href.indexOf('?') == -1) ? '?' : '&' ;
36                var locHrefGlue = (locHref.indexOf('?') == -1) ? '?' : '&';
37                window.location.href = href + hrefGlue +'redirect_to=' + encodeURI(locHref + locHrefGlue +'sln_step_page=details');
38            });
39        }
40        if ($('[data-salon-click="fb_login"]').length) {
41            if (window.fbAsyncInit === undefined) {     
42                if (salon.fb_app_id !== undefined) {                
43                    facebookInit();
44                }
45                else {
46                    jQuery('[data-salon-click=fb_login]').remove();
47                }
48            }
49            else {
50                jQuery('[data-salon-click=fb_login]').unbind('click').click(function() {
51                    FB.login(function() {
52                        facebookLogin();
53                    }, {scope: 'email'});
54
55                    return false;
56                });                
57            }
58        }
59        $('[data-salon-toggle="next"]').click(function (e) {
60            var form = $(this).closest('form');
61            $('#sln-salon input.sln-invalid,#sln-salon textarea.sln-invalid,#sln-salon select.sln-invalid').removeClass('sln-invalid');
62            if (form[0].checkValidity()) {
63                sln_loadStep($, form.serialize() + '&' + $(this).data('salon-data'));
64            }else{
65                $('#sln-salon input:invalid,#sln-salon textarea:invalid,#sln-salon select:invalid').addClass('sln-invalid').attr('placeholder', salon.checkout_field_placeholder);
66            }
67            return false;
68        });
69    }
70    $('[data-salon-toggle="direct"]').click(function (e) {
71        e.preventDefault();
72        sln_loadStep($, $(this).data('salon-data'));
73        return false;
74    });
75
76    // CHECKBOXES
77    $('#sln-salon input:checkbox').each(function () {
78        $(this).change(function () {
79            if($(this).is(':checked')) {
80                $(this).parent().addClass("is-checked");
81            }
82            else {
83                $(this).parent().removeClass("is-checked");
84            }
85
86        })
87    });
88    // RADIOBOXES
89    $('#sln-salon input:radio').each(function () {
90        $(this).click(function () {
91            //var selector = '.is-checked input[name="' + jQuery(this).attr('name').replace(/([\[\]])/g, '\\\\$1') + '"]';
92            var name = jQuery(this).attr('name');
93            jQuery('.is-checked').each(function() {
94                if(jQuery(this).find('input').attr('name') == name) {
95                    $(this).removeClass('is-checked');
96                }
97            });
98            $(this).parent().toggleClass("is-checked");
99        });
100    });
101
102    $('.sln-edit-text').change(function() {
103        var data = "key=" + $(this).attr('id') + "&value=" + $(this).val() + "&action=salon&method=SetCustomText&security=" + salon.ajax_nonce;
104        $.ajax({
105            url: salon.ajax_url,
106            data: data,
107            method: 'POST',
108            dataType: 'json',
109            success: function (data) {
110            },
111            error: function(data){alert('error'); console.log(data);}
112        });
113        return false;
114    });
115
116    $('div.editable').on('click', function() {
117        var self = $(this);
118        self.addClass('focus');
119        var text  = self.find('.text');
120        var input = self.find('input');
121        input.val(text.text().trim()).trigger('focus');
122    });
123
124    $('div.editable .input input').on('blur', function() {
125        var self = $(this);
126        var div  = self.closest('.editable');
127        div.removeClass('focus');
128        var text = div.find('.text');
129        text.html(self.val());
130    });
131
132    $('#sln_no_user_account').on('change', function() {
133        if ($(this).is(':checked')) {
134            $('#sln_password').attr('disabled', 'disabled').parent().css('display', 'none');
135            $('#sln_password_confirm').attr('disabled', 'disabled').parent().css('display', 'none');
136        }
137        else {
138            $('#sln_password').attr('disabled', false).parent().css('display', 'block');
139            $('#sln_password_confirm').attr('disabled', false).parent().css('display', 'block');
140        }
141    }).change();
142    if (typeof sln_createSelect2Full !== 'undefined') {
143        sln_createSelect2Full($);
144    }
145    salonBookingCalendarInit();
146}
147function sln_loadStep($, data) {
148    var loadingMessage = '<div class="sln-loader-wrapper"><div class="sln-loader">Loading...</div></div>';
149    data += "&action=salon&method=salonStep&security=" + salon.ajax_nonce;
150    $('#sln-notifications').html(loadingMessage).addClass('sln-notifications--active');
151    $.ajax({
152        url: salon.ajax_url,
153        data: data,
154        method: 'POST',
155        dataType: 'json',
156        success: function (data) {
157            if (typeof data.redirect != 'undefined') {
158                window.location.href = data.redirect;
159            } else {
160                $('#sln-salon').replaceWith(data.content);
161                salon.ajax_nonce = data.nonce;
162                $('html, body').animate({
163                    scrollTop: $("#sln-salon").offset().top
164                }, 700);
165                sln_init($);
166            }
167        },
168        error: function(data){alert('error'); console.log(data);}
169    });
170}
171
172function sln_stepDate($) {
173    var isValid;
174    var items = $('#salon-step-date').data('intervals');
175    var doingFunc = false;
176    var func = function () {
177        if (doingFunc) return;
178        setTimeout(function () {
179            doingFunc = true;
180            $('[data-ymd]').addClass('disabled');
181            $.each(items.dates, function (key, value) {
182                $('.day[data-ymd="' + value + '"]').removeClass('disabled');
183            });
184            $('.day[data-ymd]').removeClass('full');
185            $.each(items.fullDays, function (key, value) {
186                console.log(value);
187                $('.day[data-ymd="' + value + '"]').addClass('disabled full');
188            });
189
190            $.each(items.times, function (key, value) {
191                $('.hour[data-ymd="' + value + '"]').removeClass('disabled');
192                $('.minute[data-ymd="' + value + '"]').removeClass('disabled');
193                $('.hour[data-ymd="' + value.split(':')[0] + ':00"]').removeClass('disabled');
194            });
195            doingFunc = false;
196        }, 200);
197        return true;
198    }
199    func();
200    $('body').on('sln_date', func);
201
202    function validate(obj, autosubmit) {
203        var form = $(obj).closest('form');
204        //var validatingMessage = '<img src="' + salon.loading + '" alt="loading .." width="16" height="16" /> '+salon.txt_validating;
205        var validatingMessage = '<div class="sln-alert sln-alert--wait">'+salon.txt_validating+'</div>';
206        var data = form.serialize();
207        data += "&action=salon&method=checkDate&security=" + salon.ajax_nonce;
208        $('#sln-notifications').addClass('sln-notifications--active').html(validatingMessage);
209        $.ajax({
210            url: salon.ajax_url,
211            data: data,
212            method: 'POST',
213            dataType: 'json',
214            success: function (data) {
215                $('.sln-alert').remove();
216                if (!data.success) {
217                    var alertBox = $('<div class="sln-alert sln-alert--problem"></div>');
218                    $(data.errors).each(function () {
219                        alertBox.append('<p>').html(this);
220                    });
221                    $('#sln-notifications').html('').append(alertBox);
222// we bind a new interval so we needn't to disable
223//                    $('#sln-step-submit').attr('disabled', true);
224                    isValid = false;
225                } else {
226                    $('#sln-step-submit').attr('disabled', false);
227                    $('#sln-notifications').html('').removeClass('sln-notifications--active');
228                    isValid = true;
229                    if (autosubmit)
230                        submit();
231                }
232                bindIntervals(data.intervals);
233            }
234        });
235    }
236
237    function bindIntervals(intervals) {
238//        putOptions($('#sln_date_day'), intervals.days, intervals.suggestedDay);
239//        putOptions($('#sln_date_month'), intervals.months, intervals.suggestedMonth);
240//        putOptions($('#sln_date_year'), intervals.years, intervals.suggestedYear);
241        items = intervals;
242        func();
243        putOptions($('#sln_date'), intervals.suggestedDate);
244        putOptions($('#sln_time'), intervals.suggestedTime);
245    }
246
247    function putOptions(selectElem, value) {
248        selectElem.val(value);
249    }
250
251    function submit() {
252        if ($('#sln-step-submit').data('salon-toggle').length)
253            sln_loadStep($, $('#salon-step-date').serialize() + '&' + $('#sln-step-submit').data('salon-data'));
254        else
255            $('#sln-step-submit').click();
256    }
257
258    $('#sln_date, #sln_time').change(function () {
259        validate(this, false);
260    });
261    $('#salon-step-date').submit(function () {
262        if (!isValid) {
263            validate(this, true);
264        } else {
265            submit();
266        }
267        return false;
268    });
269
270    initDatepickers($);
271    initTimepickers($);
272}
273
274function sln_serviceTotal($) {
275    var $checkboxes = $('.sln-service-list input[type="checkbox"]');
276    var $totalbox = $('#services-total');
277    function evalTot() {
278        var tot = 0;
279        $checkboxes.each(function () {
280            if ($(this).is(':checked')) {
281                tot += $(this).data('price');
282            }
283        });
284        var decimals = (parseFloat(tot) === parseFloat(parseInt(tot)) ? 0 : 2);
285        $totalbox.text($totalbox.data('symbol-left') + tot.formatMoney(decimals, $totalbox.data('symbol-decimal'), $totalbox.data('symbol-thousand')) + $totalbox.data('symbol-right'));
286    }
287
288    function checkServices($) {
289        var form, data;
290        if ($('#salon-step-services').size()) {
291            form = $('#salon-step-services');
292            data = form.serialize() + "&action=salon&method=CheckServices&part=primaryServices&security=" + salon.ajax_nonce;
293        }
294        else if ($('#salon-step-secondary').size()) {
295            form = $('#salon-step-secondary');
296            data = form.serialize() + "&action=salon&method=CheckServices&part=secondaryServices&security=" + salon.ajax_nonce;
297        }
298        else {
299            return;
300        }
301
302        $.ajax({
303            url: salon.ajax_url,
304            data: data,
305            method: 'POST',
306            dataType: 'json',
307            success: function (data) {
308                if (!data.success) {
309                    var alertBox = $('<div class="sln-alert sln-alert--problem"></div>');
310                    $.each(data.errors, function () {
311                        alertBox.append('<p>').html(this);
312                    });
313                }
314                else {
315                    $('.sln-alert').remove();
316                    if(data.services)
317                    $.each(data.services, function(index, value) {
318                        var checkbox = $('#sln_services_' + index);
319                        var errorsArea = $('#sln_services_' + index).closest('.sln-service').find('.errors-area');
320                        if (value.status == -1) {
321                            var alertBox = $('<div class="sln-alert sln-alert-medium sln-alert--problem"><p>' + value.error + '</p></div>');
322                            checkbox.attr('checked', false).attr('disabled', 'disabled').change();
323                            errorsArea.html(alertBox);
324                        }
325                        else if (value.status == 0) {
326                            checkbox.attr('checked', false).attr('disabled', false).change();
327                        }
328                        else if (value.status == 1) {
329                            checkbox.attr('checked', true).change();
330                        }
331                    });
332                    evalTot();
333                }
334            }
335        });
336    }
337
338    $checkboxes.click(function () {
339        checkServices($);
340    });
341    checkServices($);
342    evalTot();
343}
344
345function initDatepickers($) {
346    $('.sln_datepicker input').each(function () {
347        $(this).attr('readonly','readonly');
348        if ($(this).hasClass('started')) {
349            return;
350        } else {
351            $(this)
352                .addClass('started')
353                .datetimepicker({
354                    format: $(this).data('format'),
355                    weekStart: $(this).data('weekstart'),
356                    minuteStep: 60,
357                    autoclose: true,
358                    minView: 2,
359                    maxView: 4,
360                    todayBtn: true,
361                    language: $(this).data('locale')
362                })
363                .on('show', function () {
364                    $('body').trigger('sln_date');
365                })
366                .on('place', function () {
367                    $('body').trigger('sln_date');
368                })
369                .on('changeMonth', function () {
370                    $('body').trigger('sln_date');
371                })
372                .on('changeYear', function () {
373                    $('body').trigger('sln_date');
374                })
375                .on('hide', function () {
376                    if($(this).is(':focus'));
377                        $(this).blur();
378               })
379            ;
380        }
381    });
382    var elementExists = document.getElementById('sln-salon');
383    if( elementExists){
384        setTimeout(function(){
385        $('.datetimepicker.sln-datetimepicker').wrap( "<div class='sln-salon-bs-wrap'></div>" );
386        }, 50);
387    }
388}
389
390function initTimepickers($) {
391    $('.sln_timepicker input').each(function () {
392      $(this).attr('readonly','readonly');
393        if ($(this).hasClass('started')) {
394            return;
395        } else {
396            var picker = $(this)
397                .addClass('started')
398                .datetimepicker({
399                    format: $(this).data('format'),
400                    minuteStep: $(this).data('interval'),
401                    autoclose: true,
402                    minView: $(this).data('interval') == 60 ? 1: 0,
403                    maxView: 1,
404                    startView: 1,
405                    showMeridian: $(this).data('meridian') ? true : false,
406                })
407                .on('show', function () {
408                    $('body').trigger('sln_date');
409                })
410                .on('place', function () {
411                    $('body').trigger('sln_date');
412                })
413                .on('hide', function () {
414                    if($(this).is(':focus'));
415                        $(this).blur();
416                })
417
418               .data('datetimepicker').picker;
419            picker.addClass('timepicker');
420        }
421    });
422}
423/* ========================================================================
424 * Bootstrap: transition.js v3.2.0
425 * http://getbootstrap.com/javascript/#transitions
426 * ========================================================================
427 * Copyright 2011-2014 Twitter, Inc.
428 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
429 * ======================================================================== */
430
431
432+function ($) {
433  'use strict';
434
435  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
436  // ============================================================
437
438  function transitionEnd() {
439    var el = document.createElement('bootstrap')
440
441    var transEndEventNames = {
442      WebkitTransition : 'webkitTransitionEnd',
443      MozTransition    : 'transitionend',
444      OTransition      : 'oTransitionEnd otransitionend',
445      transition       : 'transitionend'
446    }
447
448    for (var name in transEndEventNames) {
449      if (el.style[name] !== undefined) {
450        return { end: transEndEventNames[name] }
451      }
452    }
453
454    return false // explicit for ie8 (  ._.)
455  }
456
457  // http://blog.alexmaccaw.com/css-transitions
458  $.fn.emulateTransitionEnd = function (duration) {
459    var called = false
460    var $el = this
461    $(this).one('bsTransitionEnd', function () { called = true })
462    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
463    setTimeout(callback, duration)
464    return this
465  }
466
467  $(function () {
468    $.support.transition = transitionEnd()
469
470    if (!$.support.transition) return
471
472    $.event.special.bsTransitionEnd = {
473      bindType: $.support.transition.end,
474      delegateType: $.support.transition.end,
475      handle: function (e) {
476        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
477      }
478    }
479  })
480
481}(jQuery);
482
483/* ========================================================================
484 * Bootstrap: collapse.js v3.2.0
485 * http://getbootstrap.com/javascript/#collapse
486 * ========================================================================
487 * Copyright 2011-2014 Twitter, Inc.
488 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
489 * ======================================================================== */
490
491
492+function ($) {
493  'use strict';
494
495  // COLLAPSE PUBLIC CLASS DEFINITION
496  // ================================
497
498  var Collapse = function (element, options) {
499    this.$element      = $(element)
500    this.options       = $.extend({}, Collapse.DEFAULTS, options)
501    this.transitioning = null
502
503    if (this.options.parent) this.$parent = $(this.options.parent)
504    if (this.options.toggle) this.toggle()
505  }
506
507  Collapse.VERSION  = '3.2.0'
508
509  Collapse.DEFAULTS = {
510    toggle: true
511  }
512
513  Collapse.prototype.dimension = function () {
514    var hasWidth = this.$element.hasClass('width')
515    return hasWidth ? 'width' : 'height'
516  }
517
518  Collapse.prototype.show = function () {
519    if (this.transitioning || this.$element.hasClass('in')) return
520
521    var startEvent = $.Event('show.bs.collapse')
522    this.$element.trigger(startEvent)
523    if (startEvent.isDefaultPrevented()) return
524
525    var actives = this.$parent && this.$parent.find('> .panel > .in')
526
527    if (actives && actives.length) {
528      var hasData = actives.data('bs.collapse')
529      if (hasData && hasData.transitioning) return
530      Plugin.call(actives, 'hide')
531      hasData || actives.data('bs.collapse', null)
532    }
533
534    var dimension = this.dimension()
535
536    this.$element
537      .removeClass('collapse')
538      .addClass('collapsing')[dimension](0)
539
540    this.transitioning = 1
541
542    var complete = function () {
543      this.$element
544        .removeClass('collapsing')
545        .addClass('collapse in')[dimension]('')
546      this.transitioning = 0
547      this.$element
548        .trigger('shown.bs.collapse')
549    }
550
551    if (!$.support.transition) return complete.call(this)
552
553    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
554
555    this.$element
556      .one('bsTransitionEnd', $.proxy(complete, this))
557      .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
558  }
559
560  Collapse.prototype.hide = function () {
561    if (this.transitioning || !this.$element.hasClass('in')) return
562
563    var startEvent = $.Event('hide.bs.collapse')
564    this.$element.trigger(startEvent)
565    if (startEvent.isDefaultPrevented()) return
566
567    var dimension = this.dimension()
568
569    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
570
571    this.$element
572      .addClass('collapsing')
573      .removeClass('collapse')
574      .removeClass('in')
575
576    this.transitioning = 1
577
578    var complete = function () {
579      this.transitioning = 0
580      this.$element
581        .trigger('hidden.bs.collapse')
582        .removeClass('collapsing')
583        .addClass('collapse')
584    }
585
586    if (!$.support.transition) return complete.call(this)
587
588    this.$element
589      [dimension](0)
590      .one('bsTransitionEnd', $.proxy(complete, this))
591      .emulateTransitionEnd(350)
592  }
593
594  Collapse.prototype.toggle = function () {
595    this[this.$element.hasClass('in') ? 'hide' : 'show']()
596  }
597
598
599  // COLLAPSE PLUGIN DEFINITION
600  // ==========================
601
602  function Plugin(option) {
603    return this.each(function () {
604      var $this   = $(this)
605      var data    = $this.data('bs.collapse')
606      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
607
608      if (!data && options.toggle && option == 'show') option = !option
609      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
610      if (typeof option == 'string') data[option]()
611    })
612  }
613
614  var old = $.fn.collapse
615
616  $.fn.collapse             = Plugin
617  $.fn.collapse.Constructor = Collapse
618
619
620  // COLLAPSE NO CONFLICT
621  // ====================
622
623  $.fn.collapse.noConflict = function () {
624    $.fn.collapse = old
625    return this
626  }
627
628
629  // COLLAPSE DATA-API
630  // =================
631
632  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
633    var href
634    var $this   = $(this)
635    var target  = $this.attr('data-target')
636        || e.preventDefault()
637        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
638    var $target = $(target)
639    var data    = $target.data('bs.collapse')
640    var option  = data ? 'toggle' : $this.data()
641    var parent  = $this.attr('data-parent')
642    var $parent = parent && $(parent)
643
644    if (!data || !data.transitioning) {
645      if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
646      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
647    }
648
649    Plugin.call($target, option)
650  });
651
652function reattachEvents(){
653    $('.sln-datetimepicker-close').unbind('click').click(function(){
654      $('.datetimepicker.sln-datetimepicker').hide();
655    });
656}
657setTimeout(function(){
658  $('.datetimepicker.sln-datetimepicker div').append('<em class="sln-datetimepicker-close">'+salon.txt_close+'</em>');
659  reattachEvents();
660}, 500);
661}(jQuery);
662
663function facebookInit() {
664    window.fbAsyncInit = function() {
665            FB.init({
666                appId      : salon.fb_app_id,
667                cookie     : true,
668                xfbml      : true,
669                version    : 'v2.8'
670            });
671            FB.AppEvents.logPageView();
672
673            jQuery('[data-salon-click=fb_login]').unbind('click').click(function() {
674                FB.login(function() {
675                    facebookLogin();
676                }, {scope: 'email'});
677
678                return false;
679            });
680    };            
681    
682    (function(d, s, id){
683            var js, fjs = d.getElementsByTagName(s)[0];
684            if (d.getElementById(id)) {return;}
685            js = d.createElement(s); js.id = id;
686            js.src = "//connect.facebook.net/en_US/sdk.js";
687            fjs.parentNode.insertBefore(js, fjs);
688    }(document, 'script', 'facebook-jssdk'));    
689}
690
691function facebookLogin() {
692    var auth = FB.getAuthResponse();
693    if (auth) {
694        FB.api('/me?fields=id,email,name', function(response)
695        {
696            var email = response.email !== undefined ? response.email : '';
697            var id = response.id !== undefined ? response.id : '';
698            var name = response.name !== undefined ? response.name : '';
699            var tmp = name.split(' ');
700            var lastname = tmp.pop();
701            var firstname = tmp.join(' ');
702
703            var $form = jQuery('#salon-step-details');
704            if($form.length){
705                $form.append('<input type="hidden" name="fb_id" value="' + id + '" />');
706                $form.append('<input type="hidden" name="fb_email" value="' + email + '" />');
707                $form.append('<input type="hidden" name="fb_firstname" value="' + firstname + '" />');
708                $form.append('<input type="hidden" name="fb_lastname" value="' + lastname + '" />');
709                $form.find('[name=submit_details]').click();
710            }else{
711                var data = "fbEmail=" + email + "&fbID=" + id + "&fbFirstName=" + firstname + "&fbLastName=" + lastname + "&action=salon&method=FacebookLogin&security=" + salon.ajax_nonce;
712                jQuery.ajax({
713                    url: salon.ajax_url,
714                    data: data,
715                    method: 'POST',
716                    dataType: 'json',
717                    success: facebookRefreshPageCallback,
718                    error: function(data){alert('error'); console.log(data);}
719                });
720                function facebookRefreshPageCallback(response) {
721                    if (response.success) {
722                        location.reload();
723                    }
724                    else {
725                        alert('error');
726                        console.log(response);
727                    }
728                }
729
730                
731            }
732        });
733    }
734}
735
736function salonBookingCalendarInit() {
737    if (jQuery('.sln-salon-booking-calendar-wrap').size() === 0) {
738        return;
739    }
740    salonBookingCalendarInitTooltip();
741
742    setInterval(function() {
743        var data = '';
744        data    += "&action=salon&method=salonCalendar&security=" + salon.ajax_nonce;
745        if(jQuery('.sln-salon-booking-calendar').attr('data-attendantsIds'))data    += "&attendantsIds="+jQuery('.sln-salon-booking-calendar').attr('data-attendantsIds');
746        jQuery.ajax({
747            url: salon.ajax_url,
748            data: data,
749            method: 'POST',
750            dataType: 'json',
751            success: function (data) {
752                if (data.success) {
753                    jQuery('.sln-salon-booking-calendar-wrap').html(data.content);
754                    salonBookingCalendarInitTooltip();
755                }
756                else if (data.redirect) {
757                    window.location.href = data.redirect;
758                }
759                else if (data.errors) {
760                    // TODO: display errors
761                }
762            },
763            error: function(data){alert('error'); console.log(data);}
764        });
765    }, 10*1000);
766}
767
768function salonBookingCalendarInitTooltip() {
769    jQuery('[data-toggle="tooltip"]').tooltip();
770}

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.