PageSourceSearch

https://freediving.ru/wp-content/themes/ff/inc/ff.js?ver=1790053395

js freediving.ru collected 2026-09-24 23:47:53 UTC 44,961 bytes, 1,283 lines download raw bytes

1jQuery(function ($) {
2    $(document).ready(function () {
3
4        if ($('#ff-role-tabs') && window.location.hash === '#docs') {
5            UIkit.tab('#ff-role-tabs').show('#member-docs-tab');
6        }
7
8
9        // function isTouchScreendevice() {
10        //     return 'ontouchstart' in window || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
11        // };
12
13
14        const profileEditIcon = document.getElementById('profile-edit-icon'),
15            // memberName = document.getElementById('member-name'),
16            profileEdit = document.getElementById('profile-edit'),
17            profileShow = document.getElementById('profile-show'),
18            roleCheckboxes = document.querySelectorAll('.ff-role-checkbox'),
19            instructorTypeEditor = document.getElementById('instructor-type-editor'),
20            profDescriptionWrap = document.getElementById('ff-prof-description-wrap'),
21            paraAthlete = document.getElementById('para-athlete-wrapper'),
22            userId = $('#profile-edit').attr('data-user_id');
23
24        if (profileEditIcon) {
25
26            profileEditIcon.addEventListener('click', function () {
27
28                profileEdit.classList.remove('ff-hidden')
29                profileShow.classList.add('ff-hidden')
30
31            })
32
33
34            $('.js-pd-display').on('click', function () {
35
36                let pdDisplay = $(this).attr('data-pd_display'),
37                    pdType = $(this).closest('.js-pd-display-parent').attr('data-pd_type');
38
39                $.ajax({
40                    url: ffscripts.ajaxUrl,
41                    type: 'POST',
42                    data: {
43                        action: 'pd_show',
44                        pd_type: pdType,
45                        pd_display: pdDisplay,
46                        user_id: userId
47                    },
48                    beforeSend: function (xhr) {
49                    },
50                    success: function (response) {
51
52                        let eyes = $('.js-' + response);
53                        eyes.each(function () {
54
55                            if ($(this).hasClass('ff-visible')) {
56                                $(this).removeClass('ff-visible').addClass('ff-hidden')
57                            } else if ($(this).hasClass('ff-hidden')) {
58                                $(this).removeClass('ff-hidden').addClass('ff-visible')
59                            }
60
61                        })
62
63                    }
64                });
65
66            })
67
68
69        }
70
71
72        roleCheckboxes.forEach((checkbox) => {
73            checkbox.addEventListener('change', (event) => {
74                if (event.target.value === 'instructor' && event.target.checked) {
75                    instructorTypeEditor.classList.remove('ff-hidden')
76                    profDescriptionWrap.classList.remove('ff-hidden')
77                } else if (event.target.value === 'instructor' && !event.target.checked) {
78                    instructorTypeEditor.classList.add('ff-hidden')
79                    profDescriptionWrap.classList.add('ff-hidden')
80                }
81
82
83                if (event.target.value === 'athlete' && event.target.checked) {
84                    paraAthlete.classList.remove('ff-hidden')
85                } else if (event.target.value === 'athlete' && !event.target.checked) {
86                    paraAthlete.classList.add('ff-hidden')
87                }
88
89            })
90        })
91
92
93        document.body.addEventListener('keydown', function (e) {
94            if (e.key == "Escape") {
95                profileEdit.classList.add('ff-hidden')
96                profileShow.classList.remove('ff-hidden')
97            }
98        });
99
100
101        $('#photo-edit').click(function () {
102            $('#photo-input').trigger('click');
103        })
104
105        $("#photo-input").on('change', function () {
106
107            let file_data = $('#photo-input').prop('files')[0],
108                entityId = $(this).attr('data-entity_id');
109
110            let form_data = new FormData();
111            form_data.append('file', file_data);
112            form_data.append('entity_type', 'user');
113            form_data.append('entity_id', entityId);
114            form_data.append('meta_key', 'photo');
115            form_data.append('action', 'ff_ajax_uploader');
116            // form_data.append('security', blog.security); // TODO: WP Nonce
117
118
119            $.ajax({
120                url: ffscripts.ajaxUrl,
121                type: 'POST',
122                contentType: false,
123                processData: false,
124                data: form_data,
125                beforeSend: function (xhr) {
126                    $('#photo-form label[for=photo-input]').html('<img src="' + ffscripts.themeUrl + '/img/spinner.gif">');
127                },
128                success: function (response) {
129                    let fileData = JSON.parse(response)
130                    $('#member-photo-holder').html('<img src="' + fileData.url + '" alt="" class="">');
131                    $('#photo-form label[for=photo-input]').html('<span uk-icon="icon: pencil; ratio: 1.2" class="edit-icon" id="photo-edit"></span>');
132                }
133            });
134
135        });
136
137
138
139        $('.js-document-date').each(function () {
140
141            let datePicker = $(this);
142
143            datePicker.datepicker({
144                minDate: "0",
145                // maxDate: "+7d",
146                numberOfMonths: [1, 1],
147                changeMonth: true,
148                changeYear: true,
149                yearRange: ":+20",
150                onSelect: function (date, datepicker) {
151                    $.ajax({
152                        url: ffscripts.ajaxUrl,
153                        type: 'POST',
154                        data: {
155                            action: 'set_document_date',
156                            date: date,
157                            document_type_date: $(this).data('document_type_date'),
158                        },
159                        beforeSend: function (xhr) {
160                            datePicker.closest('div').find('.js-document-loader').html('<span class="uk-margin-small-left"><img src="' + ffscripts.themeUrl + '/img/spinner.gif"></span>');
161                        },
162                        success: function (response) {
163
164                            if (response === 'success') {
165                                datePicker.closest('div').find('.js-document-loader').html('<span class="uk-margin-small-left medium-blue-color" uk-icon="icon: check; ratio: 1.6"></span>');
166                                datePicker.removeClass('required-field');
167                            }
168
169                        }
170                    })
171                }
172            })
173
174        });
175
176
177        $('.js-files-upload').click(function (e) {
178            e.preventDefault();
179            $(this).closest('.js-uploader-wrapper').find('.js-ff-ajax-file-uploader').trigger('click');
180        })
181
182        $(".js-ff-ajax-file-uploader").on('change', function () {
183
184
185            let file_data = $(this).prop('files')[0],
186                entity_id = $(this).data('entity_id'),
187                entity_type = $(this).data('entity_type'),
188                metaKey = $(this).attr('name'),
189                resultWrapper = $(this).closest('.js-uploader-wrapper').find('.js-upload-result'),
190                resultText = resultWrapper.data('result_text');
191
192            let form_data = new FormData();
193            form_data.append('file', file_data);
194            form_data.append('entity_id', entity_id);
195            form_data.append('entity_type', entity_type);
196            form_data.append('meta_key', metaKey);
197            form_data.append('action', 'ff_ajax_uploader');
198            // form_data.append('security', blog.security); // TODO: WP Nonce
199
200            $.ajax({
201                url: ffscripts.ajaxUrl,
202                type: 'POST',
203                contentType: false,
204                processData: false,
205                data: form_data,
206                beforeSend: function (xhr) {
207                    resultWrapper.html('<img src="' + ffscripts.themeUrl + '/img/spinner.gif">');
208                },
209                success: function (response) {
210
211                    if (response) {
212
213                        let parsedResponse = JSON.parse(response)
214
215                        if (resultText === undefined) resultText = parsedResponse['name']
216
217                        let uploadedUrl = parsedResponse['url'];
218
219                        resultWrapper.html('<a href="' + uploadedUrl + '" target="_blank" class="uk-flex uk-flex-middle"><span class="medium-blue-color">' + resultText + '</span></a>');
220                        resultWrapper.addClass('success').trigger('classChange')
221                    } else {
222                        resultWrapper.html('<span uk-icon="icon: ban; ratio: 1.2" class="alert-icon"></span>');
223                    }
224                }
225            });
226
227        });
228
229
230        if ($('.ff-location-select').length !== 0) {
231
232            $('.ff-location-select').select2({
233                multiple: true,
234                width: '100%',
235                maximumSelectionLength: 2,
236                // placeholder: 'Город',
237                placeholder: function () {
238                    $(this).data('Город');
239                },
240                ajax: {
241                    url: ffscripts.ajaxUrl,
242                    dataType: 'json',
243                    delay: 250,
244                    data: function (params) {
245                        return {
246                            q: params.term, // search query
247                            action: 'ff_cities_select'
248                        };
249                    },
250                    processResults: function (data) {
251                        var options = [];
252                        if (data) {
253
254                            // data is the array of arrays, and each of them contains ID and the Label of the option
255                            $.each(data, function (index, text) { // do not forget that "index" is just auto incremented value
256                                options.push({id: text[0], text: text[1]});
257                            });
258
259                        }
260                        return {
261                            results: options
262                        };
263                    },
264                    cache: true
265                },
266                minimumInputLength: 2,  // TODO: для соревнование ограничение в 1 город
267                language: {
268                    maximumSelected: function (e) {
269                        return 'Вы можете выбрать максимум 2 города';
270                    },
271                    searching: function (e) {
272                        return 'Ищем...';
273                    },
274                    noResults: function () {
275                        return 'Город не найден';
276                    },
277                },
278                placeholder: {
279                    text: 'Город'
280                }
281
282            });
283
284        }
285
286
287        $('#profile-edit').addClass('ff-hidden');
288
289        $('#profile-save').on('click', function () {  // Saving member cities in the DB
290            let cities = $('.ff-location-select').val(),
291                entity_id = $(this).attr('data-entity_id'),
292                citiesType;
293
294            if ($('body').hasClass('author')) {
295                citiesType = 'member';
296            } else if ($('body').hasClass('single-competition')) {
297                citiesType = 'competition';
298            }
299
300
301            if (cities.length !== 0) {
302                $('#location-message').text('')
303
304                $.ajax({
305                    url: ffscripts.ajaxUrl,
306                    type: 'POST',
307                    data: {
308                        action: 'ff_location_save',
309                        cities: cities,
310                        entity_id: entity_id,
311                        cities_type: citiesType
312                    },
313                    beforeSend: function (xhr) {
314                        // $('#location-save').html('<img src="' + mgiscript.themeUrl + '/img/spinner-2x.gif">') // TODO: добавить спиннеры в стилистике иконок
315                    },
316                    success: function (response) {
317
318                        $('#location-edit').removeClass('required-field');
319
320                        if (JSON.parse(response)['city'] || JSON.parse(response)['country'].includes('online')) {
321                            var outputCities = '';
322
323                            if (JSON.parse(response)['city']) {
324                                JSON.parse(response)['city'].forEach((value) => {
325                                    console.log(value)
326                                    outputCities += '<span class="user-city">' + value + '</span>'
327                                });
328                            }
329                            if (citiesType === 'member') {
330                                $('.user-cities').html(outputCities)
331                            } else if (citiesType === 'competition') {
332                                $('.competition-cities').html(outputCities)
333                            }
334                        }
335
336                    }
337                });
338
339            } else {
340                $('#location-edit').addClass('required-field');
341            }
342
343        });
344
345
346        function citySelected() {
347            let citySel = $('.ff-location-select'),
348                entity_id = citySel.attr('data-entity_id'),
349                cityType = citySel.attr('data-city_type');
350
351            if (entity_id) {
352
353                $.ajax({
354                    url: ffscripts.ajaxUrl,
355                    type: 'POST',
356                    dataType: 'json',
357                    data: {
358                        action: 'city_selected',
359                        entity_id: entity_id,
360                        city_type: cityType
361                    },
362                    beforeSend: function () {
363                    },
364                    success: function (data) {
365
366                        $.each(data, function (index, value) {
367                            var option = new Option(value, value, true, true);
368                            citySel.append(option).trigger('change');
369                        });
370
371                    }
372                });
373
374            }
375        }
376
377        setTimeout(citySelected, 100);
378
379
380        $('.names-input').on('input', function () {
381            let reg = /[a-zA-Z]/g;
382            if (this.value.search(reg) != -1) {
383                this.value = this.value.replace(reg, '');
384
385                alert('Пожалуйста, используйте только кириллицу в этом поле');
386            }
387
388            let inputedName = $(this).val();
389
390            function titleCase(str) {
391                var splitStr = str.toLowerCase().split('-');
392                for (var i = 0; i < splitStr.length; i++) {
393                    splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1).toLowerCase();
394                }
395                return splitStr.join('-');
396            }
397
398            $(this).val(titleCase(inputedName))
399
400        })
401
402
403        let validatePhone = (phone) => {
404            return phone.match(
405                /^([+]?[0-9\s-\(\)]{3,25})*$/i
406            );
407        };
408
409
410        $('#phone-input').on('input', function () {
411
412            let phoneVal = $(this).val();
413            if (phoneVal) {
414                if (validatePhone(phoneVal) == null) {
415                    $("#phone-save").hide();
416                    $(this).css({'border': '1px solid #950d05', 'background': 'rgb(149 13 5 / 16%)'})
417                } else {
418                    $(this).css({'border': '1px solid #aaa', 'background': '#fff'})
419                    $("#phone-save").show();
420                }
421            }
422
423        })
424
425
426        $(document).on('change', function () {
427            validateStartEndDates()
428        })
429
430        validateStartEndDates()
431
432
433        function validateStartEndDates() {
434
435            const startInput = $('#start-date'),
436                endInput = $('#end-date');
437
438            let startDate = startInput.val(),
439                endDate = endInput.val();
440
441            if (endInput.length && startDate && endInput.hasClass('hasDatepicker')) {
442                endInput.datepicker("option", "minDate", startDate);
443            }
444
445            if ($('#event-form').length) return;
446
447            if (ffscripts.currentUserRole === 'administrator' || ffscripts.currentUserRole === 'editor' || ffscripts.currentUserRole === 'moderator') return;
448
449
450            if (startInput.length !== 0) {
451                startInput.datepicker("option", "minDate", "0");
452            }
453
454
455        }
456
457        if (  $('#birth-date').length !== 0 ) {
458
459            $('#birth-date').datepicker({
460                // minDate: "-100",
461                maxDate: "-16y",
462                numberOfMonths: [1, 1],
463                changeMonth: true,
464                changeYear: true,
465                yearRange: "-100:-16",
466                dateFormat: "dd.mm.yy"
467            });
468
469        }
470
471        $('#save-subscription-settings').on('click', function (){
472
473            const infoSubscriptionCheckbox = $('#info-subscription-checkbox'),
474                adsSubscriptionCheckbox = $('#ads-subscription-checkbox'),
475                saveBtn = $(this),
476                memberId = saveBtn.data('user_id');
477
478            let infoSubs = 1, adsSubs = 1;
479            if (infoSubscriptionCheckbox.is(':checked')) infoSubs = 1;
480            else infoSubs = 0;
481
482            if (adsSubscriptionCheckbox.is(':checked')) adsSubs = 1;
483            else adsSubs = 0;
484
485            $.ajax({
486                url: ffscripts.ajaxUrl,
487                type: 'POST',
488                data: {
489                    action: 'set_subscription_settings',
490                    info_subs: infoSubs,
491                    ads_subs: adsSubs,
492                    member_id: memberId
493                },
494                beforeSend: function () {
495                    saveBtn.text('Сохранение')
496                },
497                success: function (data) {
498
499                    saveBtn.text(data)
500                    setTimeout(function (){
501                        saveBtn.text('Сохранить')
502                    }, 3000)
503                }
504            });
505
506        })
507
508
509        // Стартовые листы
510
511        const editStartlist = $('#edit-startlist'),
512            saveStartlist = $('#save-startlist'),
513            startlistId = $('#startlist-table').attr('data-startlist_id'),
514            performanceDate = $('#startlist-table').attr('data-date');
515
516
517        editStartlist.on('click', function () {
518
519            $(this).addClass('ff-hidden');
520            saveStartlist.removeClass('ff-hidden');
521
522            $('.athlete-row').find('input, select').prop('disabled', false);
523            $('.js-set-intervals').find('input').prop('disabled', false);
524            $('.js-sorting-handle').addClass('sorting-handle');
525            $('.js-announcement-remove').removeClass('ff-hidden');
526
527        })
528
529        saveStartlist.on('click', function () {
530
531            $(this).addClass('ff-hidden')
532            editStartlist.removeClass('ff-hidden');
533
534            $('.athlete-row').find('input, select').prop('disabled', true);
535            $('.js-set-intervals').find('input').prop('disabled', true);
536            $('.js-sorting-handle').removeClass('sorting-handle');
537            $('.js-announcement-remove').addClass('ff-hidden');
538
539            changing_order();
540
541        })
542
543
544        $('#first-start-time, #set-interval').on('input', function () {     // Changing Primary startlist settings
545
546            let firstStartTime = new Date(performanceDate + 'T' + $('#first-start-time').val() + '+00:00') / 1000,
547                // let firstStartTime = Math.floor(new Date(performanceDate + 'T' + $('#first-start-time').val()).getTime() / 1000),
548                primaryInterval = $('#set-interval').val() * 60;
549
550            console.log('firstStartTime ' + $('#first-start-time').val())
551
552            $.ajax({
553                url: ffscripts.ajaxUrl,
554                type: 'POST',
555                data: {
556                    action: 'primary_interval_settings',
557                    first_start_time: firstStartTime,
558                    primary_interval: primaryInterval,
559                    startlist_id: startlistId
560                },
561                beforeSend: function (xhr) {
562                },
563                success: function (data) {
564                    console.log('done')
565                }
566            });
567
568            each_athlete_row()
569        })
570
571
572        function each_athlete_row(thisNum) {
573
574            if (thisNum) {
575                var startNum = thisNum - 1;
576            }
577
578            $('.athlete-row').each(function (index) {
579
580                if (thisNum > index) {
581                    return;
582                }
583
584
585                let fST = $('#first-start-time').val().split(':'),
586                    perfDate = performanceDate.split('-'),
587                    // firstStartTime = Date.UTC(perfDate[0], perfDate[1], perfDate[2], fST[0], fST[1]) / 1000,
588                    // firstStartTime = Math.floor(new Date(performanceDate + 'T' + $('#first-start-time').val() ).getTime() / 1000),
589                    firstStartTime = new Date(performanceDate + 'T' + $('#first-start-time').val() + '+00:00') / 1000,
590                    primaryStartInterval = $('#set-interval').val() * 60,
591                    athleteId = $(this).attr('data-athlete_id'),
592                    officialTop,
593                    setDirectly;
594
595
596                if (thisNum) {
597
598                    let thisTime = new Date(performanceDate + 'T' + $('#ot-' + thisNum).val() + '+00:00') / 1000,
599                        //thisTime =  Math.floor(new Date(performanceDate + 'T' +  $('#ot-' + thisNum ).val() ).getTime() / 1000),
600                        prevNum = thisNum - 1,
601                        prevTime = new Date(performanceDate + 'T' + $('#ot-' + prevNum).val() + '+00:00') / 1000,
602                        // prevTime =  Math.floor(new Date(performanceDate + 'T' +  $('#ot-' + prevNum ).val() ).getTime() / 1000),
603                        newInterval;
604
605
606                    if ($('.break-row').length !== 0) {
607                        // console.log($('.break-row').next('tr') )
608                        newInterval = primaryStartInterval;
609                        console.log(thisNum)
610                    } else {
611                        newInterval = thisTime - prevTime;
612                    }
613
614
615                    officialTop = thisTime + newInterval;
616
617                    thisNum++;
618
619                } else {
620
621                    startNum = $(this).find('.num-cell').attr('data-start_num') - 1;
622                    officialTop = firstStartTime + startNum * primaryStartInterval;
623
624                }
625
626                let date = new Date(officialTop * 1000),
627                    hours = date.getUTCHours(),
628                    minutes = date.getUTCMinutes();
629
630                if (hours < 10) {
631                    hours = "0" + hours;
632                }
633                if (minutes < 10) {
634                    minutes = "0" + minutes;
635                }
636                let formattedTime = hours + ':' + minutes;
637
638                setDirectly = $(this).find('.official-top').attr('data-set_directly');
639
640
641                if (!setDirectly) {
642                    $(this).find('.official-top').val(formattedTime)
643                } else {
644                    officialTop = setDirectly
645                }
646
647                setTimeout(set_official_top(athleteId, officialTop), 500)
648
649
650            })
651
652
653        }
654
655
656        $('.official-top').on('change input', function () {       // Change official top time directly
657
658            let athleteId = $(this).closest('tr').attr('data-athlete_id'),
659                officialTop = $(this).val() + '+00:00',
660                thisNum = $(this).closest('tr').find('.num-cell').attr('data-start_num'),
661                breakRow = $(this).closest('tr.break-row'); // TODO: убрать?
662
663
664            officialTop = Math.floor(new Date(performanceDate + 'T' + officialTop).getTime() / 1000);
665
666            // calculate_next_interval(thisNum);
667
668            // each_athlete_row(thisNum)
669
670            $(this).attr('data-set_directly', officialTop)
671
672            set_official_top(athleteId, officialTop);
673
674        })
675
676
677        function set_official_top(athleteId, officialTop) {
678
679            $('tr#athlete_id-' + athleteId).attr('data-official_top', officialTop)
680
681            $.ajax({
682                url: ffscripts.ajaxUrl,
683                type: 'POST',
684                data: {
685                    action: 'official_top',
686                    athlete_id: athleteId,
687                    startlist_id: startlistId,
688                    official_top: officialTop
689                },
690                beforeSend: function (xhr) {
691                },
692                success: function (data) {
693                    $('tr#athlete_id-' + athleteId).find('.official-top').val = data;
694                }
695            });
696
697            setTimeout(set_warmup_time(), 500)
698
699        }
700
701        UIkit.sortable('#startlist-table');
702
703        // $('#startlist-table').on('stop', function () {
704        //
705        //     setTimeout(changing_order, 300)
706        //
707        // })
708
709
710        function changing_order() {
711
712            let i = 1;
713
714            $('.num-cell').each(function () {
715
716
717                $(this).text(i).attr('data-start_num', i)
718
719                let athleteId = $(this).closest('tr').attr('data-athlete_id');
720
721
722                $.ajax({
723                    url: ffscripts.ajaxUrl,
724                    type: 'POST',
725                    data: {
726                        action: 'start_num',
727                        athlete_id: athleteId,
728                        startlist_id: startlistId,
729                        num: i
730                    },
731                    beforeSend: function (xhr) {
732                    },
733                    success: function (data) {
734                    }
735                });
736
737
738                i++;
739            })
740
741            setTimeout(each_athlete_row, 300)
742
743            // setTimeout(set_warmup_time(), 1500)
744
745        }
746
747
748        set_warmup_time()
749
750        function set_warmup_time() {
751
752            const warmupTime = $('#warmup-time').val() * 60;
753            const regTime = $('#reg-time').val() * 60;
754
755            $('.athlete-row').each(function () {
756                let officialTop = $(this).attr('data-official_top');
757                // console.log(Math.floor(new Date(performanceDate + ' ' + officialTop  ).getTime() / 1000))
758                // console.log( new Date(performanceDate.getDate() / 1000) + officialTop - warmupTime)
759
760                $(this).find('.warmup-time').text(formatted_time(officialTop - warmupTime))
761                $(this).find('.registration-time').text(formatted_time(officialTop - regTime))
762
763            })
764
765        }
766
767
768        function formatted_time(dt) {
769            let date = new Date(dt * 1000),
770                hours = date.getUTCHours(),
771                minutes = date.getUTCMinutes();
772
773            if (hours < 10) {
774                hours = "0" + hours;
775            }
776            if (minutes < 10) {
777                minutes = "0" + minutes;
778            }
779            let formattedTime = hours + ':' + minutes;
780
781            return formattedTime;
782        }
783
784        $('.add-break').click(function () {
785
786            let athleteId = $(this).closest('tr').attr('data-athlete_id'),
787                breakRow = '<tr class="break-row" id="break-after-' + athleteId + '"><td><span class="alert-icon remove-break" uk-icon="icon: minus-circle" data-athlete_id="' + athleteId + '"></span></td><td colspan="8">Перерыв</td></tr>';
788
789
790            $(this).closest('tr').after(breakRow)
791
792
793            $.ajax({
794                url: ffscripts.ajaxUrl,
795                type: 'POST',
796                data: {
797                    action: 'add_break',
798                    athlete_id: athleteId,
799                    startlist_id: startlistId,
800                },
801                beforeSend: function (xhr) {
802                },
803                success: function (data) {
804                }
805            });
806
807        });
808
809
810        $('.remove-break').click(function () {
811
812            let athleteId = $(this).attr('data-athlete_id');
813
814            $.ajax({
815                url: ffscripts.ajaxUrl,
816                type: 'POST',
817                data: {
818                    action: 'remove_break',
819                    athlete_id: athleteId,
820                    startlist_id: startlistId,
821                },
822                beforeSend: function (xhr) {
823                },
824                success: function (data) {
825
826                    $('#break-after-' + athleteId).remove();
827
828                }
829            });
830
831        });
832
833
834        $('.js-discipline-select-startlist, .js-input-ap, .js-input-pb, .js-input-dt, .js-start-zone').on('change input', function () {
835
836            console.log('fired')
837
838            let startNum = $(this).closest('tr').find('.num-cell').attr('data-start_num'),
839                officialTop = $(this).closest('tr').find('.official-top').val() + '+00:00',
840                discipline = $(this).closest('tr').find('.js-discipline-select-startlist').find(':selected').val(),
841                athleteId = $(this).closest('tr').attr('data-athlete_id'),
842                startlistId = $(this).closest('table').attr('data-startlist_id'),
843                announcedPerformance = $(this).closest('tr').find('.js-input-ap').val(),
844                personalBest = $(this).closest('tr').find('.js-input-pb').val(),
845                diveTime = $(this).closest('tr').find('.js-input-dt').val(),
846                startZone = $(this).closest('tr').find('.js-start-zone').find(':selected').val(),
847                notification = 'off';
848
849            officialTop = Math.floor(new Date(performanceDate + 'T' + officialTop).getTime() / 1000);
850
851            $.ajax({
852                url: ffscripts.ajaxUrl,
853                type: 'POST',
854                data: {
855                    action: 'set_announcement',
856                    athlete_id: athleteId,
857                    startlist_id: startlistId,
858                    announcement_discipline: discipline,
859                    announced_performance: announcedPerformance,
860                    personal_best: personalBest,
861                    estimated_time: diveTime,
862                    start_zone: startZone,
863                    official_top: officialTop,
864                    start_num: startNum,
865                    notification: notification
866                },
867                beforeSend: function (xhr) {
868                },
869                success: function (data) {
870                }
871            });
872
873        })
874
875
876        $('.js-remove-announcement').on('click', function () {
877
878            let athleteId = $(this).attr(('data-athlete_id')),
879                startlistId = $(this).attr(('data-startlist_id'));
880
881            $.ajax({
882                url: ffscripts.ajaxUrl,
883                type: 'POST',
884                data: {
885                    action: 'remove_announcement',
886                    athlete_id: athleteId,
887                    startlist_id: startlistId,
888                },
889                beforeSend: function (xhr) {
890                },
891                success: function (data) {
892                    if (data === 'success') {
893                        window.location.href = window.location.href;
894                    }
895                }
896            });
897
898        })
899
900
901        const startlistTable = document.querySelector("#startlist-table");
902
903        if (startlistTable) {
904
905            startlistTable.onclick = function (e) {
906
907                if (e.target.tagName != 'TH') return
908
909                let th = e.target
910
911                let sortDirection = th.getAttribute("data-sort-direction") === ">" ? "<" : ">";
912                th.setAttribute("data-sort-direction", sortDirection);
913
914                sortTable(th.cellIndex, th.dataset.type, sortDirection);
915
916            }
917
918        }
919
920
921        function sortTable(colNum, type, sortDirection) {
922
923            let tbody = startlistTable.querySelector('tbody'),
924                rowsArray = Array.from(tbody.rows),
925                compare;
926
927            switch (type) {
928                case 'number':
929                    compare = function (rowA, rowB) {
930
931                        if (sortDirection === '<') {
932          
932                  return Number(rowA.cells[colNum].getAttribute('data-announcement')) < Number(rowB.cells[colNum].getAttribute('data-announcement')) ? 1 : -1
933                        } else if (sortDirection === '>') {
934                            return Number(rowA.cells[colNum].getAttribute('data-announcement')) > Number(rowB.cells[colNum].getAttribute('data-announcement')) ? 1 : -1
935                        }
936
937                    }
938                    break;
939                case 'string':
940                    compare = function (rowA, rowB) {
941                        if (sortDirection === '<') {
942                            return rowA.cells[colNum].getAttribute('data-announcement') < rowB.cells[colNum].getAttribute('data-announcement') ? 1 : -1
943                        } else if (sortDirection === '>') {
944                            return rowA.cells[colNum].getAttribute('data-announcement') > rowB.cells[colNum].getAttribute('data-announcement') ? 1 : -1
945                        }
946                    }
947
948                    break;
949            }
950
951            rowsArray.sort(compare)
952            tbody.append(...rowsArray)
953
954            // setTimeout(changing_order, 300)
955
956        }
957
958
959        $('.js-ff-users-select').each(function () {
960
961            let userType = $(this).attr('data-user_type'),
962                plcHolder = $(this).attr('placeholder'),
963                userNotFound;
964
965            if (userType === 'instructor') {
966                // plcHolder = 'Инструкторы (есть профиль)';
967                userNotFound = 'Инструктор не найден';
968            } else if (userType === 'athlete') {
969                // plcHolder = 'Спортсмены';
970                userNotFound = 'Спортсмен не найден';
971            } else if (userType === 'organizer') {
972                // plcHolder = 'Организаторы';
973                userNotFound = 'Организатор не найден';
974            }
975
976            const multiple = $(this).attr('multiple') ? true : false;
977
978
979            $(this).select2({
980                multiple: multiple,
981                width: '100%',
982                // maximumSelectionLength: 2,
983                placeholder: plcHolder,
984                ajax: {
985                    url: ffscripts.ajaxUrl,
986                    dataType: 'json',
987                    delay: 250,
988                    data: function (params) {
989                        return {
990                            q: params.term, // search query
991                            // pf: pf,
992                            user_type: userType,
993                            action: 'ff_users_select'
994                        };
995                    },
996                    processResults: function (data) {
997                        console.log(data)
998                        var options = [];
999                        if (data) {
1000
1001                            // data is the array of arrays, and each of them contains ID and the Label of the option
1002                            $.each(data, function (index, text) { // do not forget that "index" is just auto incremented value
1003                                options.push({id: text[0], text: text[1]});
1004                            });
1005
1006                        }
1007                        return {
1008                            results: options
1009                        };
1010                    },
1011                    cache: true
1012                },
1013                minimumInputLength: 2,
1014                language: {
1015                    maximumSelected: function (e) {
1016
1017                    },
1018                    searching: function (e) {
1019                        return 'Ищем...';
1020                    },
1021                    noResults: function () {
1022                        return userNotFound;
1023                    },
1024                },
1025                placeholder: {
1026                    text: plcHolder
1027                }
1028
1029            });
1030
1031        });
1032
1033        $('#new-training-accordion li').removeClass('uk-open')
1034        $('#new-training-accordion .uk-accordion-content').prop('hidden', true)
1035
1036
1037        if (profileEdit) {
1038
1039            profileEdit.addEventListener('change', (event) => {
1040                checkProfileFilling()
1041            })
1042
1043            $('.ff-location-select').on('change', function () {
1044                checkProfileFilling()
1045            });
1046
1047        }
1048
1049
1050        $("#uploaded-instructor-certificate").on('classChange', function () {
1051            console.log('modified')
1052            checkProfileFilling()
1053        });
1054
1055
1056        function checkProfileFilling() {
1057
1058            const firstNameInput = document.getElementById('first_name-input'),
1059                patronymicInput = document.getElementById('patronymic-input'),
1060                lastNameInput = document.getElementById('last_name-input'),
1061                birthDateInput = document.getElementById('birth-date'),
1062                locationSelect = document.querySelector('#city-select-wrapper select'),
1063                genderRadio = document.querySelector('input[name=gender]'),
1064                phoneInput = document.getElementById('phone-input'),
1065                emailInput = document.getElementById('email-input'),
1066                instructorCheckbox = $('input#instructor'),
1067                uploadedInstructorCertificate = $('#uploaded-instructor-certificate'),
1068                saveProfileBtn = document.getElementById('save-profile-btn');
1069            // annualFeePaymentBtn = document.getElementById('annual-fee-payment-btn');
1070
1071            if (firstNameInput.value && patronymicInput.value && lastNameInput.value && phoneInput.value && emailInput.value && birthDateInput.value && genderRadio.value
1072                && locationSelect.value
1073                && (instructorCheckbox.is(':checked') && uploadedInstructorCertificate.hasClass('success') || !instructorCheckbox.is(':checked'))
1074            ) {
1075                saveProfileBtn.removeAttribute('disabled');
1076                // annualFeePaymentBtn.removeAttribute('disabled');
1077            } else {
1078                saveProfileBtn.setAttribute('disabled', 'disabled');
1079                // annualFeePaymentBtn.setAttribute('disabled', 'disabled');
1080            }
1081
1082        }
1083
1084
1085
1086        $('.announcement-discipline').each(function () {
1087            $(this).click(function () {
1088                let dayNum = $(this).attr('data-day'),
1089                    discipline = $(this).val();
1090                $(this).closest('.js-one-day').find('.athlete-announcement-form').addClass('ff-hidden');
1091                $('#form-day_' + dayNum + '-' + discipline).removeClass('ff-hidden');
1092
1093
1094                if ($(this).is(':checked')) {
1095
1096                    let discipline = $(this).val();
1097                    $('#form-day_' + dayNum + '-' + discipline).find('.announced_performance').on('input', function () {
1098
1099                        let announcedPerformance = $(this).val();
1100
1101                        if (discipline && announcedPerformance.length > 0 && announcedPerformance != 0 && announcedPerformance.match("_") === null) {
1102                            $(this).closest('form').find('.publish_announcement').prop('disabled', false)
1103                        } else {
1104                            $(this).closest('form').find('.publish_announcement').prop('disabled', true)
1105                        }
1106
1107                    });
1108
1109                }
1110
1111            })
1112        })
1113
1114
1115        $('.athlete-announcement-form').each(function () {
1116
1117            $(this).on('change, input', function () {
1118
1119                console.log('changing')
1120
1121                let discipline = $(this).find('input[name=announcement_discipline]').val(),
1122                    announcementDisciplineItem = $(this).closest('.js-one-day').find('input').filter(function () {
1123                        return $(this).val() === discipline
1124                    }),
1125                    announcedPerformance = $(this).find('.announced_performance').val(),
1126                    announcementBtn = $(this).find('.publish_announcement');
1127
1128                if (announcementDisciplineItem.is(':checked')) {
1129
1130                    if (discipline && announcedPerformance.length > 0 && announcedPerformance != 0 && announcedPerformance.match("_") === null) {
1131                        announcementBtn.prop('disabled', false)
1132                    } else {
1133                        announcementBtn.prop('disabled', true)
1134                    }
1135                }
1136
1137            })
1138
1139        })
1140
1141
1142        $('.publish_announcement').on('click', function (e) {
1143            e.preventDefault()
1144            let announcementFormData = $(this).closest('form').serialize();
1145
1146            console.log(announcementFormData)
1147
1148            $.ajax({
1149                url: ffscripts.ajaxUrl,
1150                type: 'POST',
1151                data: {
1152                    action: 'set_athlete_announcement',
1153                    params_string: announcementFormData,
1154                },
1155                beforeSend: function () {
1156                    $('.publish_announcement').prop('disabled', true)
1157                },
1158                success: function (data) {
1159                    window.location.reload();
1160                }
1161            })
1162
1163        })
1164
1165
1166        if ( $('#date-range').length !== 0 ) {
1167            $('#date-range').datepicker({
1168                range: 'period', // режим - выбор периода
1169                numberOfMonths: 1,
1170                onSelect: function (dateText, inst, extensionRange) {
1171                    // extensionRange - объект расширения
1172                    $('#date-range').val(extensionRange.startDateText + '-' + extensionRange.endDateText);
1173                    console.log(dateText)
1174                    console.log(inst)
1175                    console.log(extensionRange)
1176                }
1177            });
1178        }
1179
1180        $('#pdf-image-alignment span').on('click', function () {
1181
1182            $('#pdf-image-alignment span').removeClass('medium-blue-color')
1183            $(this).addClass('medium-blue-color')
1184
1185            const entityId = $(this).closest('.js-photo-wrapper').find('input').attr('data-entity_id')
1186            let alignment = $(this).attr('data-align')
1187
1188            if (alignment === 'left' || alignment == 'none') $(this).closest('.js-photo-wrapper').css('width', '100%')
1189            else $(this).closest('.js-photo-wrapper').css('width', 'auto')
1190
1191            $('#member-photo-holder').css('float', alignment)
1192
1193            $.ajax({
1194                url: ffscripts.ajaxUrl,
1195                type: 'POST',
1196                data: {
1197                    action: 'pdf_image_alignment',
1198                    float: alignment,
1199                    entity_id: entityId
1200                },
1201                success: function (data) {
1202                    console.log(data)
1203                }
1204            })
1205
1206        })
1207
1208
1209        if ($('#create-event').length !== 0) {
1210            $('#choose-event-type').on('change', function () {
1211                if ($(this).val() !== '') {
1212                    $('#create-event').prop('disabled', false)
1213                } else {
1214                    $('#create-event').prop('disabled', true)
1215                }
1216            })
1217        }
1218
1219
1220        $('.js-show-event-modal').on('click', function () {
1221            let eventId = $(this).data('event_id')
1222
1223            $.ajax({
1224                url: ffscripts.ajaxUrl,
1225                type: 'POST',
1226                data: {
1227                    action: 'views_count',
1228                    event_id: eventId
1229                },
1230                success: function (data) {
1231                    console.log(data)
1232                    $('.js-post-views-counter-' + eventId).text(data)
1233                }
1234            })
1235
1236        })
1237
1238
1239    });
1240});
1241
1242
1243document.addEventListener('DOMContentLoaded', function () {
1244
1245    let rowId = window.location.hash;
1246
1247    if (rowId) {
1248
1249        let targetRow = document.querySelector(rowId)
1250
1251        setTimeout(function () {
1252
1253            let offset = targetRow.getBoundingClientRect().top + window.scrollY;
1254
1255            window.scrollTo({
1256                top: offset - 180,
1257                behavior: 'smooth'
1258            });
1259
1260            setTimeout(function () {
1261                targetRow.style.backgroundColor = '#8f9fff47'
1262            }, 500)
1263
1264            setTimeout(function () {
1265                targetRow.style.backgroundColor = '#ffffff'
1266            }, 3600)
1267
1268        }, 50)
1269
1270    }
1271
1272
1273    const inputClear = document.querySelectorAll('.js-ff-input-clear');
1274    if (inputClear) {
1275        inputClear.forEach(element => {
1276            element.addEventListener('click', () => {
1277                element.previousElementSibling.value = ''
1278            })
1279        })
1280    }
1281
1282
1283})

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.