PageSourceSearch

https://progresso.rs.gov.br/site/custom/default/js/cookieconsent.js?v=1.1.0

js progresso.rs.gov.br collected 2026-10-02 20:50:53 UTC 95,828 bytes, 2,402 lines download raw bytes

1/*!
2 * ==============================================================
3 * NÃO EDITAR A MINIFICAÇÃO. O ARQUIVO ORIGINAL ESTÁ EM
4 * /home/eduardo/thirdParties/cookieconsent/src/cookieconsent.js
5 * ==============================================================
6 * 
7 * CookieConsent v2.9.0
8 * https://www.github.com/orestbida/cookieconsent
9 * Author Orest Bida
10 * Released under the MIT License
11 * Edited by:
12 * - Eduardo P. Gomez
13 */
14globalThis.VisaoiCookies = {
15    allowed: [],
16    denied: [],
17    /**
18     * @type {{[key: string]: Array<function>}}
19     */
20    stack: {},
21
22    /**
23     * 
24     * @param {string} category,
25     * @param {function} callback
26     */
27    onAllow(category,callback) {
28        if(!this.stack[category]) this.stack[category] = [];
29        this.stack[category].push(callback);
30    }
31};
32(function(){
33    'use strict';
34    /**
35     * @param {HTMLElement} [root] - [optional] element where the cookieconsent will be appended
36     * @returns {Object} cookieconsent object with API
37     */
38    var CookieConsent = function(root){
39
40        /**
41         * CHANGE THIS FLAG FALSE TO DISABLE console.log()
42         */
43        var ENABLE_LOGS = true;
44
45        var _config = {
46            'mode': 'opt-in',                         // 'opt-in', 'opt-out'
47            'current_lang': 'en',
48            'auto_language': null,
49            'autorun': true,                          // run as soon as loaded
50            'page_scripts': true,
51            'hide_from_bots': true,
52            'cookie_name': 'cc_cookie',
53            'cookie_expiration': 182,                 // default: 6 months (in days)
54            'cookie_domain': window.location.hostname,       // default: current domain
55            'cookie_path': '/',
56            'cookie_same_site': 'Lax',
57            'use_rfc_cookie': false,
58            'autoclear_cookies': true,
59            'revision': 0,
60            'script_selector': 'data-cookiecategory'
61        };
62        var subdomain = false;
63
64        var
65            /**
66             * Object which holds the main methods/API (.show, .run, ...)
67            */
68            _cookieconsent = {},
69
70            /**
71             * Global user configuration object
72             */
73            user_config,
74
75            /**
76             * Internal state variables
77             */
78            saved_cookie_content = {},
79            cookie_data = null,
80
81            /**
82             * @type {Date}
83             */
84            consent_date,
85
86            /**
87             * @type {Date}
88             */
89            last_consent_update,
90
91            /**
92             * @type {string}
93             */
94            consent_uuid,
95
96            /**
97             * @type {boolean}
98             */
99            invalid_consent = true,
100
101            consent_modal_exists = false,
102            consent_modal_visible = false,
103
104            settings_modal_visible = false,
105            clicked_inside_modal = false,
106            current_modal_focusable,
107
108            all_table_headers,
109            all_blocks,
110
111            // Helper callback functions
112            // (avoid calling "user_config['onAccept']" all the time)
113            onAccept,
114            onChange,
115            onFirstAction,
116
117            revision_enabled = false,
118            valid_revision = true,
119            revision_message = '',
120
121            // State variables for the autoclearCookies function
122            changed_settings = [],
123            reload_page = false;
124
125        /**
126         * Accept type:
127         *  - "all"
128         *  - "necessary"
129         *  - "custom"
130         * @type {string}
131         */
132        var accept_type;
133
134        /**
135         * Contains all accepted categories
136         * @type {string[]}
137         */
138        var accepted_categories = [];
139
140        /**
141         * Contains all non-accepted (rejected) categories
142         * @type {string[]}
143         */
144        var rejected_categories = [];
145
146        /**
147         * Contains all categories enabled by default
148         * @type {string[]}
149         */
150        var default_enabled_categories = [];
151
152        // Don't run plugin (to avoid indexing its text content) if bot detected
153        var is_bot = false;
154
155        /**
156         * Save reference to the last focused element on the page
157         * (used later to restore focus when both modals are closed)
158         */
159        var last_elem_before_modal;
160        var last_consent_modal_btn_focus;
161
162        /**
163         * Both of the arrays below have the same structure:
164         * [0] => holds reference to the FIRST focusable element inside modal
165         * [1] => holds reference to the LAST focusable element inside modal
166         */
167        var consent_modal_focusable = [];
168        var settings_modal_focusable = [];
169
170        /**
171         * Keep track of enabled/disabled categories
172         * @type {boolean[]}
173         */
174        var toggle_states = [];
175
176        /**
177         * Stores all available categories
178         * @type {string[]}
179         */
180        var all_categories = [];
181
182        /**
183         * Keep track of readonly toggles
184         * @type {boolean[]}
185         */
186        var readonly_categories = [];
187
188        /**
189         * Pointers to main dom elements (to avoid retrieving them later using document.getElementById)
190         */
191        var
192            /** @type {HTMLElement} */ html_dom = document.documentElement,
193            /** @type {HTMLElement} */ main_container,
194            /** @type {HTMLElement} */ all_modals_container,
195
196            /** @type {HTMLElement} */ consent_modal,
197            /** @type {HTMLElement} */ consent_modal_title,
198            /** @type {HTMLElement} */ consent_modal_description,
199            /** @type {HTMLElement} */ consent_primary_btn,
200            /** @type {HTMLElement} */ consent_secondary_btn,
201            /** @type {HTMLElement} */ consent_buttons,
202            /** @type {HTMLElement} */ consent_modal_inner,
203
204            /** @type {HTMLElement} */ settings_container,
205            /** @type {HTMLElement} */ settings_inner,
206            /** @type {HTMLElement} */ settings_title,
207            /** @type {HTMLElement} */ settings_close_btn,
208            /** @type {HTMLElement} */ settings_blocks,
209            /** @type {HTMLElement} */ new_settings_blocks,
210            /** @type {HTMLElement} */ settings_buttons,
211            /** @type {HTMLElement} */ settings_save_btn,
212            /** @type {HTMLElement} */ settings_accept_all_btn,
213            /** @type {HTMLElement} */ settings_reject_all_btn;
214
215        /**
216         * Update config settings
217         * @param {Object} user_config
218         */
219        var _setConfig = function(_user_config){
220
221            /**
222             * Make user configuration globally available
223             */
224            user_config = _user_config;
225
226            _log("CookieConsent [CONFIG]: received_config_settings ", user_config);
227
228            if(typeof user_config['cookie_expiration'] === "number")
229                _config.cookie_expiration = user_config['cookie_expiration'];
230
231            if(typeof user_config['cookie_necessary_only_expiration'] === "number")
232                _config.cookie_necessary_only_expiration  = user_config['cookie_necessary_only_expiration'];
233
234            if(typeof user_config['autorun'] === "boolean")
235                _config.autorun = user_config['autorun'];
236
237            if(typeof user_config['cookie_domain'] === "string")
238                _config.cookie_domain = user_config['cookie_domain'];
239
240            if(typeof user_config['cookie_same_site'] === "string")
241                _config.cookie_same_site = user_config['cookie_same_site'];
242
243            if(typeof user_config['cookie_path'] === "string")
244                _config.cookie_path = user_config['cookie_path'];
245
246            if(typeof user_config['cookie_name'] === "string")
247                _config.cookie_name = user_config['cookie_name'];
248
249            if(typeof user_config['onAccept'] === "function")
250                onAccept = user_config['onAccept'];
251
252            if(typeof user_config['onFirstAction'] === "function")
253                onFirstAction = user_config['onFirstAction'];
254
255            if(typeof user_config['onChange'] === "function")
256                onChange = user_config['onChange'];
257
258            if(user_config['mode'] === 'opt-out')
259                _config.mode = 'opt-out';
260
261            if(typeof user_config['revision'] === "number"){
262                user_config['revision'] > -1 && (_config.revision = user_config['revision']);
263                revision_enabled = true;
264            }
265
266            if(typeof user_config['autoclear_cookies'] === "boolean")
267                _config.autoclear_cookies = user_config['autoclear_cookies'];
268
269            if(user_config['use_rfc_cookie'] === true)
270                _config.use_rfc_cookie = true;
271
272            if(typeof user_config['hide_from_bots'] === "boolean"){
273                _config.hide_from_bots = user_config['hide_from_bots'];
274            }
275
276            if(_config.hide_from_bots){
277                is_bot = navigator &&
278                    ((navigator.userAgent && /bot|crawl|spider|slurp|teoma/i.test(navigator.userAgent)) || navigator.webdriver);
279            }
280
281            _config.page_scripts = user_config['page_scripts'] === true;
282
283            if (user_config['auto_language'] === 'browser' || user_config['auto_language'] === true) {
284                _config.auto_language = 'browser';
285            } else if (user_config['auto_language'] === 'document') {
286                _config.auto_language = 'document';
287            }
288
289            _log("CookieConsent [LANG]: auto_language strategy is '" + _config.auto_language + "'");
290
291            _config.current_lang = _resolveCurrentLang(user_config.languages, user_config['current_lang']);
292        }
293
294        /**
295         * Add an onClick listeners to all html elements with data-cc attribute
296         */
297        var _addDataButtonListeners = function(elem){
298
299            var _a = 'accept-';
300
301            var show_settings = _getElements('c-settings');
302            var accept_all = _getElements(_a + 'all');
303            var accept_necessary = _getElements(_a + 'necessary');
304            var accept_custom_selection = _getElements(_a + 'custom');
305
306            for(var i=0; i<show_settings.length; i++){
307                show_settings[i].setAttribute('aria-haspopup', 'dialog');
308                _addEvent(show_settings[i], 'click', function(event){
309                    event.preventDefault();
310                    _cookieconsent.showSettings(0);
311                });
312            }
313
314            for(i=0; i<accept_all.length; i++){
315                _addEvent(accept_all[i], 'click', function(event){
316                    _acceptAction(event, 'all');
317                });
318            }
319
320            for(i=0; i<accept_custom_selection.length; i++){
321                _addEvent(accept_custom_selection[i], 'click', function(event){
322                    _acceptAction(event);
323                });
324            }
325
326            for(i=0; i<accept_necessary.length; i++){
327                _addEvent(accept_necessary[i], 'click', function(event){
328                    _acceptAction(event, []);
329                });
330            }
331
332            /**
333             * Return all elements with given data-cc role
334             * @param {string} data_role
335             * @returns {NodeListOf<Element>}
336             */
337            function _getElements(data_role){
338                return (elem || document).querySelectorAll('a[data-cc="' + data_role + '"], button[data-cc="' + data_role + '"]');
339            }
340
341            /**
342             * Helper function: accept and then hide modals
343             * @param {PointerEvent} e source event
344             * @param {string} [accept_type]
345             */
346            function _acceptAction(e, accept_type){
347                e.preventDefault();
348                _cookieconsent.accept(accept_type);
349                _cookieconsent.hideSettings();
350                _cookieconsent.hide();
351            }
352        }
353
354        /**
355         * Get a valid language (at least 1 must be defined)
356         * @param {string} lang - desired language
357         * @param {Object} all_languages - all defined languages
358         * @returns {string} validated language
359         */
360        var _getValidatedLanguage = function(lang, all_languages){
361            if(Object.prototype.hasOwnProperty.call(all_languages, lang)){
362                return lang;
363            }else if(_getKeys(all_languages).length > 0){
364                if(Object.prototype.hasOwnProperty.call(all_languages, _config.current_lang)){
365                    return _config.current_lang ;
366                }else{
367                    return _getKeys(all_languages)[0];
368                }
369            }
370        }
371
372        /**
373         * Save reference to first and last focusable elements inside each modal
374         * to prevent losing focus while navigating with TAB
375         */
376        var _getModalFocusableData = function(){
377
378            /**
379             * Note: any of the below focusable elements, which has the attribute tabindex="-1" AND is either
380             * the first or last element of the modal, won't receive focus during "open/close" modal
381             */
382            var allowed_focusable_types = ['[href]', 'button', 'input', 'details', '[tabindex="0"]'];
383
384            function _getAllFocusableElements(modal, _array){
385                var focus_later=false, focus_first=false;
386
387                // ie might throw exception due to complex unsupported selector => a:not([tabindex="-1"])
388                try{
389                    var focusable_elems = modal.querySelectorAll(allowed_focusable_types.join(':not([tabindex="-1"]), '));
390                    var attr, len=focusable_elems.length, i=0;
391
392                    while(i < len){
393
394                        attr = focusable_elems[i].getAttribute('data-focus');
395
396                        if(!focus_first && attr === "1"){
397                            focus_first = focusable_elems[i];
398
399                        }else if(attr === "0"){
400                            focus_later = focusable_elems[i];
401                            if(!focus_first && focusable_elems[i+1].getAttribute('data-focus') !== "0"){
402                                focus_first = focusable_elems[i+1];
403                            }
404                        }
405
406                        i++;
407                    }
408
409                }catch(e){
410                    return modal.querySelectorAll(allowed_focusable_types.join(', '));
411                }
412
413                /**
414                 * Save first and last elements (used to lock/trap focus inside modal)
415                 */
416                _array[0] = focusable_elems[0];
417                _array[1] = focusable_elems[focusable_elems.length - 1];
418                _array[2] = focus_later;
419                _array[3] = focus_first;
420            }
421
422            /**
423             * Get settings modal'S all focusable elements
424             * Save first and last elements (used to lock/trap focus inside modal)
425             */
426            _getAllFocusableElements(settings_inner, settings_modal_focusable);
427
428            /**
429             * If consent modal exists, do the same
430             */
431            if(consent_modal_exists){
432                _getAllFocusableElements(consent_modal, consent_modal_focusable);
433            }
434        }
435
436        var _createConsentModal = function(lang){
437
438            if(user_config['force_consent'] === true)
439                _addClass(html_dom, 'force--consent');
440
441            // Create modal if it doesn't exist
442            if(!consent_modal){
443
444                consent_modal = _createNode('div');
445                var consent_modal_inner_inner = _createNode('div');
446                var overlay = _createNode('div');
447
448                consent_modal.id = 'cm';
449                consent_modal_inner_inner.id = 'c-inr-i';
450                overlay.id = 'cm-ov';
451
452                consent_modal.setAttribute('role', 'dialog');
453                consent_modal.setAttribute('aria-modal', 'true');
454                consent_modal.setAttribute('aria-hidden', 'false');
455                consent_modal.setAttribute('aria-labelledby', 'c-ttl');
456                consent_modal.setAttribute('aria-describedby', 'c-txt');
457
458                // Append consent modal to main container
459                all_modals_container.appendChild(consent_modal);
460                all_modals_container.appendChild(overlay);
461
462                /**
463                 * Make modal by default hidden to prevent weird page jumps/flashes (shown only once css is loaded)
464                 */
465                consent_modal.style.visibility = overlay.style.visibility = "hidden";
466                overlay.style.opacity = 0;
467            }
468
469            // Use insertAdjacentHTML instead of innerHTML
470            var consent_modal_title_value = user_config.languages[lang]['consent_modal']['title'];
471
472            // Add title (if valid)
473            if(consent_modal_title_value){
474
475                if(!consent_modal_title){
476                    consent_modal_title = _createNode('div');
477                    consent_modal_title.id = 'c-ttl';
478                    consent_modal_title.setAttribute('role', 'heading');
479                    consent_modal_title.setAttribute('aria-level', '2');
480                    consent_modal_inner_inner.appendChild(consent_modal_title);
481                }
482
483                consent_modal_title.innerHTML = consent_modal_title_value;
484            }
485
486            var description = user_config.languages[lang]['consent_modal']['description'];
487
488            if(revision_enabled){
489                if(!valid_revision){
490                    description = description.replace("{{revision_message}}", revision_message || user_config.languages[lang]['consent_modal']['revision_message'] || "");
491                }else{
492                    description = description.replace("{{revision_message}}", "");
493                }
494            }
495
496            if(!consent_modal_description){
497                consent_modal_description = _createNode('div');
498                consent_modal_description.id = 'c-txt';
499                consent_modal_inner_inner.appendChild(consent_modal_description);
500            }
501
502            // Set description content
503            consent_modal_description.innerHTML = description;
504
505            var primary_btn_data = user_config.languages[lang]['consent_modal']['primary_btn'],   // accept current selection
506                secondary_btn_data = user_config.languages[lang]['consent_modal']['secondary_btn'];
507
508            // Add primary button if not falsy
509            if(primary_btn_data){
510
511                if(!consent_primary_btn){
512                    consent_primary_btn = _createNode('button');
513                    consent_primary_btn.id = 'c-p-bn';
514                    consent_primary_btn.className =  "c-bn";
515
516                    var _accept_type;
517
518                    if(primary_btn_data['role'] === 'accept_all')
519                        _accept_type = 'all'
520
521                    _addEvent(consent_primary_btn, "click", function(){
522                        _cookieconsent.hide();
523                        _log("CookieConsent [ACCEPT]: cookie_consent was accepted!");
524                        _cookieconsent.accept(_accept_type);
525                    });
526                }
527
528                consent_primary_btn.innerHTML = user_config.languages[lang]['consent_modal']['primary_btn']['text'];
529            }
530
531            // Add secondary button if not falsy
532            if(secondary_btn_data){
533
534                if(!consent_secondary_btn){
535                    consent_secondary_btn = _createNode('button');
536                    consent_secondary_btn.id = 'c-s-bn';
537                    consent_secondary_btn.className = "c-bn c_link";
538
539                    if(secondary_btn_data['role'] === 'accept_necessary'){
540                        _addEvent(consent_secondary_btn, 'click', function(){
541                            _cookieconsent.hide();
542                            _cookieconsent.accept([]); // accept necessary only
543                        });
544                    }else{
545                        _addEvent(consent_secondary_btn, 'click', function(){
546                            _cookieconsent.showSettings(0);
547                        });
548                    }
549                }
550
551                consent_secondary_btn.innerHTML = user_config.languages[lang]['consent_modal']['secondary_btn']['text'];
552            }
553
554            // Swap buttons
555            var gui_options_data = user_config['gui_options'];
556
557            if(!consent_modal_inner){
558                consent_modal_inner = _createNode('div');
559                consent_modal_inner.id = 'c-inr';
560
561                consent_modal_inner.appendChild(consent_modal_inner_inner);
562            }
563
564            if(!consent_buttons){
565                consent_buttons = _createNode('div');
566                consent_buttons.id = "c-bns";
567
568                if(gui_options_data && gui_options_data['consent_modal'] && gui_options_data['consent_modal']['swap_buttons'] === true){
569                    secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn);
570                    primary_btn_data && consent_buttons.appendChild(consent_primary_btn);
571                    consent_buttons.className = 'swap';
572                }else{
573                    primary_btn_data && consent_buttons.appendChild(consent_primary_btn);
574                    secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn);
575                }
576
577                (primary_btn_data || secondary_btn_data ) && consent_modal_inner.appendChild(consent_buttons);
578                consent_modal.appendChild(consent_modal_inner);
579            }
580
581            consent_modal_exists = true;
582
583            _addDataButtonListeners(consent_modal_inner);
584        }
585
586        var _createSettingsModal = function(lang){
587
588            /**
589             * Create all consent_modal elements
590             */
591            if(!settings_container){
592                settings_container = _createNode('div');
593                var settings_container_valign = _createNode('div');
594                var settings = _createNode('div');
595                var settings_container_inner = _createNode('div');
596                settings_inner = _createNode('div');
597                settings_title = _createNode('div');
598                var settings_header = _createNode('div');
599                settings_close_btn = _createNode('button');
600                var settings_close_btn_container = _createNode('div');
601                settings_blocks = _createNode('div');
602                var overlay = _createNode('div');
603
604                /**
605                 * Set ids
606                 */
607                settings_container.id = 's-cnt';
608                settings_container_valign.id = "c-vln";
609                settings_container_inner.id = "c-s-in";
610                settings.id = "cs";
611                settings_title.id = 's-ttl';
612                settings_inner.id = 's-inr';
613                settings_header.id = "s-hdr";
614                settings_blocks.id = 's-bl';
615                settings_close_btn.id = 's-c-bn';
616                overlay.id = 'cs-ov';
617                settings_close_btn_container.id = 's-c-bnc';
618                settings_close_btn.className = 'c-bn';
619
620                settings_container.setAttribute('role', 'dialog');
621                settings_container.setAttribute('aria-modal', 'true');
622                settings_container.setAttribute('aria-hidden', 'true');
623                settings_container.setAttribute('aria-labelledby', 's-ttl');
624                settings_title.setAttribute('role', 'heading');
625                settings_container.style.visibility = overlay.style.visibility = "hidden";
626                overlay.style.opacity = 0;
627
628                settings_close_btn_container.appendChild(settings_close_btn);
629
630                // If 'esc' key is pressed inside settings_container div => hide settings
631                _addEvent(settings_container_valign, 'keydown', function(evt){
632                    evt = evt || window.event;
633                    if (evt.keyCode === 27) {
634                        _cookieconsent.hideSettings(0);
635                    }
636                }, true);
637
638                _addEvent(settings_close_btn, 'click', function(){
639                    _cookieconsent.hideSettings(0);
640                });
641            }else{
642                new_settings_blocks = _createNode('div');
643                new_settings_blocks.id = 's-bl';
644            }
645
646            // Add label to close button
647            settings_close_btn.setAttribute('aria-label', user_config.languages[lang]['settings_modal']['close_btn_label'] || 'Close');
648
649            all_blocks = user_config.languages[lang]['settings_modal']['blocks'];
650            all_table_headers = user_config.languages[lang]['settings_modal']['cookie_table_headers'];
651
652            var n_blocks = all_blocks.length;
653
654            // Set settings modal title
655            settings_title.innerHTML = user_config.languages[lang]['settings_modal']['title'];
656
657            // Create settings modal content (blocks)
658            for(var i=0; i<n_blocks; ++i){
659
660                var title_data = all_blocks[i]['title'],
661                    description_data = all_blocks[i]['description'],
662                    toggle_data = all_blocks[i]['toggle'],
663                    cookie_table_data = all_blocks[i]['cookie_table'],
664                    remove_cookie_tables = user_config['remove_cookie_tables'] === true,
665                    isExpandable = (description_data && 'truthy') || (!remove_cookie_tables && (cookie_table_data && 'truthy'));
666
667                // Create title
668                var block_section = _createNode('div');
669                var block_table_container = _createNode('div');
670
671                // Create description
672                if(description_data){
673                    var block_desc = _createNode('div');
674                    block_desc.className = 'p';
675                    block_desc.insertAdjacentHTML('beforeend', description_data);
676                }
677
678                var block_title_container = _createNode('div');
679                block_title_container.className = 'title';
680
681                block_section.className = 'c-bl';
682                block_table_container.className = 'desc';
683
684                // Create toggle if specified (opt in/out)
685                if(typeof toggle_data !== 'undefined'){
686
687                    var accordion_id = "c-ac-"+i;
688
689                    // Create button (to collapse/expand block description)
690                    var block_title_btn = isExpandable ? _createNode('button') : _createNode('div');
691                    var block_switch_label = _createNode('label');
692                    var block_switch = _createNode('input');
693                    var block_switch_span = _createNode('span');
694                    var label_text_span = _createNode('span');
695
696                    // These 2 spans will contain each 2 pseudo-elements to generate 'tick' and 'x' icons
697                    var block_switch_span_on_icon = _createNode('span');
698                    var block_switch_span_off_icon = _createNode('span');
699
700                    block_title_btn.className = isExpandable ? 'b-tl exp' : 'b-tl';
701                    block_switch_label.className = 'b-tg';
702                    block_switch.className = 'c-tgl';
703                    block_switch_span_on_icon.className = 'on-i';
704                    block_switch_span_off_icon.className = 'off-i';
705                    block_switch_span.className = 'c-tg';
706                    label_text_span.className = "t-lb";
707
708                    if(isExpandable){
709                        block_title_btn.setAttribute('aria-expanded', 'false');
710                        block_title_btn.setAttribute('aria-controls', accordion_id);
711                    }
712
713                    block_switch.type = 'checkbox';
714                    block_switch_span.setAttribute('aria-hidden', 'true');
715
716                    var cookie_category = toggle_data.value;
717                    block_switch.value = cookie_category;
718
719                    label_text_span.textContent = title_data;
720                    block_title_btn.insertAdjacentHTML('beforeend', title_data);
721
722                    block_title_container.appendChild(block_title_btn);
723                    block_switch_span.appendChild(block_switch_span_on_icon);
724                    block_switch_span.appendChild(block_switch_span_off_icon);
725
726                    /**
727                     * If consent is valid => retrieve category states from cookie
728                     * Otherwise use states defined in the user_config. object
729                     */
730                    if(!invalid_consent){
731                        if(_inArray(saved_cookie_content['categories'], cookie_category) > -1){
732                            block_switch.checked = true;
733                            !new_settings_blocks && toggle_states.push(true);
734                        }else{
735                            !new_settings_blocks && toggle_states.push(false);
736                        }
737                    }else if(toggle_data['enabled']){
738                        block_switch.checked = true;
739                        !new_settings_blocks && toggle_states.push(true);
740
741                        /**
742                         * Keep track of categories enabled by default (useful when mode=='opt-out')
743                         */
744                        if(toggle_data['enabled'])
745                            !new_settings_blocks && default_enabled_categories.push(cookie_category);
746
747                    }else{
748                        !new_settings_blocks && toggle_states.push(false);
749                    }
750
751                    !new_settings_blocks && all_categories.push(cookie_category);
752
753                    /**
754                     * Set toggle as readonly if true (disable checkbox)
755                     */
756                    if(toggle_data['readonly']){
757                        block_switch.disabled = true;
758                        _addClass(block_switch_span, 'c-ro');
759                        !new_settings_blocks && readonly_categories.push(true);
760                    }else{
761                        !new_settings_blocks && readonly_categories.push(false);
762                    }
763
764                    _addClass(block_table_container, 'b-acc');
765                    _addClass(block_title_container, 'b-bn');
766                    _addClass(block_section, 'b-ex');
767
768                    block_table_container.id = accordion_id;
769                    block_table_container.setAttribute('aria-hidden', 'true');
770
771                    block_switch_label.appendChild(block_switch);
772                    block_switch_label.appendChild(block_switch_span);
773                    block_switch_label.appendChild(label_text_span);
774                    block_title_container.appendChild(block_switch_label);
775
776                    /**
777                     * On button click handle the following :=> aria-expanded, aria-hidden and act class for current block
778                     */
779                    isExpandable && (function(accordion, block_section, btn){
780                        _addEvent(block_title_btn, 'click', function(){
781                            if(!_hasClass(block_section, 'act')){
782                                _addClass(block_section, 'act');
783                                btn.setAttribute('aria-expanded', 'true');
784                                accordion.setAttribute('aria-hidden', 'false');
785                            }else{
786                                _removeClass(block_section, 'act');
787                                btn.setAttribute('aria-expanded', 'false');
788                                accordion.setAttribute('aria-hidden', 'true');
789                            }
790                        }, false);
791                    })(block_table_container, block_section, block_title_btn);
792
793                }else{
794                    /**
795                     * If block is not a button (no toggle defined),
796                     * create a simple div instead
797                     */
798                    if(title_data){
799                        var block_title = _createNode('div');
800                        block_title.className = 'b-tl';
801                        block_title.setAttribute('role', 'heading');
802                        block_title.setAttribute('aria-level', '3');
803                        block_title.insertAdjacentHTML('beforeend', title_data);
804                        block_title_container.appendChild(block_title);
805                    }
806                }
807
808                title_data && block_section.appendChild(block_title_container);
809                description_data && block_table_container.appendChild(block_desc);
810
811                // if cookie table found, generate table for this block
812                if(!remove_cookie_tables && typeof cookie_table_data !== 'undefined'){
813                    var tr_tmp_fragment = document.createDocumentFragment();
814
815                    /**
816                     * Use custom table headers
817                     */
818                    for(var p=0; p<all_table_headers.length; ++p){
819                        // create new header
820                        var th1 = _createNode('th');
821                        var obj = all_table_headers[p];
822                        th1.setAttribute('scope', 'col');
823
824                        // get custom header content
825                        if(obj){
826                            var new_column_key = obj && _getKeys(obj)[0];
827                            th1.textContent = all_table_headers[p][new_column_key];
828                            tr_tmp_fragment.appendChild(th1);
829                        }
830                    }
831
832                    var tr_tmp = _createNode('tr');
833                    tr_tmp.appendChild(tr_tmp_fragment);
834
835                    // create table header & append fragment
836                    var thead = _createNode('thead');
837                    thead.appendChild(tr_tmp);
838
839                    // append header to table
840                    var block_table = _createNode('table');
841                    block_table.appendChild(thead);
842
843                    var tbody_fragment = document.createDocumentFragment();
844
845                    // create table content
846                    for(var n=0; n<cookie_table_data.length; n++){
847                        var tr = _createNode('tr');
848
849                        for(var g=0; g<all_table_headers.length; ++g){
850                            // get custom header content
851                            obj = all_table_headers[g];
852                            if(obj){
853                                new_column_key = _getKeys(obj)[0];
854
855                                var td_tmp = _createNode('td');
856
857                                // Allow html inside table cells
858                                td_tmp.insertAdjacentHTML('beforeend', cookie_table_data[n][new_column_key]);
859                                td_tmp.setAttribute('data-column', obj[new_column_key]);
860
861                                tr.appendChild(td_tmp);
862                            }
863                        }
864
865                        tbody_fragment.appendChild(tr);
866                    }
867
868                    // append tbody_fragment to tbody & append the latter into the table
869                    var tbody = _createNode('tbody');
870                    tbody.appendChild(tbody_fragment);
871                    block_table.appendChild(tbody);
872
873                    block_table_container.appendChild(block_table);
874                }
875
876                /**
877                 * Append only if is either:
878                 * - togglable div with title
879                 * - a simple div with at least a title or description
880                 */
881                if(toggle_data && title_data || (!toggle_data && (title_data || description_data))){
882                    block_section.appendChild(block_table_container);
883
884                    if(new_settings_blocks)
885                        new_settings_blocks.appendChild(block_section);
886                    else
887                        settings_blocks.appendChild(block_section);
888                }
889            }
890
891            // Create settings buttons
892            if(!settings_buttons){
893                settings_buttons = _createNode('div');
894                settings_buttons.id = 's-bns';
895            }
896
897            if(!settings_accept_all_btn){
898                settings_accept_all_btn = _createNode('button');
899                settings_accept_all_btn.id = 's-all-bn';
900                settings_accept_all_btn.className ='c-bn';
901                settings_buttons.appendChild(settings_accept_all_btn);
902
903                _addEvent(settings_accept_all_btn, 'click', function(){
904                    _cookieconsent.hideSettings();
905                    _cookieconsent.hide();
906                    _cookieconsent.accept('all');
907                });
908            }
909
910            settings_accept_all_btn.innerHTML = user_config.languages[lang]['settings_modal']['accept_all_btn'];
911
912            var reject_all_btn_text = user_config.languages[lang]['settings_modal']['reject_all_btn'];
913
914            // Add third [optional] reject all button if provided
915            if(reject_all_btn_text){
916
917                if(!settings_reject_all_btn){
918                    settings_reject_all_btn = _createNode('button');
919                    settings_reject_all_btn.id = 's-rall-bn';
920                    settings_reject_all_btn.className = 'c-bn';
921
922                    _addEvent(settings_reject_all_btn, 'click', function(){
923                        _cookieconsent.hideSettings();
924                        _cookieconsent.hide();
925                        _cookieconsent.accept([]);
926                    });
927
928                    settings_inner.className = "bns-t";
929                    settings_buttons.appendChild(settings_reject_all_btn);
930                }
931
932                settings_reject_all_btn.innerHTML = reject_all_btn_text;
933            }
934
935
936            if(!settings_save_btn){
937                settings_save_btn = _createNode('button');
938                settings_save_btn.id = 's-sv-bn';
939                settings_save_btn.className ='c-bn';
940                settings_buttons.appendChild(settings_save_btn);
941
942                // Add save preferences button onClick event
943                // Hide both settings modal and consent modal
944                _addEvent(settings_save_btn, 'click', function(){
945                    _cookieconsent.hideSettings();
946                    _cookieconsent.hide();
947                    _cookieconsent.accept();
948                });
949            }
950
951            settings_save_btn.innerHTML = user_config.languages[lang]['settings_modal']['s
951ave_settings_btn'];
952
953
954            if(new_settings_blocks) {
955                // replace entire existing cookie category blocks with the new cookie categories new blocks (in a different language)
956                settings_inner.replaceChild(new_settings_blocks, settings_blocks);
957                settings_blocks = new_settings_blocks;
958                return;
959            };
960
961            settings_header.appendChild(settings_title);
962            settings_header.appendChild(settings_close_btn_container);
963            settings_inner.appendChild(settings_header);
964            settings_inner.appendChild(settings_blocks);
965            settings_inner.appendChild(settings_buttons);
966            settings_container_inner.appendChild(settings_inner);
967
968            settings.appendChild(settings_container_inner);
969            settings_container_valign.appendChild(settings);
970            settings_container.appendChild(settings_container_valign);
971
972            all_modals_container.appendChild(settings_container);
973            all_modals_container.appendChild(overlay);
974        }
975
976        /**
977         * Generate cookie consent html markup
978         */
979        var _createCookieConsentHTML = function(){
980
981            // Create main container which holds both consent modal & settings modal
982            main_container = _createNode('div');
983            main_container.id = 'cc--main';
984
985            // Fix layout flash
986            main_container.style.position = "fixed";
987            main_container.style.zIndex = "2147483647";
988            main_container.innerHTML = '<!--[if lt IE 9 ]><div id="cc_div" class="cc_div ie"></div><![endif]--><!--[if (gt IE 8)|!(IE)]><!--><div id="cc_div" class="cc_div"></div><!--<![endif]-->'
989            all_modals_container = main_container.children[0];
990
991            // Get current language
992            var lang = _config.current_lang;
993
994            // Create consent modal
995            if(consent_modal_exists)
996                _createConsentModal(lang);
997
998            // Always create settings modal
999            _createSettingsModal(lang);
1000
1001            // Finally append everything (main_container holds both modals)
1002            (root || document.body).appendChild(main_container);
1003        }
1004
1005        /**
1006         * Update/change modals language
1007         * @param {String} lang new language
1008         * @param {Boolean} [force] update language fields forcefully
1009         * @returns {Boolean}
1010         */
1011        _cookieconsent.updateLanguage = function(lang, force){
1012
1013            if(typeof lang !== 'string') return;
1014
1015            /**
1016             * Validate language to avoid errors
1017             */
1018            var new_validated_lang = _getValidatedLanguage(lang, user_config.languages);
1019
1020            /**
1021             * Set language only if it differs from current
1022             */
1023            if(new_validated_lang !== _config.current_lang || force === true){
1024                _config.current_lang = new_validated_lang;
1025
1026                if(consent_modal_exists){
1027                    _createConsentModal(new_validated_lang);
1028                }
1029
1030                _createSettingsModal(new_validated_lang);
1031
1032                _log("CookieConsent [LANGUAGE]: curr_lang: '" + new_validated_lang + "'");
1033
1034                return true;
1035            }
1036
1037            return false;
1038        }
1039
1040        /**
1041         * Delete all cookies which are unused (based on selected preferences)
1042         *
1043         * @param {boolean} [clearOnFirstAction]
1044         */
1045        var _autoclearCookies = function(clearOnFirstAction){
1046
1047            // Get number of blocks
1048            var len = all_blocks.length;
1049            var count = -1;
1050
1051            // reset reload state
1052            reload_page = false;
1053
1054            // Retrieve all cookies
1055            var all_cookies_array = _getCookie('', 'all');
1056
1057            // delete cookies on 'www.domain.com' and '.www.domain.com' (can also be without www)
1058            var domains = [_config.cookie_domain, '.'+_config.cookie_domain];
1059
1060            // if domain has www, delete cookies also for 'domain.com' and '.domain.com'
1061            if(_config.cookie_domain.slice(0, 4) === 'www.'){
1062                var non_www_domain = _config.cookie_domain.substr(4);  // remove first 4 chars (www.)
1063                domains.push(non_www_domain);
1064                domains.push('.' + non_www_domain);
1065            }
1066
1067            // For each block
1068            for(var i=0; i<len; i++){
1069
1070                // Save current block (local scope & less accesses -> ~faster value retrieval)
1071                var curr_block = all_blocks[i];
1072
1073                // If current block has a toggle for opt in/out
1074                if(Object.prototype.hasOwnProperty.call(curr_block, "toggle")){
1075
1076                    // if current block has a cookie table, an off toggle,
1077                    // and its preferences were just changed => delete cookies
1078                    var category_just_disabled = _inArray(changed_settings, curr_block['toggle']['value']) > -1;
1079                    if(
1080                        !toggle_states[++count] &&
1081                        Object.prototype.hasOwnProperty.call(curr_block, "cookie_table") &&
1082                        (clearOnFirstAction || category_just_disabled)
1083                    ){
1084                        var curr_cookie_table = curr_block['cookie_table'];
1085
1086                        // Get first property name
1087                        var ckey = _getKeys(all_table_headers[0])[0];
1088
1089                        // Get number of cookies defined in cookie_table
1090                        var clen = curr_cookie_table.length;
1091
1092                        // set "reload_page" to true if reload=on_disable
1093                        if(curr_block['toggle']['reload'] === 'on_disable')
1094                            category_just_disabled && (reload_page = true);
1095
1096                        // for each row defined in the cookie table
1097                        for(var j=0; j<clen; j++){
1098                            var curr_domains = domains;
1099
1100                            // Get current row of table (corresponds to all cookie params)
1101                            var curr_row = curr_cookie_table[j], found_cookies = [];
1102                            var curr_cookie_name = curr_row[ckey];
1103                            var is_regex = curr_row['is_regex'] || false;
1104                            var curr_cookie_domain = curr_row['domain'] || null;
1105                            var curr_cookie_path = curr_row['path'] || false;
1106
1107                            // set domain to the specified domain
1108                            curr_cookie_domain && ( curr_domains = [curr_cookie_domain, '.'+curr_cookie_domain]);
1109
1110                            // If regex provided => filter cookie array
1111                            if(is_regex){
1112                                for(var n=0; n<all_cookies_array.length; n++){
1113                                    if(all_cookies_array[n].match(curr_cookie_name)){
1114                                        found_cookies.push(all_cookies_array[n]);
1115                                    }
1116                                }
1117                            }else{
1118                                var found_index = _inArray(all_cookies_array, curr_cookie_name);
1119                                if(found_index > -1) found_cookies.push(all_cookies_array[found_index]);
1120                            }
1121
1122                            _log("CookieConsent [AUTOCLEAR]: search cookie: '" + curr_cookie_name + "', found:", found_cookies);
1123
1124                            // If cookie exists -> delete it
1125                            if(found_cookies.length > 0){
1126                                _eraseCookies(found_cookies, curr_cookie_path, curr_domains);
1127                                curr_block['toggle']['reload'] === 'on_clear' && (reload_page = true);
1128                            }
1129                        }
1130                    }
1131                }
1132            }
1133        }
1134
1135        /**
1136         * Set toggles/checkboxes based on accepted categories and save cookie
1137         * @param {string[]} accepted_categories - Array of categories to accept
1138         */
1139        var _saveCookiePreferences = function(accepted_categories){
1140            // (@visaoi)
1141            VisaoiCookies.allowed = [];
1142            VisaoiCookies.denied = [];
1143
1144            changed_settings = [];
1145
1146            // Retrieve all toggle/checkbox values
1147            var category_toggles = document.querySelectorAll('.c-tgl') || [];
1148
1149            // If there are opt in/out toggles ...
1150            if(category_toggles.length > 0){
1151
1152                for(var i=0; i<category_toggles.length; i++){
1153                    if(_inArray(accepted_categories, all_categories[i]) !== -1){
1154                        VisaoiCookies.allowed.push(all_categories[i]);
1155
1156                        let stack = VisaoiCookies.stack[all_categories[i]];
1157
1158                        if(stack){
1159                            for(let j=0; j<stack.length; j++){
1160                                stack[j]();
1161                            }
1162                        }
1163
1164                        category_toggles[i].checked = true;
1165                        if(!toggle_states[i]){
1166                            changed_settings.push(all_categories[i]);
1167                            toggle_states[i] = true;
1168                        }
1169                    }else{
1170                        VisaoiCookies.denied.push(all_categories[i]);
1171                        category_toggles[i].checked = false;
1172                        if(toggle_states[i]){
1173                            changed_settings.push(all_categories[i]);
1174                            toggle_states[i] = false;
1175                        }
1176                    }
1177                }
1178            }
1179
1180            /**
1181             * Clear cookies when settings/preferences change
1182             */
1183            if(!invalid_consent && _config.autoclear_cookies && changed_settings.length > 0)
1184                _autoclearCookies();
1185
1186            if(!consent_date) consent_date = new Date();
1187            if(!consent_uuid) consent_uuid = _uuidv4();
1188
1189            saved_cookie_content = {
1190                "categories": accepted_categories,
1191                "level": accepted_categories, // Copy of the `categories` property for compatibility purposes with version v2.8.0 and below.
1192                "revision": _config.revision,
1193                "data": cookie_data,
1194                "rfc_cookie": _config.use_rfc_cookie,
1195                "consent_date": consent_date.toISOString(),
1196                "consent_uuid": consent_uuid
1197            }
1198
1199            // save cookie with preferences 'categories' (only if never accepted or settings were updated)
1200            if(invalid_consent || changed_settings.length > 0){
1201                valid_revision = true;
1202
1203                /**
1204                 * Update "last_consent_update" only if it is invalid (after t)
1205                 */
1206                if(!last_consent_update)
1207                    last_consent_update = consent_date;
1208                else
1209                    last_consent_update = new Date();
1210
1211                saved_cookie_content['last_consent_update'] = last_consent_update.toISOString();
1212
1213                /**
1214                 * Update accept type
1215                 */
1216                accept_type = _getAcceptType(_getCurrentCategoriesState());
1217
1218                _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content));
1219                _manageExistingScripts();
1220            }
1221
1222            if(invalid_consent){
1223
1224                /**
1225                 * Delete unused/"zombie" cookies if consent is not valid (not yet expressed or cookie has expired)
1226                 */
1227                if(_config.autoclear_cookies)
1228                    _autoclearCookies(true);
1229
1230                if(typeof onFirstAction === 'function')
1231                    onFirstAction(_cookieconsent.getUserPreferences(), saved_cookie_content);
1232
1233                if(typeof onAccept === 'function')
1234                    onAccept(saved_cookie_content);
1235
1236                /**
1237                 * Set consent as valid
1238                 */
1239                invalid_consent = false;
1240
1241                if(_config.mode === 'opt-in') return;
1242            }
1243
1244            // fire onChange only if settings were changed
1245            if(typeof onChange === "function" && changed_settings.length > 0)
1246                onChange(saved_cookie_content, changed_settings);
1247
1248            /**
1249             * reload page if needed
1250             */
1251            _deleteDeniedCookies();
1252            
1253            if(reload_page)
1254                window.location.reload();
1255        }
1256
1257        /**
1258         * Returns index of found element inside array, otherwise -1
1259         * @param {Array} arr
1260         * @param {Object} value
1261         * @returns {number}
1262         */
1263        var _inArray = function(arr, value){
1264            return arr.indexOf(value);
1265        }
1266
1267        /**
1268         * Helper function which prints info (console.log())
1269         * @param {Object} print_msg
1270         * @param {Object} [optional_param]
1271         */
1272        var _log = function(print_msg, optional_param, error) {
1273            if (ENABLE_LOGS) {
1274                !error ?
1275                    console.log(print_msg, optional_param !== undefined ? optional_param : ' ') :
1276                    console.error(print_msg, optional_param || "");
1277            }
1278        }
1279
1280        /**
1281         * Helper function which creates an HTMLElement object based on 'type' and returns it.
1282         * @param {string} type
1283         * @returns {HTMLElement}
1284         */
1285        var _createNode = function(type){
1286            var el = document.createElement(type);
1287            if(type === 'button'){
1288                el.setAttribute('type', type);
1289            }
1290            return el;
1291        }
1292
1293        /**
1294         * Generate RFC4122-compliant UUIDs.
1295         * https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid?page=1&tab=votes#tab-top
1296         * @returns {string}
1297         */
1298        var _uuidv4 = function(){
1299            return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, function(c){
1300                try{
1301                    return (c ^ (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
1302                }catch(e){
1303                    return '';
1304                }
1305            });
1306        }
1307
1308        /**
1309         * Resolve which language should be used.
1310         *
1311         * @param {Object} languages Object with language translations
1312         * @param {string} [requested_language] Language specified by given configuration parameters
1313         * @returns {string}
1314         */
1315        var _resolveCurrentLang = function (languages, requested_language) {
1316
1317            if (_config.auto_language === 'browser') {
1318                return _getValidatedLanguage(_getBrowserLang(), languages);
1319            } else if (_config.auto_language === 'document') {
1320                return _getValidatedLanguage(document.documentElement.lang, languages);
1321            } else {
1322                if (typeof requested_language === 'string') {
1323                    return _config.current_lang = _getValidatedLanguage(requested_language, languages);
1324                }
1325            }
1326
1327            _log("CookieConsent [LANG]: setting current_lang = '" + _config.current_lang + "'");
1328            return _config.current_lang; // otherwise return default
1329        }
1330
1331        /**
1332         * Get current client's browser language
1333         * @returns {string}
1334         */
1335        var _getBrowserLang = function(){
1336            var browser_lang = navigator.language || navigator.browserLanguage;
1337            browser_lang.length > 2 && (browser_lang = browser_lang[0]+browser_lang[1]);
1338            _log("CookieConsent [LANG]: detected_browser_lang = '"+ browser_lang + "'");
1339            return browser_lang.toLowerCase()
1340        }
1341
1342        /**
1343         * Trap focus inside modal and focus the first
1344         * focusable element of current active modal
1345         */
1346        var _handleFocusTrap = function(){
1347            var tabbedOutsideDiv = false;
1348            var tabbedInsideModal = false;
1349
1350            _addEvent(document, 'keydown', function(e){
1351                e = e || window.event;
1352
1353                // If is tab key => ok
1354                if(e.key !== 'Tab') return;
1355
1356                // If there is any modal to focus
1357                if(current_modal_focusable){
1358                    // If reached natural end of the tab sequence => restart
1359                    if(e.shiftKey){
1360                        if (document.activeElement === current_modal_focusable[0]) {
1361                            current_modal_focusable[1].focus();
1362                            e.preventDefault();
1363                        }
1364                    }else{
1365                        if (document.activeElement === current_modal_focusable[1]) {
1366                            current_modal_focusable[0].focus();
1367                            e.preventDefault();
1368                        }
1369                    }
1370
1371                    // If have not yet used tab (or shift+tab) and modal is open ...
1372                    // Focus the first focusable element
1373                    if(!tabbedInsideModal && !clicked_inside_modal){
1374                        tabbedInsideModal = true;
1375                        !tabbedOutsideDiv && e.preventDefault();
1376
1377                        if(e.shiftKey){
1378                            if(current_modal_focusable[3]){
1379                                if(!current_modal_focusable[2]){
1380                                    current_modal_focusable[0].focus();
1381                                }else{
1382                                    current_modal_focusable[2].focus();
1383                                }
1384                            }else{
1385                                current_modal_focusable[1].focus();
1386                            }
1387                        }else{
1388                            if(current_modal_focusable[3]){
1389                                current_modal_focusable[3].focus();
1390                            }else{
1391                                current_modal_focusable[0].focus();
1392                            }
1393                        }
1394                    }
1395                }
1396
1397                !tabbedInsideModal && (tabbedOutsideDiv = true);
1398            });
1399
1400            if(document.contains){
1401                _addEvent(main_container, 'click', function(e){
1402                    e = e || window.event;
1403                    /**
1404                     * If click is on the foreground overlay (and not inside settings_modal),
1405                     * hide settings modal
1406                     *
1407                     * Notice: click on div is not supported in IE
1408                     */
1409                    if(settings_modal_visible){
1410                        if(!settings_inner.contains(e.target)){
1411                            _cookieconsent.hideSettings(0);
1412                            clicked_inside_modal = false;
1413                        }else{
1414                            clicked_inside_modal = true;
1415                        }
1416                    }else if(consent_modal_visible){
1417                        if(consent_modal.contains(e.target)){
1418                            clicked_inside_modal = true;
1419                        }
1420                    }
1421
1422                }, true);
1423            }
1424        }
1425
1426        /**
1427         * (@visaoi)
1428         * Helper function which deletes cookies which its categories is in VisaoiCookie.denied
1429         */
1430        var _deleteDeniedCookies = () => {
1431            console.log("Hora de comer!");
1432            // delete cookies which its categories is in VisaoiCookie.denied (@visaoi)
1433            let blocks = user_config.languages.en.settings_modal.blocks;
1434            for (let x = 0; x < blocks.length; x++) {
1435                if (
1436                    blocks[x].cookie_table &&
1437                    blocks[x].toggle
1438                ) {
1439                    console.log("Quero biscoitos de sabor '" + blocks[x].toggle.value + "'");
1440                    let cookies = blocks[x].cookie_table;
1441
1442                    //get list of cookies to delete with regex
1443                    let allCookieNames = document.cookie.split(';');
1444                    allCookieNames = allCookieNames.map(cookie => cookie
1445                        .split('=')[0]
1446                        .replace(/\s+/g, ''));
1447
1448                    console.log("All cookies: ", allCookieNames);
1449
1450                    for (let y = 0; y < cookies.length; y++) {
1451                        if (VisaoiCookies.denied.includes(blocks[x].toggle.value)) {    
1452                            //delete blocks[x].cookie_table.col1 from blocks[x].cookie_table;
1453                            if (cookies[y].regex) {
1454                                let cookies_to_delete = allCookieNames.filter(cookie => {
1455                                    const regex =new RegExp(cookies[y].col1.replace(/\*$/g, '[A-Za-z0-9\\!\\#\\$\\%\\&\\\'\\*\\+\\-\\.\\^_\\`\\|\\~]*'),'g');
1456                                    
1457                                    return regex.test(cookie);
1458                                });
1459                                
1460                                console.log(cookies[y].col1, ">",cookies[y].col1.replace(/\*$/g, '[A-Za-z0-9\\!\\#\\$\\%\\&\\\'\\*\\+\\-\\.\\^_\\`\\|\\~]*'));
1461                                console.log("Cookies to delete: ", cookies_to_delete);
1462                                _eraseCookies(cookies_to_delete);
1463                            } else {
1464                                console.log("Deletando",cookies[y]);
1465                                _eraseCookies([cookies[y].col1]);
1466                            }
1467                        }
1468                    }
1469                }
1470            }
1471        }
1472
1473        /**
1474         * Manage each modal's layout
1475         * @param {Object} gui_options
1476         */
1477        var _guiManager = function(gui_options, only_consent_modal){
1478
1479            // If gui_options is not object => exit
1480            if(typeof gui_options !== 'object') return;
1481
1482            var consent_modal_options = gui_options['consent_modal'];
1483            var settings_modal_options = gui_options['settings_modal'];
1484
1485            /**
1486             * Helper function which adds layout and
1487             * position classes to given modal
1488             *
1489             * @param {HTMLElement} modal
1490             * @param {string[]} allowed_layouts
1491             * @param {string[]} allowed_positions
1492             * @param {string} layout
1493             * @param {string[]} position
1494             */
1495            function _setLayout(modal, allowed_layouts, allowed_positions, allowed_transitions, layout, position, transition){
1496                position = (position && position.split(" ")) || [];
1497
1498                // Check if specified layout is valid
1499                if(_inArray(allowed_layouts, layout) > -1){
1500
1501                    // Add layout classes
1502                    _addClass(modal, layout);
1503
1504                    // Add position class (if specified)
1505                    if(!(layout === 'bar' && position[0] === 'middle') && _inArray(allowed_positions, position[0]) > -1){
1506                        for(var i=0; i<position.length; i++){
1507                            _addClass(modal, position[i]);
1508                        }
1509                    }
1510                }
1511
1512                // Add transition class
1513                (_inArray(allowed_transitions, transition) > -1) && _addClass(modal, transition);
1514            }
1515
1516            if(consent_modal_exists && consent_modal_options){
1517                _setLayout(
1518                    consent_modal,
1519                    ['box', 'bar', 'cloud'],
1520                    ['top', 'middle', 'bottom'],
1521                    ['zoom', 'slide'],
1522                    consent_modal_options['layout'],
1523                    consent_modal_options['position'],
1524                    consent_modal_options['transition']
1525                );
1526            }
1527
1528            if(!only_consent_modal && settings_modal_options){
1529                _setLayout(
1530                    settings_container,
1531                    ['bar'],
1532                    ['left', 'right'],
1533                    ['zoom', 'slide'],
1534                    settings_modal_options['layout'],
1535                    settings_modal_options['position'],
1536                    settings_modal_options['transition']
1537                );
1538            }
1539        }
1540
1541        /**
1542         * Returns true if cookie category is accepted by the user
1543         * @param {string} cookie_category
1544         * @returns {boolean}
1545         */
1546        _cookieconsent.allowedCategory = function(cookie_category){
1547
1548            if(!invalid_consent || _config.mode === 'opt-in')
1549                var allowed_categories = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || '{}')['categories'] || []
1550            else  // mode is 'opt-out'
1551                var allowed_categories = default_enabled_categories;
1552
1553            return _inArray(allowed_categories, cookie_category) > -1;
1554        }
1555
1556        /**
1557         * "Init" method. Will run once and only if modals do not exist
1558         * 
1559         * @param {{
1560         *  page_scripts: boolean,
1561         *  gui_options: Object,
1562         *  languages: {
1563         *    "en": {
1564         *      consent_modal: Object,
1565         *      settings_modal: {
1566         *        blocks: Array<{
1567         *          toggle?: {value:string},
1568         *          cookie_table?: Array<{
1569         *            col1: string, //nome
1570         *            col2: string, //dominio
1571         *            col3: string, //expiracao
1572         *            col4: string, //descricao
1573         *            regex: boolean
1574         *          }>
1575         *        }>,
1576         *      }
1577         *    }
1578         *  }
1579         * }} user_config
1580         */
1581        _cookieconsent.run = function(user_config, bypass=false, isSubdomain=false) {
1582            //or is www
1583            subdomain = isSubdomain || window.location.hostname.split('.')[0] === 'www';
1584
1585            // Ignora o consentimento e executa todos os scripts
1586            if (bypass) {
1587                document.querySelectorAll('script[data-src]').forEach(function (script) {
1588                    var src = script.getAttribute('data-src');
1589                    script.setAttribute('src', src);
1590                    script.removeAttribute('data-src');
1591                });
1592                return;
1593            }
1594
1595            if(!document.getElementById('cc_div')){
1596
1597                // configure all parameters
1598                _setConfig(user_config);
1599
1600                // if is bot, don't run plugin
1601                if(is_bot) return;
1602
1603                // Retrieve cookie value (if set)
1604                saved_cookie_content = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}");
1605
1606                // Retrieve "consent_uuid"
1607                consent_uuid = saved_cookie_content['consent_uuid'];
1608
1609                // If "consent_uuid" is present => assume that consent was previously given
1610                var cookie_consent_accepted = consent_uuid !== undefined;
1611
1612                // Retrieve "consent_date"
1613                consent_date = saved_cookie_content['consent_date'];
1614                consent_date && (consent_date = new Date(consent_date));
1615
1616                // Retrieve "last_consent_update"
1617                last_consent_update = saved_cookie_content['last_consent_update'];
1618                last_consent_update && (last_consent_update = new Date(last_consent_update));
1619
1620                // Retrieve "data"
1621                cookie_data = saved_cookie_content['data'] !== undefined ? saved_cookie_content['data'] : null;
1622
1623                // If revision is enabled and current value !== saved value inside the cookie =>
1623 revision is not valid
1624                if(revision_enabled && saved_cookie_content['revision'] !== _config.revision){
1625                    valid_revision = false;
1626                }
1627
1628                // If consent is not valid => create consent modal
1629                consent_modal_exists = invalid_consent = (!cookie_consent_accepted || !valid_revision || !consent_date || !last_consent_update || !consent_uuid);
1630
1631                //merge saved_cookie_content["categories"] with VisaoiCookie.allowed
1632                VisaoiCookies.allowed = [...VisaoiCookies.allowed, ...(saved_cookie_content["categories"] || [])] || [];
1633                VisaoiCookies.allowed = VisaoiCookies.allowed.filter(function (item, pos) {
1634                    return VisaoiCookies.allowed.indexOf(item) === pos;
1635                });
1636
1637                //denied coolies are every category except allowed
1638                user_config.languages["en"].settings_modal.blocks.forEach(block => {
1639                    if (block.toggle) {
1640                        //if array has item
1641                        if (!VisaoiCookies.allowed.includes(block.toggle.value)) {
1642                            VisaoiCookies.denied.push(block.toggle.value);
1643                        }
1644                    }
1645                })
1646
1647                _deleteDeniedCookies();
1648
1649                // Generate cookie-settings dom (& consent modal)
1650                _createCookieConsentHTML();
1651
1652                _getModalFocusableData();
1653                _guiManager(user_config['gui_options']);
1654                _addDataButtonListeners();
1655
1656                if(_config.autorun && consent_modal_exists){
1657                    _cookieconsent.show(user_config['delay'] || 0);
1658                }
1659
1660                // Add class to enable animations/transitions
1661                setTimeout(function(){_addClass(main_container, 'c--anim');}, 30);
1662
1663                // Accessibility :=> if tab pressed => trap focus inside modal
1664                setTimeout(function(){_handleFocusTrap();}, 100);
1665
1666                // If consent is valid
1667                if(!invalid_consent){
1668                    var rfc_prop_exists = typeof saved_cookie_content['rfc_cookie'] === "boolean";
1669
1670                    /*
1671                     * Convert cookie to rfc format (if `use_rfc_cookie` is enabled)
1672                     */
1673                    if(!rfc_prop_exists || (rfc_prop_exists && saved_cookie_content['rfc_cookie'] !== _config.use_rfc_cookie)){
1674                        saved_cookie_content['rfc_cookie'] = _config.use_rfc_cookie;
1675                        _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content));
1676                    }
1677
1678                    /**
1679                     * Update accept type
1680                     */
1681                    accept_type = _getAcceptType(_getCurrentCategoriesState());
1682
1683                    _manageExistingScripts();
1684
1685                    if(typeof onAccept === 'function')
1686                        onAccept(saved_cookie_content);
1687
1688                    _log("CookieConsent [NOTICE]: consent already given!", saved_cookie_content);
1689
1690                }else{
1691                    if(_config.mode === 'opt-out'){
1692                        _log("CookieConsent [CONFIG] mode='" + _config.mode + "', default enabled categories:", default_enabled_categories);
1693                        _manageExistingScripts(default_enabled_categories);
1694                    }
1695                    _log("CookieConsent [NOTICE]: ask for consent!");
1696                }
1697            }else{
1698                _log("CookieConsent [NOTICE]: cookie consent already attached to body!");
1699            }
1700        }
1701
1702        /**
1703         * Show settings modal (with optional delay)
1704         * @param {number} delay
1705         */
1706        _cookieconsent.showSettings = function(delay){
1707            setTimeout(function() {
1708                _addClass(html_dom, "show--settings");
1709                settings_container.setAttribute('aria-hidden', 'false');
1710                document.getElementById("c-vln").style.backdropFilter = "blur(10px)";
1711                document.getElementsByTagName("html")[0].style.overflow = "hidden";
1712                settings_modal_visible = true;
1713
1714                /**
1715                 * Set focus to the first focusable element inside settings modal
1716                 */
1717                setTimeout(function(){
1718                    // If there is no consent-modal, keep track of the last focused elem.
1719                    if(!consent_modal_visible){
1720                        last_elem_before_modal = document.activeElement;
1721                    }else{
1722                        last_consent_modal_btn_focus = document.activeElement;
1723                    }
1724
1725                    if (settings_modal_focusable.length === 0) return;
1726
1727                    if(settings_modal_focusable[3]){
1728                        settings_modal_focusable[3].focus();
1729                    }else{
1730                        settings_modal_focusable[0].focus();
1731                    }
1732                    current_modal_focusable = settings_modal_focusable;
1733                }, 200);
1734
1735                _log("CookieConsent [SETTINGS]: show settings_modal");
1736            }, delay > 0 ? delay : 0);
1737        }
1738
1739        /**
1740         * This function handles the loading/activation logic of the already
1741         * existing scripts based on the current accepted cookie categories
1742         *
1743         * @param {string[]} [must_enable_categories]
1744         */
1745        var _manageExistingScripts = function(must_enable_categories){
1746
1747            if(!_config.page_scripts) return;
1748
1749            // get all the scripts with "cookie-category" attribute
1750            var scripts = document.querySelectorAll('script[' + _config.script_selector + ']');
1751            var accepted_categories = must_enable_categories || saved_cookie_content['categories'] || [];
1752
1753            /**
1754             * Load scripts (sequentially), using a recursive function
1755             * which loops through the scripts array
1756             * @param {Element[]} scripts scripts to load
1757             * @param {number} index current script to load
1758             */
1759            var _loadScripts = function(scripts, index){
1760                if(index < scripts.length){
1761
1762                    var curr_script = scripts[index];
1763                    var curr_script_category = curr_script.getAttribute(_config.script_selector);
1764
1765                    /**
1766                     * If current script's category is on the array of categories
1767                     * accepted by the user => load script
1768                     */
1769                    if(_inArray(accepted_categories, curr_script_category) > -1){
1770
1771                        curr_script.type = 'text/javascript';
1772                        curr_script.removeAttribute(_config.script_selector);
1773
1774                        // get current script data-src
1775                        var src = curr_script.getAttribute('data-src');
1776
1777                        // some scripts (like ga) might throw warning if data-src is present
1778                        src && curr_script.removeAttribute('data-src');
1779
1780                        // create fresh script (with the same code)
1781                        var fresh_script = _createNode('script');
1782                        fresh_script.textContent = curr_script.innerHTML;
1783
1784                        // Copy attributes over to the new "revived" script
1785                        (function(destination, source){
1786                            var attributes = source.attributes;
1787                            var len = attributes.length;
1788                            for(var i=0; i<len; i++){
1789                                var attr_name = attributes[i].nodeName;
1790                                destination.setAttribute(attr_name , source[attr_name] || source.getAttribute(attr_name));
1791                            }
1792                        })(fresh_script, curr_script);
1793
1794                        // set src (if data-src found)
1795                        src ? (fresh_script.src = src) : (src = curr_script.src);
1796
1797                        // if script has "src" attribute
1798                        // try loading it sequentially
1799                        if(src){
1800                            // load script sequentially => the next script will not be loaded
1801                            // until the current's script onload event triggers
1802                            if(fresh_script.readyState) {  // only required for IE <9
1803                                fresh_script.onreadystatechange = function() {
1804                                    if (fresh_script.readyState === "loaded" || fresh_script.readyState === "complete" ) {
1805                                        fresh_script.onreadystatechange = null;
1806                                        _loadScripts(scripts, ++index);
1807                                    }
1808                                };
1809                            }else{  // others
1810                                fresh_script.onload = function(){
1811                                    fresh_script.onload = null;
1812                                    _loadScripts(scripts, ++index);
1813                                };
1814                            }
1815                        }
1816
1817                        // Replace current "sleeping" script with the new "revived" one
1818                        curr_script.parentNode.replaceChild(fresh_script, curr_script);
1819
1820                        /**
1821                         * If we managed to get here and scr is still set, it means that
1822                         * the script is loading/loaded sequentially so don't go any further
1823                         */
1824                        if(src) return;
1825                    }
1826
1827                    // Go to next script right away
1828                    _loadScripts(scripts, ++index);
1829                }
1830            }
1831
1832            _loadScripts(scripts, 0);
1833        }
1834
1835        /**
1836         * Save custom data inside cookie
1837         * @param {object|string} new_data
1838         * @param {string} [mode]
1839         * @returns {boolean}
1840         */
1841        var _setCookieData = function(new_data, mode){
1842
1843            var set = false;
1844            /**
1845             * If mode is 'update':
1846             * add/update only the specified props.
1847             */
1848            if(mode === 'update'){
1849                cookie_data = _cookieconsent.get('data');
1850                var same_type = typeof cookie_data === typeof new_data;
1851
1852                if(same_type && typeof cookie_data === "object"){
1853                    !cookie_data && (cookie_data = {});
1854
1855                    for(var prop in new_data){
1856                        if(cookie_data[prop] !== new_data[prop]){
1857                            cookie_data[prop] = new_data[prop]
1858                            set = true;
1859                        }
1860                    }
1861                }else if((same_type || !cookie_data) && cookie_data !== new_data){
1862                    cookie_data = new_data;
1863                    set = true;
1864                }
1865            }else{
1866                cookie_data = new_data;
1867                set = true;
1868            }
1869
1870            if(set){
1871                saved_cookie_content['data'] = cookie_data;
1872                _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content));
1873            }
1874
1875            return set;
1876        }
1877
1878        /**
1879         * Helper method to set a variety of fields
1880         * @param {string} field
1881         * @param {object} data
1882         * @returns {boolean}
1883         */
1884        _cookieconsent.set = function(field, data){
1885            switch(field){
1886                case 'data': return _setCookieData(data['value'], data['mode']);
1887                default: return false;
1888            }
1889        }
1890
1891        /**
1892         * Retrieve data from existing cookie
1893         * @param {string} field
1894         * @param {string} [cookie_name]
1895         * @returns {any}
1896         */
1897        _cookieconsent.get = function(field, cookie_name){
1898            var cookie = JSON.parse(_getCookie(cookie_name || _config.cookie_name, 'one', true) || "{}");
1899
1900            return cookie[field];
1901        }
1902
1903        /**
1904         * Read current configuration value
1905         * @returns {any}
1906         */
1907        _cookieconsent.getConfig = function(field){
1908            return _config[field] || user_config[field];
1909        }
1910
1911        /**
1912         * Obtain accepted and rejected categories
1913         * @returns {{accepted: string[], rejected: string[]}}
1914         */
1915        var _getCurrentCategoriesState = function(){
1916
1917            // get accepted categories
1918            accepted_categories = saved_cookie_content['categories'] || [];
1919
1920            // calculate rejected categories (all_categories - accepted_categories)
1921            rejected_categories = all_categories.filter(function(category){
1922                return (_inArray(accepted_categories, category) === -1);
1923            });
1924
1925            return {
1926                accepted: accepted_categories,
1927                rejected: rejected_categories
1928            }
1929        }
1930
1931        /**
1932         * Calculate "accept type" given current categories state
1933         * @param {{accepted: string[], rejected: string[]}} currentCategoriesState
1934         * @returns {string}
1935         */
1936        var _getAcceptType = function(currentCategoriesState){
1937
1938            var type = 'custom';
1939
1940            // number of categories marked as necessary/readonly
1941            var necessary_categories_length = readonly_categories.filter(function(readonly){
1942                return readonly === true;
1943            }).length;
1944
1945            // calculate accept type based on accepted/rejected categories
1946            if(currentCategoriesState.accepted.length === all_categories.length)
1947                type = 'all';
1948            else if(currentCategoriesState.accepted.length === necessary_categories_length)
1949                type = 'necessary'
1950
1951            return type;
1952        }
1953
1954        /**
1955         * @typedef {object} userPreferences
1956         * @property {string} accept_type
1957         * @property {string[]} accepted_categories
1958         * @property {string[]} rejected_categories
1959         */
1960
1961        /**
1962         * Retrieve current user preferences (summary)
1963         * @returns {userPreferences}
1964         */
1965        _cookieconsent.getUserPreferences = function(){
1966            var currentCategoriesState = _getCurrentCategoriesState();
1967            var accept_type = _getAcceptType(currentCategoriesState);
1968
1969            return {
1970                'accept_type': accept_type,
1971                'accepted_categories': currentCategoriesState.accepted,
1972                'rejected_categories': currentCategoriesState.rejected
1973            }
1974        }
1975
1976        /**
1977         * Function which will run after script load
1978         * @callback scriptLoaded
1979         */
1980
1981        /**
1982         * Dynamically load script (append to head)
1983         * @param {string} src
1984         * @param {scriptLoaded} callback
1985         * @param {object[]} [attrs] Custom attributes
1986         */
1987        _cookieconsent.loadScript = function(src, callback, attrs){
1988
1989            var function_defined = typeof callback === 'function';
1990
1991            // Load script only if not already loaded
1992            if(!document.querySelector('script[src="' + src + '"]')){
1993
1994                var script = _createNode('script');
1995
1996                // if an array is provided => add custom attributes
1997                if(attrs && attrs.length > 0){
1998                    for(var i=0; i<attrs.length; ++i){
1999                        attrs[i] && script.setAttribute(attrs[i]['name'], attrs[i]['value']);
2000                    }
2001                }
2002
2003                // if callback function defined => run callback onload
2004                if(function_defined){
2005                    script.onload = callback;
2006                }
2007
2008                script.src = src;
2009
2010                /**
2011                 * Append script to head
2012                 */
2013                document.head.appendChild(script);
2014            } else {
2015                function_defined && callback();
2016            }
2017
2018            /**
2019             * check if "cc_cookie" cookie exists
2020             */
2021            /*if(_getCookie(_config.cookie_name, 'one', true)) {
2022                /**
2023                 * manage iframes
2024                 * /
2025                document.querySelectorAll('iframe[data-src]').forEach(function(iframe) {
2026                    //if cookie category is accepted...
2027                    if (_inArray(accepted_categories, iframe.getAttribute('data-category')) !== -1) {
2028                        iframe.src = iframe.getAttribute('data-src');
2029                    }
2030                });
2031            }*/
2032        }
2033
2034        /**
2035         * Manage dynamically loaded scripts: https://github.com/orestbida/cookieconsent/issues/101
2036         * If plugin has already run, call this method to enable
2037         * the newly added scripts based on currently selected preferences
2038         */
2039        _cookieconsent.updateScripts = function(){
2040            _manageExistingScripts();
2041        }
2042
2043        /**
2044         * Show cookie consent modal (with delay parameter)
2045         * @param {number} [delay]
2046         * @param {boolean} [create_modal] create modal if it doesn't exist
2047         */
2048        _cookieconsent.show = function(delay, create_modal){
2049
2050            if(create_modal === true)
2051                _createConsentModal(_config.current_lang);
2052
2053            if(consent_modal_exists){
2054                setTimeout(function() {
2055                    _addClass(html_dom, "show--consent");
2056
2057                    /**
2058                     * Update attributes/internal statuses
2059                     */
2060                    consent_modal.setAttribute('aria-hidden', 'false');
2061                    consent_modal_visible = true;
2062
2063                    setTimeout(function(){
2064                        last_elem_before_modal = document.activeElement;
2065                        current_modal_focusable = consent_modal_focusable;
2066                    }, 200);
2067
2068                    _log("CookieConsent [MODAL]: show consent_modal");
2069                }, delay > 0 ? delay : (create_modal ? 30 : 0));
2070            }
2071        }
2072
2073        /**
2074         * Hide consent modal
2075         */
2076        _cookieconsent.hide = function(){
2077            if(consent_modal_exists){
2078                _removeClass(html_dom, "show--consent");
2079                consent_modal.setAttribute('aria-hidden', 'true');
2080                consent_modal_visible = false;
2081
2082                setTimeout(function(){
2083                    //restore focus to the last page element which had focus before modal opening
2084                    last_elem_before_modal.focus();
2085                    current_modal_focusable = null;
2086                }, 200);
2087
2088                _log("CookieConsent [MODAL]: hide");
2089            }
2090        }
2091
2092        /**
2093         * Hide settings modal
2094         */
2095        _cookieconsent.hideSettings = function(){
2096            _removeClass(html_dom, "show--settings");
2097            settings_modal_visible = false;
2098            document.getElementById("c-vln").style.backdropFilter = "unset";
2099            settings_container.setAttribute('aria-hidden', 'true');
2100            document.getElementsByTagName("html")[0].style.overflow = "";
2101
2102
2103            setTimeout(function(){
2104                /**
2105                 * If consent modal is visible, focus him (instead of page document)
2106                 */
2107                if(consent_modal_visible){
2108                    last_consent_modal_btn_focus && last_consent_modal_btn_focus.focus();
2109                    current_modal_focusable = consent_modal_focusable;
2110                }else{
2111                    /**
2112                     * Restore focus to last page element which had focus before modal opening
2113                     */
2114                    last_elem_before_modal && last_elem_before_modal.focus();
2115                    current_modal_focusable = null;
2116                }
2117
2118                clicked_inside_modal = false;
2119            }, 200);
2120
2121            _log("CookieConsent [SETTINGS]: hide settings_modal");
2122        }
2123
2124        /**
2125         * Accept cookieconsent function API
2126         * @param {string[]|string} _categories - Categories to accept
2127         * @param {string[]} [_exclusions] - Excluded categories [optional]
2128         */
2129        _cookieconsent.accept = function(_categories, _exclusions){
2130            var categories = _categories || undefined;
2131            var exclusions = _exclusions || [];
2132            var to_accept = [];
2133
2134            /**
2135             * Get all accepted categories
2136             * @returns {string[]}
2137             */
2138            var _getCurrentPreferences = function(){
2139                var toggles = document.querySelectorAll('.c-tgl') || [];
2140                var states = [];
2141
2142                for(var i=0; i<toggles.length; i++){
2143                    if(toggles[i].checked){
2144                        states.push(toggles[i].value);
2145                    }
2146                }
2147                return states;
2148            }
2149
2150            if(!categories){
2151                to_accept = _getCurrentPreferences();
2152            }else{
2153                if(
2154                    typeof categories === "object" &&
2155                    typeof categories.length === "number"
2156                ){
2157                    for(var i=0; i<categories.length; i++){
2158                        if(_inArray(all_categories, categories[i]) !== -1) {
2159                            to_accept.push(categories[i]);
2160                        }
2161
2162                    }
2163                }else if(typeof categories === "string"){
2164                    if(categories === 'all')
2165                        to_accept = all_categories.slice();
2166                    else{
2167                        if(_inArray(all_categories, categories) !== -1)
2168                            to_accept.push(categories);
2169                    }
2170                }
2171            }
2172
2173            // Remove excluded categories
2174            if(exclusions.length >= 1){
2175                for(i=0; i<exclusions.length; i++){
2176                    to_accept = to_accept.filter(function(item) {
2177                        return item !== exclusions[i]
2178                    })
2179                }
2180            }
2181
2182            // Add back all the categories set as "readonly/required"
2183            for(i=0; i<all_categories.length; i++){
2184                if(
2185                    readonly_categories[i] === true &&
2186                    _inArray(to_accept, all_categories[i]) === -1
2187                ){
2188                    to_accept.push(all_categories[i]);
2189                }
2190            }
2191
2192            _saveCookiePreferences(to_accept);
2193        }
2194
2195        /**
2196         * API function to easily erase cookies
2197         * @param {(string|string[])} _cookies
2198         * @param {string} [_path] - optional
2199         * @param {string} [_domain] - optional
2200         */
2201        _cookieconsent.eraseCookies = function(_cookies, _path, _domain){
2202            var cookies = [];
2203            var domains = _domain
2204                ? [_domain, "."+_domain]
2205                : [_config.cookie_domain, "."+_config.cookie_domain];
2206
2207            if(typeof _cookies === "object" && _cookies.length > 0){
2208                for(var i=0; i<_cookies.length; i++){
2209                    this.validCookie(_cookies[i]) && cookies.push(_cookies[i]);
2210                }
2211            }else{
2212                this.validCookie(_cookies) && cookies.push(_cookies);
2213            }
2214
2215            _eraseCookies(cookies, _path, domains);
2216        }
2217
2218        /**
2219         * Set cookie, by specifying name and value
2220         * @param {string} name
2221         * @param {string} value
2222         */
2223        var _setCookie = function(name, value) {
2224
2225            var cookie_expiration = _config.cookie_expiration;
2226
2227            if(typeof _config.cookie_necessary_only_expiration === 'number' && accept_type === 'necessary')
2228                cookie_expiration = _config.cookie_necessary_only_expiration;
2229
2230            value = _config.use_rfc_cookie ? encodeURIComponent(value) : value;
2231
2232            var date = new Date();
2233            date.setTime(date.getTime() + (1000 * (cookie_expiration * 24 * 60 * 60)));
2234            var expires = "; expires=" + date.toUTCString();
2235
2236            var cookieStr = name + "=" + (value || "") + expires + "; Path=" + _config.cookie_path + ";";
2237            cookieStr += " SameSite=" + _config.cookie_same_site + ";";
2238
2239            // assures cookie works with localhost (=> don't specify domain if on localhost)
2240            if(window.location.hostname.indexOf(".") > -1){
2241                cookieStr += " Domain=" + _config.cookie_domain + ";";
2242            }
2243
2244            if(window.location.protocol === "https:") {
2245                cookieStr += " Secure;";
2246            }
2247
2248            document.cookie = cookieStr;
2249
2250            _log("CookieConsent [SET_COOKIE]: '" + name + "' expires after " + cookie_expiration + " day(s)");
2251        }
2252
2253        /**
2254         * Get cookie value by name,
2255         * returns the cookie value if found (or an array
2256         * of cookies if filter provided), otherwise empty string: ""
2257         * @param {string} name
2258         * @param {string} filter 'one' or 'all'
2259         * @param {boolean} [get_value] set to true to obtain its value
2260         * @returns {string|string[]}
2261         */
2262        var _getCookie = function(name, filter, get_value) {
2263            var found;
2264
2265            if(filter === 'one'){
2266                found = document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)");
2267                found = found ? (get_value ? found.pop() : name) : "";
2268
2269                if(found && name === _config.cookie_name){
2270                    try{
2271                        found = JSON.parse(found)
2272                    }catch(e){
2273                        try {
2274                            found = JSON.parse(decodeURIComponent(found))
2275                        } catch (e) {
2276                            // if I got here => cookie value is not a valid json string
2277                            found = {};
2278                        }
2279                    }
2280                    found = JSON.stringify(found);
2281                }
2282            }else if(filter === 'all'){
2283                // array of names of all existing cookies
2284                var cookies = document.cookie.split(/;\s*/); found = [];
2285                for(var i=0; i<cookies.length; i++){
2286                    found.push(cookies[i].split("=")[0]);
2287                }
2288            }
2289
2290            return found;
2291        }
2292
2293        /**
2294         * Delete cookie by name & path
2295         * @param {string[]} cookies
2296         * @param {string} [custom_path] - optional
2297         * @param {string[]} domains - example: ['domain.com', '.domain.com']
2298         */
2299        var _eraseCookies = function(cookies, custom_path, domains) {
2300            domains = [
2301                window.location.hostname
2302            ];
2303
2304            if (subdomain) {
2305                let parent = window.location.hostname.split('.');
2306                parent.shift();
2307                domains.push('.'+parent.join('.'));
2308            }
2309
2310            var path = custom_path ? custom_path : '/';
2311            var expires = 'Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
2312
2313            for(var i=0; i<cookies.length; i++){
2314                for(var j=0; j<domains.length; j++){
2315                    document.cookie = cookies[i] + '=; path=' + path + '; ' + expires + ' Domain=' + domains[j];
2316                    _log("CookieConsent [AUTOCLEAR]: deleting cookie: '" + cookies[i] + "' path: '" + path + "' domain:", domains);
2317                }
2318            }
2319        }
2320
2321        /**
2322         * Returns true if cookie was found and has valid value (not empty string)
2323         * @param {string} cookie_name
2324         * @returns {boolean}
2325         */
2326        _cookieconsent.validCookie = function(cookie_name){
2327            return _getCookie(cookie_name, 'one', true) !== "";
2328        }
2329
2330        /**
2331         * Function to run when event is fired
2332         * @callback eventFired
2333         */
2334
2335        /**
2336         * Add event listener to dom object (cross browser function)
2337         * @param {Element} elem
2338         * @param {string} event
2339         * @param {eventFired} fn
2340         * @param {boolean} [isPassive]
2341         */
2342        var _addEvent = function(elem, event, fn, isPassive) {
2343            elem.addEventListener(event, fn , isPassive === true ? { passive: true } : false);
2344        }
2345
2346        /**
2347         * Get all prop. keys defined inside object
2348         * @param {Object} obj
2349         */
2350        var _getKeys = function(obj){
2351            if(typeof obj === "object"){
2352                return Object.keys(obj);
2353            }
2354        }
2355
2356        /**
2357         * Append class to the specified dom element
2358         * @param {HTMLElement} elem
2359         * @param {string} classname
2360         */
2361        var _addClass = function (elem, classname){
2362            elem.classList.add(classname);
2363        }
2364
2365        /**
2366         * Remove specified class from dom element
2367         * @param {HTMLElement} elem
2368         * @param {string} classname
2369         */
2370        var _removeClass = function (el, className) {
2371            el.classList.remove(className);
2372        }
2373
2374        /**
2375         * Check if html element has class
2376         * @param {HTMLElement} el
2377         * @param {string} className
2378         */
2379        var _hasClass = function(el, className) {
2380            return el.classList.contains(className);
2381        }
2382
2383        // @Visaoi: Checa se já foi aceito
2384        var cookied = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}");
2385
2386        if (cookied["categories"] && cookied["categories"].length > 0) {
2387            cookied["categories"]?.forEach(function (item) {
2388                VisaoiCookies.stack[item]?.forEach(f => f())
2389            });
2390        }
2391
2392        return _cookieconsent;
2393    };
2394
2395    var init = 'initCookieConsent';
2396    /**
2397     * Make CookieConsent object accessible globally
2398     */
2399    if(typeof window !== 'undefined' && typeof window[init] !== 'function'){
2400        window[init] = CookieConsent
2401    }
2402})();

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.