PageSourceSearch

https://serpstat.com/js/common.js?3493883178

js serpstat.com collected 2026-10-01 08:42:07 UTC 58,081 bytes, 1,964 lines download raw bytes

1function callDialog(data) {
2  var $custom_dialog = $('#custom_dialog');
3  $custom_dialog.find('.dialog_heading').html(data.header);
4  $custom_dialog.find('.dialog_body').html(data.body);
5  $custom_dialog.myDialog();
6}
7
8function callDialogAlert(data) {
9  var $custom_dialog = $('#custom_dialog_alert');
10  $custom_dialog.addClass('smaller');
11  $custom_dialog.find('.dialog_blank_body').html(data.body);
12  $custom_dialog.myDialog();
13  return $custom_dialog;
14}
15
16$(document).ready(function() {
17  var chatToken = $('#chat_token').attr('data-value');
18  var sessionId = $('#session_id').attr('data-value');
19  var chatTokenAudit = $('#chat_token_audit').attr('data-value');
20  window.competitors = [];
21
22  if (chatToken) {
23    webSocketDataTrigger(chatToken, sessionId);
24    SerpstatMain.setUserReportsCountVisibility();
25  }
26
27  if (chatTokenAudit) {
28    webSocketDataTrigger(chatTokenAudit, sessionId);
29    SerpstatMain.setUserReportsCountVisibility();
30  }
31
32  function webSocketDataTrigger(chatToken, sessionId) {
33    SerpstatMain.webSocketData(
34      {
35        host: 'progress.serpstat.com',
36        port: 443,
37        channel: chatToken,
38        useSSL: true
39      },
40      function(ui) {
41        var timestamp = ui.id;
42        var lastTimestamp = localStorage.getItem('timestampReport');
43        var lastSessionDestroyedTimestamp = localStorage.getItem(
44          'timestampSessionDestroyed'
45        );
46        var lastBacklinksCompetitorsUpdated = localStorage.getItem(
47          'timestampBacklinksCompetitorsUpdated'
48        );
49        var lastBacklinksCompetitorsDomainUpdated = localStorage.getItem(
50          'timestampBacklinksCompetitorsDomainUpdated'
51        );
52        var isPageLoad = localStorage.getItem('isPageLoad');
53        var idBacklinksCompetitorsDomain = localStorage.getItem(
54          'idBacklinksCompetitorsDomain'
55        );
56
57        if (ui.data.method == 'report_finished' && timestamp > lastTimestamp) {
58          var exportId = '';
59          try {
60            var link = $.parseHTML(ui.data.message)[1];
61            exportId = link.dataset.reportId;
62          }
63          catch (e) {
64            console.log('error in parsing web socket message', e);
65          }
66
67          if (!sessionStorage.getItem(exportId)) {
68            doAlert('success', ui.data.message);
69            sessionStorage.setItem(exportId, 'showed');
70          }
71          SerpstatMain.setUserReportsCount(1);
72          localStorage.setItem('timestampReport', timestamp);
73        }
74
75        if (ui.data.method == 'report_failed' && timestamp > lastTimestamp) {
76          SerpstatMain.setUserReportsCount(0);
77          doAlert('error', ui.data.message);
78          localStorage.setItem('timestampReport', timestamp);
79        }
80
81        if (
82          ui.data.method === 'backlinks_competitors_domain_updated' &&
83          (timestamp > lastBacklinksCompetitorsDomainUpdated ||
84            (timestamp === Number(lastBacklinksCompetitorsDomainUpdated) &&
85              idBacklinksCompetitorsDomain !== ui.data.message.data.id))
86        ) {
87          localStorage.setItem(
88            'idBacklinksCompetitorsDomain',
89            ui.data.message.data.id
90          );
91          if (isPageLoad === 'true') {
92            window.competitors.push(ui.data.message.data);
93          } else {
94            updateCompetitorRowData(ui.data.message.data);
95            localStorage.setItem(
96              'timestampBacklinksCompetitorsDomainUpdated',
97              timestamp
98            );
99          }
100        }
101
102        if (
103          ui.data.method === 'backlinks_competitors_updated' &&
104          timestamp > lastBacklinksCompetitorsUpdated
105        ) {
106          doAlert('backlinks_competitors_updated', ui.data.message, 60000);
107          localStorage.setItem(
108            'timestampBacklinksCompetitorsUpdated',
109            timestamp
110          );
111        }
112
113        if (
114          ui.data.method === 'user_session_destroyed' &&
115          timestamp > lastSessionDestroyedTimestamp
116        ) {
117          var $dialog = $('#dialog_session_destroyed');
118
119          if (sessionId != null && sessionId !== ui.data.user) {
120            $dialog.myDialog();
121            localStorage.setItem('timestampSessionDestroyed', timestamp);
122          } else {
123            $dialog.myDialog('close');
124          }
125        }
126
127        if (ui.data.method === 'audit_site') {
128          auditUpdateProgress(ui.data);
129        }
130      }
131    );
132  }
133
134  function auditUpdateProgress(data) {
135    var report_id = parseInt($('#audit_report_id').attr('data-value'));
136
137    if (parseInt(data.report_id) === report_id) {
138      if (parseInt(data.progress) === 100) {
139        location.reload();
140      }
141
142      var count = parseInt(data.count);
143      var limit = parseInt(data.limit);
144
145      var urls_enqueued_count = parseInt(data.urls_enqueued_count);
146      var urls_dequeued_count = parseInt(data.urls_dequeued_count);
147
148      audit_start_animation_startter = false;
149
150      if (urls_dequeued_count > 0) {
151        var progress = 5 + Math.floor((95 * count) / limit);
152
153        var template = $('#audit_progress_text_template').attr('data-value');
154
155        var text = template
156          .replace('%count_scanned%', count)
157          .replace('%limit_scanned%', limit)
158          .replace('%urls_dequeued_count%', urls_dequeued_count)
159          .replace('%urls_enqueued_count%', urls_enqueued_count);
160
161        $('#audit_report_progress_bar').attr('data-text', text);
162        $('#audit_report_loader_progress_content').text(text);
163        $('#audit_report_progress_bar').css('width', progress + '%');
164
165        audit_start_animation();
166      }
167    }
168  }
169
170  function audit_start_animation() {
171    if (audit_start_animation_startter) {
172      return;
173    }
174    var tm = TweenMax,
175      $text = $('.animate_text'),
176      tl = new TimelineMax({ repeat: -1 }),
177      length = $text.length;
178    tm.to($('.animate_spin'), 2, {
179      rotation: 360,
180      repeat: -1,
181      transformOrigin: '50% 50%',
182      ease: Linear.easeNone
183    });
184    for (var i = 0; i < length; i += 1) {
185      tl.fromTo(
186        $text[i],
187        0.2,
188        { y: -20, autoAlpha: 0 },
189        { y: 0, autoAlpha: 1 }
190      );
191      tl.to($text[i], 0.2, { y: 20, autoAlpha: 0, delay: 2 });
192    }
193    audit_start_animation_startter = true;
194  }
195
196  String.prototype.replaceAll = function(search, replace) {
197    return this.split(search).join(replace);
198  };
199  $.expr[':'].contains = jQuery.expr.createPseudo(function(arg) {
200    return function(elem) {
201      return (
202        jQuery(elem)
203          .text()
204          .toUpperCase()
205          .indexOf(arg.toUpperCase()) >= 0
206      );
207    };
208  });
209  // Button back in browser
210  window.addEventListener(
211    'popstate',
212    function(e) {
213      if (!window.location.hash) {
214        SerpstatMain.getPage(window.location.href, '#content', false);
215      }
216    },
217    false
218  );
219  $.ajaxSetup({
220    type: 'GET',
221    dataType: 'html',
222    beforeSend: function(req) {},
223    error: debounce(function(err) {
224      // If request aborted,
225      if (err.status === 0 && err.statusText === "abort") {
226        return;
227      }
228
229      if (err.status === 423 || err.status === 404) {
230        var response = JSON.parse(err.responseText);
231        message = response.result;
232      } else {
233        var message = 'Failed to get page!';
234      }
235      doAlert('error', message);
236    }, 200),
237    complete: function(req) {}
238  });
239  SerpstatMain.init();
240  document.getElementById('content').addEventListener(
241    'after_ajax_load',
242    function(e) {
243      // подключаем websocket аудита всего сайта
244      var chatTokenAudit = $('#chat_token_audit').attr('data-value');
245      var sessionId = $('#session_id').attr('data-value');
246      if (chatTokenAudit) {
247        webSocketDataTrigger(chatTokenAudit, sessionId);
248        SerpstatMain.setUserReportsCountVisibility();
249      }
250
251      SerpstatMain.fieldsOrderTrigger();
252    },
253    false
254  );
255  document.getElementById('content').addEventListener(
256    'after_ajax_load_block',
257    function(e) {
258      SerpstatMain.fieldsOrderTrigger();
259    },
260    false
261  );
262  document.getElementById('content').addEventListener(
263    'after_change_url',
264    function(e) {
265      SerpstatMain.setResponsivePageClass();
266      $('input[name=continue_url]').val(window.location.href);
267    },
268    false
269  );
270
271  (function() {
272    var requestAnimationFrame =
273      window.requestAnimationFrame ||
274      window.mozRequestAnimationFrame ||
275      window.webkitRequestAnimationFrame ||
276      window.msRequestAnimationFrame ||
277      function(callback) {
278        window.setTimeout(callback, 1000 / 60);
279      };
280    window.requestAnimationFrame = requestAnimationFrame;
281  })();
282  canvas = document.getElementById('snow_canvas');
283  if (canvas !== null) {
284    console.log('true');
285    var flakes = [],
286      ctx = canvas.getContext('2d'),
287      flakeCount = 10,
288      mX = -100,
289      mY = -100;
290    canvas.width = window.innerWidth;
291    canvas.height = 300;
292    canvas.addEventListener('mousemove', function(e) {
293      (mX = e.clientX), (mY = e.clientY);
294    });
295    window.addEventListener('resize', function() {
296      canvas.width = window.innerWidth;
297      canvas.height = 300;
298    });
299
300    initNewYear();
301  }
302
303  function snow() {
304    ctx.clearRect(0, 0, canvas.width, canvas.height);
305    for (var i = 0; i < flakeCount; i++) {
306      var flake = flakes[i],
307        x = mX,
308        y = mY,
309        minDist = 150,
310        x2 = flake.x,
311        y2 = flake.y;
312      var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
313        dx = x2 - x,
314        dy = y2 - y;
315      if (dist < minDist) {
316        var force = minDist / (dist * dist),
317          xcomp = (x - x2) / dist,
318          ycomp = (y - y2) / dist,
319          deltaV = force / 2;
320        flake.velX -= deltaV * xcomp;
321        flake.velY -= deltaV * ycomp;
322      } else {
323        flake.velX *= 0.98;
324        if (flake.velY <= flake.speed) {
325          flake.velY = flake.speed;
326        }
327        flake.velX += Math.cos((flake.step += 0.05)) * flake.stepSize;
328      }
329      ctx.fillStyle = 'rgba(255,255,255,' + flake.opacity + ')';
330      flake.y += flake.velY;
331      flake.x += flake.velX;
332      if (flake.y >= canvas.height || flake.y <= 0) {
333        reset(flake);
334      }
335      if (flake.x >= canvas.width || flake.x <= 0) {
336        reset(flake);
337      }
338      ctx.beginPath();
339      ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
340      ctx.fill();
341    }
342    requestAnimationFrame(snow);
343  }
344
345  function reset(flake) {
346    flake.x = Math.floor(Math.random() * canvas.width);
347    flake.y = 0;
348    flake.size = Math.random() * 3 + 2;
349    flake.speed = Math.random() * 1 + 0.8;
350    flake.velY = flake.speed;
351    flake.velX = 0;
352    flake.opacity = Math.random() * 0.5 + 0.3;
353  }
354
355  function initNewYear() {
356    for (var i = 0; i < flakeCount; i++) {
357      var x = Math.floor(Math.random() * canvas.width),
358        y = Math.floor(Math.random() * canvas.height),
359        size = Math.random() * 3 + 2,
360        speed = Math.random() * 1 + 0.5,
361        opacity = Math.random() * 0.5 + 0.3;
362      flakes.push({
363        speed: speed,
364        velY: speed,
365        velX: 0,
366        x: x,
367        y: y,
368        size: size,
369        stepSize: Math.random() / 30,
370        step: 0,
371        opacity: opacity
372      });
373    }
374    snow();
375  }
376
377  $('#gdpr_submit_checkbox').change(function() {
378    if (this.checked) {
379      $(this)
380        .parent()
381        .find(':input:not([type="checkbox"])')
382        .prop('disabled', false);
383    } else {
384      $(this)
385        .parent()
386        .find(':input:not([type="checkbox"])')
387        .prop('disabled', true);
388    }
389  });
390  $('#dialob_agree_policy').change(function() {
391    if (this.checked) {
392      $(this)
393        .parent()
394        .parent()
395        .find('button')
396        .prop('disabled', false);
397    } else {
398      $(this)
399        .parent()
400        .parent()
401        .find('button')
402        .prop('disabled', true);
403    }
404  });
405});
406
407function updateCompetitorRowData(data) {
408  var $this = $('tr[data-id="' + data.id + '"]'),
409    arrayData = [
410      {
411        cell: $this.find('.competitors_backlinks_refdomain'),
412        data: data.referringDomains
413      },
414      {
415        cell: $this.find('.competitors_backlinks_backlink'),
416        data: data.referringLinks
417      },
418      {
419        cell: $this.find('.competitors_backlinks_total_indexed'),
420        data: data.totalIndexed
421      },
422      {
423        cell: $this.find('.competitors_backlinks_ip'),
424        data: data.referringIps
425      },
426      {
427        cell: $this.find('.competitors_backlinks_subnet'),
428        data: data.referringSubnets
429      },
430      {
431        cell: $this.find('.competitors_backlinks_facebook_links'),
432        data: data.facebookLinks
433      },
434      {
435        cell: $this.find('.competitors_backlinks_pinterest_links'),
436        data: data.pinterestLinks
437      },
438      {
439        cell: $this.find('.competitors_backlinks_linkedin_links'),
440        data: data.linkedInLinks
441      },
442      {
443        cell: $this.find('.competitors_backlinks_vk_links'),
444        data: data.vkLinks
445      },
446      {
447        cell: $this.find('.competitors_backlinks_nofollow_links'),
448        data: data.noFollowLinks
449      },
450      {
451        cell: $this.find('.competitors_backlinks_citation_flow'),
452        data: data.citationRank
453      },
454      {
455        cell: $this.find('.competitors_backlinks_trust_flow'),
456        data: data.trustRank
457      }
458    ];
459
460  if ($this.length !== 0) {
461    arrayData.forEach(function(item) {
462      updateCompetitorsData(item.cell, item.data);
463    });
464  }
465}
466
467function updateCompetitorsData(cell, data) {
468  if (data == -1) {
469    cell.find('.content').html('n/a');
470    cell.find('.progress').attr('data-text', 'n/a');
471    cell.find('.content').attr('data-value', data);
472  } else {
473    cell.find('.content').html(data.toLocaleString('ru'));
474    cell.find('.progress').attr('data-text', data.toLocaleString('ru'));
475    cell.find('.content').attr('data-value', data);
476
477    var className = cell.attr('class').split(/\s+/)[0],
478      classes = $('.' + className),
479      maxValue = 0;
480
481    $.each(classes, function(item, element) {
482      var value = Number(
483        $(element)
484          .find('.content')
485          .attr('data-value')
486      );
487      if (maxValue < value) {
488        maxValue = value;
489      }
490    });
491    $.each(classes, function(item, element) {
492      var percent =
493        (Number(
494          $(element)
495            .find('.content')
496            .attr('data-value')
497        ) /
498          maxValue) *
499        100;
500      $(element)
501        .find('.progress')
502        .removeClass('bg_green');
503      if (
504        Number(
505          $(element)
506            .find('.content')
507            .attr('data-value')
508        ) === maxValue
509      ) {
510        $(element)
511          .find('.progress')
512          .addClass('bg_green');
513      }
514      $(element)
515        .find('.progress')
516        .css('width', Math.floor(percent) + '%');
517    });
518  }
519}
520
521function getPhoneValidateInput(context) {
522  var form = $(context).closest('form');
523  var phone_validate_input = form.find('input[name="phone_validate"]');
524  if (!phone_validate_input.length) {
525    form.append('<input type="hidden" name="phone_validate">');
526    phone_validate_input = form.find('input[name="phone_validate"]');
527  }
528  return phone_validate_input;
529}
530
531var countryToMask = {
532  UA: {
533    code: 380,
534    countNum: 11
535  },
536  RU: {
537    code: 7,
538    countNum: 11
539  }
540};
541
542var SerpstatMain = {
543  ajaxReload: function() {
544    SerpstatMain.getPage(window.location.href);
545  },
546  afterAjaxLoadEvent: new Event('after_ajax_load'),
547  afterAjaxLoadBlockEvent: new Event('after_ajax_load_block'),
548  afterAjaxFormSubmitEvent: new Event('after_ajax_form_submit'),
549  afterChangeUrlEvent: new Event('after_change_url'),
550  title: '',
551  isResponsivePage: false,
552  currentAjaxRequests: 0,
553  currentAjaxRequestNumber: 1,
554  ajaxRequests: {},
555  loadedScripts: [],
556  loadingScripts: [],
557  loadingScriptsCallbacks: {},
558  init: function() {
559    var inputPhone = $('.phone-inputmask');
560
561    if (countryCode in countryToMask) {
562      $(inputPhone).focus(function () {
563        if ($(this).val().length < 1) {
564          $(this).val(countryToMask[countryCode]['code']);
565        }
566      });
567    }
568    if (inputPhone) {
569      inputPhone.inputmask({
570        showMaskOnFocus: true,
571        oncomplete: function (e) {
572          var phone_validate_input = getPhoneValidateInput(e.target);
573          phone_validate_input.val('1');
574        },
575        onincomplete: function (e) {
576          //@TODO: если будет несколько телефонов для валидации на форме - нужно будет переделать
577          var phone_validate_input = getPhoneValidateInput(e.target);
578          phone_validate_input.val('0');
579        }
580      });
581    }
582    SerpstatMain.setResponsivePageClass();
583  },
584  fieldsOrderTrigger: function() {
585    $('.table').on('tableOrder', function(event) {
586      if (SerpstatMain.isNotGuest()) {
587        var that = $(this),
588          fields = [];
589
590        that.find('th').each(function() {
591          var field = $(this).attr('data-name');
592
593          if (field) {
594            fields.push(field);
595          }
596        });
597
598        var url_path = that.attr('data-url-path');
599
600        if (!url_path) {
601          url_path = window.location.pathname;
602        }
603
604        if (fields) {
605          $.ajax({
606            url: '/users/save_fields_order',
607            type: 'POST',
608            dataType: 'json',
609            data: {
610              fields: fields.join(','),
611              url: url_path
612            },
613            beforeSend: function() {},
614            error: function() {}
615          });
616        }
617      }
618    });
619  },
620  scoreEvent: function(eventName) {
621    if (eventName && SerpstatMain.isNotGuest()) {
622      var event = localStorage.getItem('ss_event' + eventName);
623
624      if (!event) {
625        console.log('Fire trigger event ' + eventName);
626        $.ajax({
627          url: '/users/scoring_event?event=' + eventName,
628          dataType: 'json',
629          beforeSend: function() {},
630          error: function() {},
631          success: function() {
632            localStorage.setItem('ss_event' + eventName, 1);
633          }
634        });
635      } else {
636        console.log('Event ' + eventName + ' was already fired');
637      }
638    }
639  },
640  abortAjaxQueries: function() {
641    for (var n in SerpstatMain.ajaxRequests) {
642      SerpstatMain.ajaxRequests[n].abort();
643    }
644    SerpstatMain.currentAjaxRequests = 0;
645    SerpstatMain.currentAjaxRequestNumber = 1;
646  },
647  addAjaxRequest: function(n, request) {
648    SerpstatMain.ajaxRequests[n] = request;
649  },
650  removeAjaxRequest: function(n) {
651    delete SerpstatMain.ajaxRequests[n];
652  },
653  getCurrentAjaxRequestNumber: function() {
654    return SerpstatMain.currentAjaxRequestNumber++;
655  },
656  getPage: function(url, target, changeUrl, type, scroll, loader) {
657    target = SerpstatMain.setParam(target, '#content');
658    changeUrl = SerpstatMain.setParam(changeUrl, true);
659    type = SerpstatMain.setParam(type, 'GET');
660    scroll = SerpstatMain.setParam(scroll, true);
661    loader = SerpstatMain.setParam(loader, true);
662
663    SerpstatMain.abortAjaxQueries();
664    var result_block = $(target),
665      n = SerpstatMain.getCurrentAjaxRequestNumber();
666
667    var loader_block = result_block;
668    if (loader == true) loader_block = result_block;
669    else if (loader == 'false') loader_block = false;
670    else loader_block = $(loader);
671
672    var req = $.ajax({
673      url: url,
674      type: type,
675      beforeSend: function(req) {
676        if (loader_block != false) loader_block.loader();
677      },
678      success: function(data, textstatus, xhrreq) {
679        try {
680          data = JSON.parse(data);
681          if (data.status_code == 204) {
682            doAlert('info', data.result);
683          } else if (data.status_code == 200) {
684            result_block.text(data.result);
685          } else if (data.status_code == 1001) {
686            window.location.href = '/pay/';
687          } else if (data.status_code == 304) {
688            $.get('/base/updateLimitWidget', {
689              module: data.result['module']
690            }).done(function(data) {
691              $('#limit_exceeded_dialog').html(data);
692              $('#dialog_limit_exceeded').myDialog();
693            });
694          } else if (data.status_code == 302) {
695            $('#dialog_upgrade')
696              .find('.info-text')
697              .text(data.result['msg']);
698            $('#dialog_upgrade').myDialog();
699          } else if (data.status_code == 308) {
700            $('#dialog_team_member')
701              .find('.info-text')
702              .text(data.result['msg']);
703            $('#dialog_team_member')
704              .find('.owner_email')
705              .attr('href', 'mailto:' + data.result['owner_email'])
706              .text(data.result['owner_email']);
707            $('#dialog_team_member').myDialog();
708          } else if (data.status_code == 303) {
709            $('#dialog_register')
710              .find('.info-text')
711              .text(data.result['msg']);
712            $('#dialog_register').myDialog();
713          } else if (data.status_code == 400) {
714            doAlert('error', data.result);
715          } else if (data.status_code == 406) {
716            callDialog(data.result);
717          } else if (data.status_code == 402) {
718            callDialogAlert(data.result);
719          } else if (data.status_code == 205) {
720            if (data.result) {
721              window.location.href = data.result;
722            } else {
723              window.location.reload();
724            }
725          }
726          return false;
727        } catch (e) {
728          result_block.html(data);
729          $.get('/base/preHeader', { url: url }).done(function(data) {
730            $('.pre_header').html(data);
731            $('.pre_header .alert').each(function() {
732              var alert_id = $(this).data('alert_id');
733              var alert_shown = localStorage.getItem('globalAlert' + alert_id);
734              if (!alert_shown) {
735                $(this).show();
736              }
737            });
738          });
739        }
740        if (changeUrl && target == '#content') {
741          var url_parser = document.createElement('a');
742          url_parser.href = url;
743
744          var final_url = xhrreq.getResponseHeader('X-REQUESTED-URL');
745          if (final_url) {
746            url = final_url;
747          }
748
749          url = removeParamFromUrl(url, 'content');
750
751          // добавляем hash если он был в старом урле
752          SerpstatMain.changeUrl(url + url_parser.hash);
753        }
754
755        if (scroll && target == '#content') {
756          $('body,html').animate({ scrollTop: 0 }, 'slow');
757          $('.bsearch_handler').hide();
758        } else if (target != '#content') {
759          if (result_block) {
760            $('body,html').animate(
761              { scrollTop: result_block.offset().top },
762              'slow'
763            );
764          }
765        }
766        document
767          .getElementById('content')
768          .dispatchEvent(SerpstatMain.afterAjaxLoadEvent);
769      },
770      complete: function(req) {
771        if (loader_block != false) loader_block.loader('remove');
772        SerpstatMain.removeAjaxRequest(n);
773        localStorage.setItem('isPageLoad', false);
774        if (window.competitors.length > 0) {
775          window.competitors.forEach(function(item, index) {
776            updateCompetitorRowData(item);
777            if (window.competitors.length - 1 === index) {
778              window.competitors = [];
779            }
780          });
781        }
782      }
783    });
784    SerpstatMain.addAjaxRequest(n, req);
785
786    return req;
787  },
788  getAjaxBlocks: function(data) {
789    SerpstatMain.currentAjaxRequests += data.length;
790    for (var i in data) {
791      SerpstatMain.getAjaxBlock(data[i].url, data[i].id);
792    }
793  },
794  getAjaxBlock: function(url, block, fire_ajax_event, callback, move_script) {
795    fire_ajax_event = SerpstatMain.setParam(fire_ajax_event, true);
796    var result_block = typeof block == 'string' ? $('#' + block) : block;
797    var n = SerpstatMain.getCurrentAjaxRequestNumber();
798    SerpstatMain.currentAjaxRequests += 1;
799    var request = $.ajax({
800      url: url,
801      timeout: 300000,
802      beforeSend: function() {},
803      success: function(data) {
804        // переопределил, т.к. старый result_block был не валидным и не работал с текущим DOM
805        var result_block = typeof block == 'string' ? $('#' + block) : block;
806        try {
807          data = JSON.parse(data);
808          if (!isNaN(data)) {
809            result_block.html(data);
810          }
811          return false;
812        } catch (e) {
813          if (move_script) {
814            var scripts = data.match(/<script[.\s\S]*?<\/script>/g);
815            result_block.html(data.replace(/<script[.\s\S]*?<\/script>/g, ''));
816            if (scripts) {
817              scripts.forEach(function(tag) {
818                $(tag).appendTo('body');
819              });
820            }
821          } else {
822            result_block.html(data);
823          }
824        }
825
826        // если загружается много одновременных запросов выполнить
827        // только в конце загрузки
828        if (fire_ajax_event && SerpstatMain.currentAjaxRequests < 2) {
829          //                  закоментил, т.к. при загрузке блока - срабатывали и обработчики при загрузке страницы
830          //                    document.getElementById('content').dispatchEvent(SerpstatMain.afterAjaxLoadEvent);
831          document
832            .getElementById('content')
833            .dispatchEvent(SerpstatMain.afterAjaxLoadBlockEvent);
834        }
835
836        if (typeof callback == 'function') {
837          callback();
838        }
839      },
840      complete: function(req) {
841        SerpstatMain.removeAjaxRequest(n);
842        SerpstatMain.currentAjaxRequests -= 1;
843      },
844      error: function() {
845        result_block.html('');
846      }
847    });
848    SerpstatMain.addAjaxRequest(n, request);
849    return request;
850  },
851  changeUrl: function(url) {
852    // Добавление слеша в закрывающий url при ajax запросе.
853    // Меньше вопросов от seo-шников будет.
854    var url_parser = document.createElement('a');
855    url_parser.href = url;
856    if (url_parser.pathname.slice(-1) !== '/') {
857      url_parser.pathname += '/';
858    }
859    url = url_parser.pathname + url_parser.search + url_parser.hash;
860    if (window.history.pushState) {
861      window.history.pushState(null, null, url);
862    } else if (history.pushState) {
863      history.pushState(null, null, url);
864    }
865      var pathNameArray = window.location.pathname.split('/');
866      if (pathNameArray.includes('api')
867          || pathNameArray.includes('tutorial')
868          || pathNameArray.includes('use-cases')
869          || pathNameArray.includes('help')) {
870        var langArr = ['en', 'uk', 'ru'],
871            langDropdown = '',
872            currentLocale = window.location.pathname.substr(1, 2),
873            pathName= window.location.pathname;
874        if (['ru', 'uk', 'de'].indexOf(currentLocale) !== -1) {
875          pathName = window.location.pathname.substr(3);
876        }
877        langArr.forEach(function (lang, index) {
878          var locale = '';
879          if (lang !== 'en') {
880            locale = '/' + lang;
881          }
882          var lang_url = locale + pathName + window.location.search;
883          if (currentLocale === lang) {
884            langDropdown += '<a>' + lang.toUpperCase() + '</a>';
885          } else {
886            langDropdown += '<a href="' + lang_url + '"  data-lang="' + lang + '"  class = "set_langs"  data-event-action = "language" '
887                + 'data-event-label = "' + currentLocale + '-' + lang + '" data-interaction = "opt_noninteraction" >' + lang.toUpperCase() + '</a>';
888          }
889        });
890        $('.header_lang .links_dropdown').html(langDropdown)
891      }
892
893    $('title').text(SerpstatMain.title);
894    document
895      .getElementById('content')
896      .dispatchEvent(SerpstatMain.afterChangeUrlEvent);
897
898    window.dataLayer = window.dataLayer || [];
899    dataLayer.push({
900      event: 'gtmUaEvent',
901      eventCategory: 'Pageview',
902      eventAction: url,
903      eventLabel: document.title,
904      eventNonInteraction: 'false'
905    });
906
907    return false;
908  },
909  getAttr: function(element, attr_name, default_value) {
910    var value = element.attr(attr_name);
911    return value ? value : default_value;
912  },
913  getFormElements: function(form) {
914    var elements = form.serializeArray(),
915      result = [];
916    if (form.attr('data-skip-empty')) {
917      for (var i in elements) {
918        if (elements[i].value) {
919          result.push(elements[i]);
920        }
921      }
922      return result;
923    } else {
924      return elements;
925    }
926  },
927  ajaxSubmit: function(submit) {
928    var form = submit.closest('form'),
929      url = form.attr('action'),
930      elements = SerpstatMain.getFormElements(form);
931
932    var element_loader = submit.find('button[type=submit]');
933    if (element_loader === false) {
934      element_loader = submit;
935    }
936
937    form.find('.input_error').remove();
938
939    return $.ajax({
940      url: url,
941      // crossDomain: true,
942      // xhrFields: {
943      //     withCredentials: true
944      // },
945      type: 'POST',
946      dataType: 'json',
947      data: elements,
948      beforeSend: function(req) {
949        element_loader.loader();
950      },
951      success: function(data) {
952        // console.log(data);return;
953        if (data.status_code == 205) {
954          if (data.result) {
955            window.location.href = data.result;
956          } else {
957            window.location.reload();
958          }
959        } else if (data.status_code == 302) {
960          SerpstatMain.getPage(data.result);
961        } else if (data.status_code == 200) {
962          if (data.result && !form.hasClass('no_alert')) {
963            if (form.hasClass('success_animation')) {
964              element_loader.buttonSuccess();
965            }
966            var time = 10000,
967              message;
968            if (typeof data.result == 'object') {
969              message = data.result.message;
970              if (data.result.time) {
971                time = data.result.time;
972              }
973            } else {
974              message = data.result;
975            }
976
977            doAlert('success', message, time);
978            $('.dialog').myDialog('close');
979          } else {
980            $('.dialog').myDialog('close');
981          }
982          if (form.attr('data-clear')) {
983            form
984              .find(
985                'input[type=text], input[type=email], input.tagsinput, textarea, select'
986              )
987              .val('');
988            form.find('.tagsinput .tag').remove();
989            form.find('input[type=checkbox]').removeAttr('checked');
990          }
991          if(form.attr('data-no-gdpr')){
992            hasNoGdprCookie = false
993            $(".el_used_gdpr").each(function () {
994              $(this).removeAttr("hidden")
995              $(this).removeAttr("disabled")
996            });
997            $(".hide_by_gdpr").each(function () {
998              $(this).removeClass("hide_by_gdpr")
999            });
1000          }
1001
1002          if (form.attr('data-hide-block')) {
1003            $(form.attr('data-hide-block')).hide();
1004          }
1005        } else if (data.status_code == 406) {
1006          callDialog(data.result);
1007        } else if (data.status_code == 402) {
1008          setTimeout(function() {
1009            callDialogAlert(data.result);
1010          }, 300);
1011        } else if (data.status_code != 200) {
1012          if (form.hasClass('ajax_errors_inline')) {
1013            if (typeof data.result == 'object') {
1014              for (var name in data.result) {
1015                if (typeof data.result[name][0] == 'object') {
1016                  form
1017                    .find('input[name=' + name + ']')
1018                    .after(
1019                      '<div class="input_error">' +
1020                        data.result[name][0] +
1021                        '</div>'
1022                    );
1023                } else {
1024                  form
1025                    .find('input[name=' + name + ']')
1026                    .after(
1027                      '<div class="input_error">' + data.result[name] + '</div>'
1028                    );
1029                }
1030              }
1031            } else {
1032              doAlert('info', data.result);
1033            }
1034          } else {
1035            if (typeof data.result == 'object') {
1036              for (var i in data.result) {
1037                if (data.status_code == 400) {
1038                  doAlert('info', data.result[i]);
1039                } else if (data.status_code != 304) {
1040                  doAlert('error', data.result[i]);
1041                }
1042              }
1043            } else {
1044              if (data.status_code == 400) {
1045                doAlert('info', data.result);
1046              } else {
1047                doAlert('error', data.result);
1048              }
1049            }
1050          }
1051        }
1052        document
1053          .getElementById('content')
1054          .dispatchEvent(SerpstatMain.afterAjaxFormSubmitEvent);
1055      },
1056      complete: function(req) {
1057
1058        element_loader.loader('remove');
1059      }
1060    });
1061  },
1062  getScript: function(url, callback) {
1063    if (SerpstatMain.loadedScripts.indexOf(url) != -1) {
1064      if (typeof callback == 'function') {
1065        callback();
1066      }
1067    } else {
1068      if (SerpstatMain.loadingScripts.indexOf(url) != -1) {
1069        if (typeof callback == 'function') {
1070          if (!SerpstatMain.loadingScriptsCallbacks[url]) {
1071            SerpstatMain.loadingScriptsCallbacks[url] = [];
1072          }
1073          SerpstatMain.loadingScriptsCallbacks[url].push(callback);
1074        }
1075        return;
1076      }
1077      var added_num = SerpstatMain.loadingScripts.push(url) - 1;
1078      $.ajax({
1079        url: url,
1080        dataType: 'script',
1081        beforeSend: function() {},
1082        success: function(data) {
1083          SerpstatMain.loadedScripts.push(url);
1084          delete SerpstatMain.loadingScripts[added_num];
1085          if (typeof callback == 'function') {
1086            callback();
1087          }
1088          if (SerpstatMain.loadingScriptsCallbacks[url] !== undefined) {
1089            for (
1090              i = 0;
1091              i < SerpstatMain.loadingScriptsCallbacks[url].length;
1092              i++
1093            ) {
1094              SerpstatMain.loadingScriptsCallbacks[url][i]();
1095            }
1096            delete SerpstatMain.loadingScriptsCallbacks[url];
1097          }
1098        },
1099        complete: function() {},
1100        error: function() {}
1101      });
1102    }
1103  },
1104  getUrlParams: function(url) {
1105    var query_string = url.split('?').pop(),
1106      result = {},
1107      params = query_string.split('&');
1108    for (var i in params) {
1109      if (!params.hasOwnProperty(i)) {
1110        continue;
1111      }
1112      param = params[i].split('=');
1113      if (param.length == 2) {
1114        result[param[0]] = decodeURIComponent(param[1]).replace('+', ' ');
1115      }
1116    }
1117    return result;
1118  },
1119  formatNumber: function(number, decimal_digits, delemeter) {
1120    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
1121  },
1122  buildUri: function(params) {
1123    var uri = '';
1124    for (var name in params) {
1125      if (name && params[name])
1126        uri += name + '=' + encodeURIComponent(params[name]) + '&';
1127    }
1128    return uri;
1129  },
1130  shortNumber: function(value) {
1131    var abs_value = Math.abs(value);
1132    if (abs_value >= 1000000000)
1133      return Math.round(value / 100000000) / 10 + 'B';
1134    else if (abs_value >= 1000000) return Math.round(value / 100000) / 10 + 'M';
1135    else if (abs_value >= 1000) return Math.round(value / 100) / 10 + 'K';
1136    return value;
1137  },
1138  isNotGuest: function() {
1139    return $('.header_user').length == 1;
1140  },
1141  checkGuestUser: function() {
1142    // Если юзер не гость - релоадим страницу. У него истекла сессия.
1143    if (SerpstatMain.isNotGuest()) window.location.reload();
1144  },
1145  getFilterParams: function(form) {
1146    var filter = [];
1147
1148    form.find('.filter_row_default input').each(function() {
1149      filter.push(
1150        $(this).attr('name') + '=' + encodeURIComponent($(this).val())
1151      );
1152    });
1153
1154    var i = 0;
1155    n = 0;
1156    form.find('.filter').each(function() {
1157      if ($(this).hasClass('filter_or')) {
1158        n++;
1159      }
1160      $(this)
1161        .find('.filter_row')
1162        .each(function() {
1163          $(this)
1164            .find('input, textarea')
1165            .each(function() {
1166              filter.push(
1167                'filter:' +
1168                  n +
1169                  ':' +
1170                  i +
1171                  ':' +
1172                  $(this).attr('name') +
1173                  '=' +
1174                  encodeURIComponent($(this).val())
1175              );
1176            });
1177          i++;
1178        });
1179    });
1180    return filter.join('&');
1181  },
1182
1183  setParam: function(variable, value) {
1184    if (typeof variable === 'undefined') {
1185      variable = value;
1186    }
1187    return variable;
1188  },
1189
1190  setResponsivePageClass: function() {
1191    if (document.isResponsivePage || $('body').hasClass('page_promo')) {
1192      $('body').addClass('page_responsive');
1193      $('meta[name=viewport]').attr(
1194        'content',
1195        'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'
1196      );
1197      document.isResponsivePage = false;
1198    } else {
1199      $('body').removeClass('page_responsive');
1200      $('meta[name=viewport]').attr('content', 'width=1250');
1201    }
1202  },
1203  exportRequest: function(url) {
1204    if (window.location.hostname == SerpstatMain.getUrlHost(url)) {
1205      if (window.success_export_message) {
1206        doAlert('info', window.success_export_message);
1207      }
1208
1209      $.ajax({
1210        url: url,
1211        type: 'GET',
1212        dataType: 'json',
1213        success: function(data) {
1214          if (data.status_code == 200) {
1215            if (!window.success_export_message) {
1216              doAlert('info', data.result);
1217            }
1218          } else if (data.status_code == 201) {
1219            doAlert('warning', data.result);
1220          } else {
1221            doAlert('error', data.result);
1222          }
1223        }
1224      });
1225    } else {
1226      window.open(url, '_blank');
1227    }
1228  },
1229
1230  formParamsToUrl: function(form) {
1231    var join_sign,
1232      parser = document.createElement('a'),
1233      elements = SerpstatMain.getFormElements(form);
1234
1235    parser.href = form.attr('action');
1236    join_sign = parser.search ? '&' : '?';
1237
1238    return form.attr('action') + join_sign + $.param(elements);
1239  },
1240  getUrlHost: function(href) {
1241    var l = document.createElement('a');
1242    l.href = href;
1243    return l.hostname;
1244  },
1245  webSocketData: function(options, callback) {
1246    var optionsDefault = {
1247        modes: 'websocket',
1248        jsonChannelKey: 'context',
1249        jsonTextKey: 'data',
1250        messagesPublishedAfter: 10000,
1251        messagesControlByArgument: true,
1252        onmessage: function(data, id, channel) {
1253          callback({ id: id, data: data });
1254        }
1255      },
1256      optionsMerged = {};
1257    for (var attrname in options) {
1258      if (attrname !== 'channel') {
1259        optionsMerged[attrname] = options[attrname];
1260      }
1261    }
1262    for (var attrname2 in optionsDefault) {
1263      optionsMerged[attrname2] = optionsDefault[attrname2];
1264    }
1265    var pushstream = new PushStream(optionsMerged);
1266    pushstream.addChannel(SerpstatMain.createChannelName(options.channel));
1267    pushstream.connect();
1268  },
1269
1270  /**
1271   * @description
1272   * @param {string} name
1273   * @return {string}
1274   */
1275  createChannelName: function createChannelName(name) {
1276    /**
1277   * @description
1278   * Покрывает следующие шаблоны доменов
1279   *
1280   * N.dev.serpstat.com - N_dev
1281   * dev0N.serpstat.com - dev0N
1282   * prelive-w2.serpstat.com - prelive_w2
1283   * prelive.serpstat.com - prelive
1284   * serpstat.com - prod
1285   *
1286   * @return {string}
1287   */
1288    function getPrefix() {
1289      const { hostname = domain } = new URL(getPrefix.URL);
1290      const splitDomain = hostname.replace('admin.', '').split('.');
1291      const first = splitDomain[0];
1292      const second = splitDomain[1];
1293
1294      switch (splitDomain.length) {
1295        case 2:
1296          return 'prod';
1297        case 3:
1298          return first.split('-').join('_');
1299        case 4:
1300          return `${first}_${second}`;
1301        case 5:
1302          return `${first}_${second}`;
1303        default:
1304          return '';
1305      }
1306    }
1307    /**
1308     * If need overide URL just change this static value
1309     */
1310    getPrefix.URL = window.location.origin;
1311
1312    const prefix = getPrefix();
1313
1314    return `${prefix}_${name}`;
1315  },
1316
1317  // ********************************************************************************
1318  // Reports
1319  // ********************************************************************************
1320  setUserReportsCountVisibility: function (count) {
1321    var $counters = $('.unread_reports_count');
1322    var countToCheck = 0;
1323    $counters.each(function (index, item) {
1324      var currentCount = parseInt($(item).find('.user_reports_num').text());
1325       countToCheck = currentCount > 0 ? currentCount : 0;
1326    })
1327
1328    $counters.each(function (index, item) {
1329      var countReport = count ? countToCheck + count : countToCheck;
1330      if (countReport) {
1331        $(item).show();
1332      } else {
1333        $(item).hide();
1334      }
1335    })
1336
1337  },
1338  setUserReportsCount: function(count) {
1339    SerpstatMain.setUserReportsCountVisibility(count);
1340  },
1341  clearSubmitedForm: function (elementId, widgetName, widgetId) {
1342    $($('#' + elementId + ' input ')).each(function () {
1343      $(this).val('');
1344    });
1345    grecaptcha.reset(widgetId);
1346    $('#' + widgetName).css('display', 'none');
1347  }
1348};
1349
1350
1351$('body').on('click', '.report_download_event', function(event) {
1352  var $this = $(this);
1353  var reportId = $this.attr('data-report-id');
1354  var gdriveReport = $this.attr('data-gdrive');
1355
1356  SerpstatMain.setUserReportsCount(-1);
1357
1358  if ($this.hasClass('hide_new_after')) {
1359    $this.next().hide();
1360  }
1361
1362  $.ajax({
1363    method: 'POST',
1364    url: '/users/report_update_status',
1365    data: {
1366      reportId: reportId,
1367      status: 2
1368    },
1369    dataType: 'json'
1370  }).done(function() {});
1371});
1372
1373$('body').on('click', '.report_delete_event', function(event) {
1374  var $this = $(this);
1375  var reportId = $this.attr('data-report-id');
1376  event.preventDefault();
1377
1378  $.ajax({
1379    method: 'POST',
1380    url: '/users/report_delete',
1381    data: {
1382      reportId: reportId
1383    },
1384    dataType: 'json'
1385  }).done(function() {
1386    $this.closest('tr').hide();
1387  });
1388});
1389
1390$(document).on('click', '.load_more', function(e) {
1391  e.preventDefault();
1392  $(this).loader();
1393  var wrapper = $(this).attr('data-block'),
1394    next_page = parseInt($(this).attr('data-page')),
1395    last_page = parseInt($(this).attr('data-last-page')),
1396    index = $(wrapper).find('.grid').length + 1,
1397    targetBlock = 'grid_page_' + index,
1398    search_by = $(this).data('search_by'),
1399    language = $(this).data('language'),
1400    search = $(this).data('search'),
1401      slug = $(this).data('category-slug'),
1402      company_type = $(this).data('filter-company-type'),
1403      industry_type = $(this).data('filter-industry-type'),
1404      tag = $(this).data('filter-tag');
1405
1406  var link_params = {
1407    page: next_page,
1408    slug: slug
1409  };
1410
1411  if (typeof search_by !== 'undefined' && typeof search !== 'undefined') {
1412    link_params[search_by] = search;
1413  }
1414
1415  if (typeof industry_type !== 'undefined') {
1416    link_params['industry_type'] = industry_type;
1417  }
1418  if (typeof company_type !== 'undefined') {
1419    link_params['company_type'] = company_type;
1420  }
1421  if (typeof tag !== 'undefined') {
1422    link_params['tag'] = tag;
1423  }
1424
1425  url = '/blog/get_more_news/?' + $.param(link_params);
1426
1427  if (language && language.length > 0) {
1428    url = '/' + language + url;
1429  }
1430
1431  $(wrapper).append('<div  id="' + targetBlock + '">');
1432  SerpstatMain.getPage(url, '#' + targetBlock, false, 'GET', false, false)
1433      .then(() => {
1434        $(this).loader('remove');
1435        if (next_page < last_page) {
1436          $(this).attr('data-page', next_page + 1);
1437        } else {
1438          $(this).remove();
1439        }
1440      });
1441});
1442
1443$(document).on('click', '.load_more_results', function (e) {
1444  e.preventDefault();
1445  $(this).loader();
1446  var wrapper = $(this).attr('data-block'),
1447      next_page = parseInt($(this).attr('data-page')),
1448      last_page = parseInt($(this).attr('data-last-page')),
1449      action = $(this).attr('data-action'),
1450      index = $(wrapper).find('.grid').length + 1,
1451      targetBlock = 'grid_page_' + index,
1452      language = $(this).attr('data-language');
1453
1454  var link_params = {
1455    page: next_page,
1456    action: action,
1457    search: $('.bsearch_input').val()
1458  };
1459  url = '/blog/blog-search/?' + $.param(link_params);
1460  if (language && language.length > 0) {
1461    url = '/' + language + url;
1462  }
1463  $(wrapper).append('<div  id="' + targetBlock + '">');
1464  SerpstatMain.getPage(url, '#' + targetBlock, false, 'GET', false, false)
1465      .then(() => {
1466        $(this).loader('remove');
1467        if (action != 'more_results') {
1468          if (next_page > last_page) {
1469            $('.another_language_button').attr('disabled', true)
1470          }else{
1471            $(this).attr('data-page', next_page + 1);
1472          }
1473          return
1474        }
1475        if (next_page < last_page) {
1476          $(this).attr('data-page', next_page + 1);
1477        } else {
1478          $(this).attr('disabled', true)
1479          $('.another_language_button').show()
1480
1481        }
1482      });
1483});
1484
1485function removeParamFromUrl(sourceURL, key) {
1486  var rtn = sourceURL.split('?')[0],
1487    param,
1488    params_arr = [],
1489    queryString = sourceURL.indexOf('?') !== -1 ? sourceURL.split('?')[1] : '';
1490  if (queryString !== '') {
1491    params_arr = queryString.split('&');
1492    for (var i = params_arr.length - 1; i >= 0; i -= 1) {
1493      param = params_arr[i].split('=')[0];
1494      if (param === key) {
1495        params_arr.splice(i, 1);
1496      }
1497    }
1498    rtn = rtn + '?' + params_arr.join('&');
1499  }
1500  return rtn;
1501}
1502
1503function setUrlParam(url, param, paramVal) {
1504  var newAdditionalURL = '';
1505  var tempArray = url.split('?');
1506  var baseURL = tempArray[0];
1507  var additionalURL = tempArray[1];
1508  var temp = '';
1509  if (additionalURL) {
1510    tempArray = additionalURL.split('&');
1511    for (var i = 0; i < tempArray.length; i++) {
1512      if (tempArray[i].split('=')[0] != param) {
1513        newAdditionalURL += temp + tempArray[i];
1514        temp = '&';
1515      }
1516    }
1517  }
1518
1519  var rows_txt = temp + '' + param + '=' + paramVal;
1520  return baseURL + '?' + newAdditionalURL + rows_txt;
1521}
1522
1523/**
1524 * Change item list for intervals dropdown
1525 *
1526 * @param {string} type
1527 * @param {Object} freqs_to_days
1528 */
1529function updateMailTriggerSelects(selector, type, freqs_to_days) {
1530  var freq = $(selector)
1531    .find('input[name="dps_' + type + '_data_freq"]')
1532    .val();
1533  var days = $(selector)
1534    .find('input[name="dps_' + type + '_interval"]')
1535    .val();
1536  var freq_in_days = freqs_to_days[freq];
1537
1538  var mail_triggers_disabled = $(selector)
1539    .find('#flag_mail_trigger_disabled')
1540    .val();
1541
1542  // if (freq > days) {
1543  //     $(selector).find('input[name="dps_' + type + '_interval"]').val(freqs_to_days[freq]);
1544  //     days = freqs_to_days[freq];
1545  // }
1546
1547  $(selector)
1548    .find('input[name="dps_' + type + '_interval"]')
1549    .parent()
1550    .find('.select_option')
1551    .each(function(i) {
1552      var el = $(this);
1553      if (el.data('val') < freq_in_days) {
1554        el.addClass('dn');
1555        el.removeClass('active');
1556      } else {
1557        el.removeClass('dn');
1558      }
1559
1560      if (el.data('val') == days) {
1561        el.addClass('active');
1562      }
1563    });
1564
1565  if (freq == 0 || mail_triggers_disabled) {
1566    // Только для Аудитов в Ручном режиме.
1567    $('#dps_' + type + '_enabled').prop('checked', false);
1568    $('#label_' + type + '_enabled').addClass('disabled');
1569    $('#dps_' + type + '_enableExportAfterFinish').addClass('disabled');
1570    $(selector)
1571      .find('input[name="dps_' + type + '_interval"]')
1572      .parent()
1573      .addClass('disabled');
1574  } else {
1575    if (days <= freqs_to_days[freq]) {
1576      // Частота больше чем интервал.  Нужно привести Интервал к частоте.
1577      $(
1578        selector +
1579          ' div[wrapper_class*="interval_dropdown"] div.select_option[data-val=' +
1580          freq_in_days +
1581          ']'
1582      ).click();
1583    }
1584    // интервал больше частоты.  Все норм.
1585    if (type == 'audit') {
1586      $('#label_' + type + '_enabled').removeClass('disabled');
1587      $('#dps_' + type + '_enableExportAfterFinish').removeClass('disabled');
1588    }
1589    $(selector)
1590      .find('input[name="dps_' + type + '_interval"]')
1591      .parent()
1592      .removeClass('disabled');
1593  }
1594
1595  return freq;
1596}
1597
1598
1599/**
1600 * Change item list for rt intervals dropdown
1601 */
1602function updateRtMailTriggerSelects() {
1603  updateMailTriggerSelects('#subscribe_rt', 'rt', {
1604    1: 1,
1605    3: 3,
1606    7: 7,
1607    14: 14,
1608    30: 30
1609  });
1610}
1611
1612function updateStartAuditMailTriggerSelects() {
1613  // key : days
1614  var freq = updateMailTriggerSelects('#dialog_audit_start', 'audit', {
1615    0: 0,
1616    1: 1,
1617    2: 3,
1618    3: 7,
1619    4: 14,
1620    5: 30
1621  });
1622  $(
1623    '#dialog_audit_start .check_frequency div.select_option[data-val=' +
1624      freq +
1625      ']'
1626  ).click();
1627  if (freq == 0) {
1628    $('#audit_mail_trigger_manual_scan_alert').show();
1629  } else {
1630    $('#audit_mail_trigger_manual_scan_alert').hide();
1631  }
1632}
1633
1634/**
1635 * Rules for disable rt switcher
1636 */
1637function disableRtSwitcher() {
1638  $('#label_rt_enabled').addClass('disabled');
1639}
1640
1641$('body').on(
1642  'dropdown.afterSelect',
1643
1644  '#subscribe_rt .dropdown_handler',
1645  function(e) {
1646    updateRtMailTriggerSelects();
1647  }
1648);
1649
1650$('body').on(
1651  'dropdown.afterSelect',
1652  '#dialog_audit_start .frequency_dropdown' +
1653    ', #dialog_audit_start .dropdown_handler',
1654  function(e) {
1655    if ($(this).hasClass('check_frequency')) {
1656      var freq = $('#dialog_audit_start')
1657        .find('input[name="check_frequency"]')
1658        .val();
1659
1660      $(
1661        '#dialog_audit_start .check_frequency div.select_option[data-val=' +
1662          freq +
1663          ']'
1664      ).click();
1665    } else {
1666      updateStartAuditMailTriggerSelects();
1667    }
1668  }
1669);
1670
1671$('body').on(
1672  'dropdown.afterSelect',
1673  '#subscribe_audit .dropdown_handler' +
1674    ', #subscribe_audit .frequency_dropdown',
1675  function(e) {
1676    updateAuditMailTriggerSelects();
1677  }
1678);
1679
1680$('body').on('click', '.limit_exceeded', function(e) {
1681  e.preventDefault();
1682  loadLimitsExceededWidgetBase($(this));
1683});
1684
1685$('body').on(
1686  'click',
1687  '#dialog_project_subscribe .dialog_tabs_choose .tab_choose',
1688  function() {
1689    tabName = $(this).data('tab');
1690    if (tabName == '#subscribe_rt') {
1691      alertProjectNotConfigured();
1692    }
1693  }
1694);
1695
1696$('body').on('click', '.create_project_button', function(e) {
1697  e.preventDefault();
1698  e.stopPropagation();
1699  $.ajax({
1700    url: $(this).attr('href'),
1701    type: 'GET',
1702    beforeSend: function() {},
1703    error: function() {},
1704    success: function(data) {
1705      var dialog = $('#dialog_new_project');
1706      dialog.html(data);
1707      dialog.myDialog({
1708        open: function(event, ui) {}
1709      });
1710    }
1711  });
1712  return false;
1713});
1714
1715$(document).on('click', '.dialog-session-destroyed .dialog_close', function(e) {
1716  e.preventDefault();
1717  location.reload();
1718});
1719
1720$('body').on('click', '.deleteGroup', function(e) {
1721  e.preventDefault();
1722  var $id = $(this).data('id');
1723  deleteProjectGroup($id);
1724});
1725
1726function deleteProjectGroup(groupId) {
1727  $.ajax({
1728    method: 'POST',
1729    url: '/projects/delete_group/',
1730    data: {
1731      pg_id: groupId
1732    },
1733    dataType: 'json'
1734  }).done(function(response) {
1735    if (response && response.status_code == 400) {
1736      doAlert('error', response.result);
1737      return false;
1738    }
1739
1740    SerpstatMain.getPage(document.URL);
1741  });
1742}
1743
1744function loadLimitsExceededWidgetBase(context) {
1745  $.get('/base/updateLimitWidget', {
1746    module: context.attr('data-module'),
1747    auditProjectOwnerId: context.attr('data-owner_id')
1748  }).done(function(data) {
1749    $('#limit_exceeded_dialog').html(data);
1750    $('#dialog_limit_exceeded').myDialog();
1751  });
1752}
1753
1754function showingManualFrequencySettingsAlert() {
1755  var frequency = $('#subscribe_audit')
1756    .find('input[name="dps_audit_data_freq"]')
1757    .val();
1758
1759  if (frequency == 0) {
1760    $('#subscribe_audit .alert.info').show();
1761  } else {
1762    $('#subscribe_audit .alert.info').hide();
1763  }
1764}
1765
1766/**
1767 * Запись в document.cookie
1768 *
1769 * @param string name название cookie
1770 * @param string value значение cookie
1771 * @param obj options объект с дополнительными свойствами для установки cookie:
1772
1773 expires - Время истечения cookie. Интерпретируется по-разному, в зависимости от типа:
1774 Число – количество секунд до истечения. Например, expires: 3600 – кука на час.
1775 Объект типа Date – дата истечения.
1776 Если expires в прошлом, то cookie будет удалено.
1777 Если expires отсутствует или 0, то cookie будет установлено как сессионное и исчезнет при закрытии браузера.
1778
1779 path - Путь для cookie.
1780
1781 domain - Домен для cookie.
1782
1783 secure - Если true, то пересылать cookie только по защищенному соединению.
1784 */
1785function setCookie(name, value, options) {
1786  options = options || {};
1787
1788  var expires = options.expires;
1789
1790  if (typeof expires == 'number' && expires) {
1791    var d = new Date();
1792    d.setTime(d.getTime() + expires * 1000);
1793    expires = options.expires = d;
1794  }
1795  if (expires && expires.toUTCString) {
1796    options.expires = expires.toUTCString();
1797  }
1798
1799  value = encodeURIComponent(value);
1800
1801  var updatedCookie = name + '=' + value;
1802
1803  for (var propName in options) {
1804    updatedCookie += '; ' + propName;
1805    var propValue = options[propName];
1806    if (propValue !== true) {
1807      updatedCookie += '=' + propValue;
1808    }
1809  }
1810
1811  document.cookie = updatedCookie;
1812}
1813
1814/**
1815 * Удаление куки
1816 *
1817 * @param string name
1818 */
1819function deleteCookie(name) {
1820  setCookie(name, '', {
1821    expires: -1
1822  });
1823}
1824
1825/**
1826 * Возвращает cookie с именем name, если есть, если нет, то undefined
1827 *
1828 * @param string name
1829 * @returns {any}
1830 */
1831function getCookie(name) {
1832  var matches = document.cookie.match(
1833    new RegExp(
1834      '(?:^|; )' +
1835        name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') +
1836        '=([^;]*)'
1837    )
1838  );
1839
1840  return matches ? decodeURIComponent(matches[1]) : undefined;
1841}
1842
1843function setSessionItemAfterAlertClose(alert_id) {
1844  localStorage.setItem('globalAlert' + alert_id, 1);
1845}
1846
1847$(document).ready(function() {
1848  $('.pre_header .alert').each(function() {
1849    var alert_id = $(this).data('alert_id');
1850    var alert_shown = localStorage.getItem('globalAlert' + alert_id);
1851    if (!alert_shown) {
1852      $(this).show();
1853    }
1854  });
1855});
1856
1857function setPropIfChecked() {
1858  const items = [].slice.apply($('.pdf_field_checkbox:not(:disabled)'));
1859  const isAllChecked = items.every(function(item) {
1860    return $(item).prop('checked');
1861  });
1862  $('#select_all_fields').prop('checked', isAllChecked);
1863}
1864
1865function setValueToSessionStorage() {
1866  const items = [].slice.apply($('.pdf_field_checkbox:not(:disabled)'));
1867  let itemsToSessionStorage = {};
1868  items.forEach(function(elem) {
1869    itemsToSessionStorage = Object.assign({}, itemsToSessionStorage, {
1870      [$(elem).attr('id')]: $(elem).prop('checked')
1871    });
1872  });
1873
1874  sessionStorage.setItem('popupItems', JSON.stringify(itemsToSessionStorage));
1875}
1876
1877function getValueFromSessionStorage() {
1878  return sessionStorage.getItem('popupItems') || null;
1879}
1880
1881function setInitProps() {
1882  const items =
1883    getValueFromSessionStorage() && JSON.parse(getValueFromSessionStorage());
1884  if (items) {
1885    for (const key in items) {
1886      if (items.hasOwnProperty(key)) {
1887        $("input[id='" + key + "']:not(:disabled)").prop('checked', items[key]);
1888      }
1889    }
1890  }
1891}
1892
1893$(document).ready(function() {
1894  $('#content').on('after_ajax_load_block', function() {
1895    setInitProps();
1896    setPropIfChecked();
1897
1898    $('#select_all_fields').on('change', function() {
1899      const $that = $(this);
1900      const isChecked = $that.prop('checked');
1901      $('.pdf_field_checkbox:not(:disabled)').prop('checked', isChecked);
1902      setValueToSessionStorage();
1903    });
1904
1905    $('.pdf_field_checkbox:not(:disabled)').on('change', setPropIfChecked);
1906    $('.pdf_field_checkbox:not(:disabled)').on(
1907      'change',
1908      setValueToSessionStorage
1909    );
1910  });
1911});
1912
1913
1914var demoBtns = document.querySelectorAll("a[data-dialog='#dialog_demo'], button[data-dialog='#dialog_demo']");
1915[].forEach.call(demoBtns, function(btn) {
1916  btn.addEventListener('click', function(){
1917    addToDataLayer('Basic', 'Demo', 'Btn');
1918  });
1919});
1920
1921function addToDataLayer(category, action, label) {
1922  window.dataLayer = window.dataLayer || [];
1923  dataLayer.push({
1924    'event' : 'gtmUaEvent',
1925    'eventCategory' : category, //подставить соотв. категорию
1926    'eventAction' : action, //подставить соотв. действие
1927    'eventLabel' : label, //подставить соотв. label
1928    'eventNonInteraction' : false
1929  });
1930
1931  if(action === 'Demo'){
1932    var d = (new Date());
1933    dataLayer.push({'demoDate': d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate()});
1934  }
1935
1936
1937}
1938
1939function gdprAccepted(){
1940  hasNoGdprCookie = false
1941  $(".gdpr-tab").remove();
1942  $(".el_used_gdpr").each(function () {
1943    $(this).removeAttr("hidden")
1944    $(this).removeAttr("disabled")
1945  });
1946}
1947
1948$('body').on("click", ".blog_youtube_video_play", function(event) {
1949  var $this = $(this);
1950  var iframe = document.createElement('iframe');
1951  iframe.width = "100%";
1952  iframe.height = "100%";
1953  iframe.src = $this.data("video") + '?autoplay=1';
1954  iframe.title = $this.data("title");
1955  iframe.frameborder = "0";
1956  iframe.allowfullscreen = "allowfullscreen";
1957  iframe.mozallowfullscreen = "mozallowfullscreen";
1958  iframe.msallowfullscreen = "msallowfullscreen";
1959  iframe.oallowfullscreen = "oallowfullscreen";
1960  iframe.webkitallowfullscreen = "webkitallowfullscreen";
1961  iframe.allow = "autoplay";
1962  $this.html('');
1963  $this.append(iframe);
1964});

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.