class Tabs_ttTab {
    constructor(p) {
        this.id = p.tab.id;
        this.pinned = p.tab.pinned;
        if (document.getElementById(p.tab.id) != null && tt.tabs[p.tab.id]) {
            tt.tabs[p.tab.id].GetFaviconAndTitle(p.addCounter);
            return;
        }
        let ClassList = p.tab.pinned ? "pin" : "tab";
        if (p.tab.discarded) ClassList += " discarded";
        if (p.tab.attention) ClassList += " attention";
        if (p.AdditionalClass) ClassList += " " + p.AdditionalClass;
        if (p.ExpandState) ClassList += " " + p.ExpandState;
        let DIV_Tab = DOM_New("div", undefined, {id: p.tab.id, className: ClassList});
        let DIV_header = DOM_New("div", DIV_Tab, {id: ("tab_header_" + p.tab.id), className: (opt.always_show_close && !opt.never_show_close) ? "tab_header close_show" : "tab_header", draggable: (!p.SkipSetEvents ? true : false)});
        let DIV_expand = DOM_New("div", DIV_header, {id: ("exp_" + p.tab.id), className: "expand"});
        let DIV_counter = DOM_New("div", DIV_header, {id: ("tab_counter_" + p.tab.id), className: "tab_counter"});
        DOM_New("div", DIV_counter, {id: ("counter_number_" + p.tab.id), className: "counter_number"});
        let DIV_title = DOM_New("div", DIV_header, {id: ("tab_title_" + p.tab.id), className: "tab_title"});
        let DIV_close_button = DOM_New("div", DIV_header, {id: ("close_" + p.tab.id), className: (opt.never_show_close ? "close hidden" : "close")});
        DOM_New("div", DIV_close_button, {id: ("close_img_" + p.tab.id), className: (opt.never_show_close ? "close_img hidden" : "close_img")});
        let DIV_audio_indicator = DOM_New("div", DIV_header, {id: ("tab_mediaicon_" + p.tab.id), className: "tab_mediaicon"});
        let DIV_children = DOM_New("div", DIV_Tab, {id: ("°" + p.tab.id), className: "children"});
        DOM_New("div", DIV_Tab, {id: ("drag_indicator_" + p.tab.id), className: "drag_indicator"});
        if (!p.SkipSetEvents) {
            DIV_children.onclick = function(event) {
                if (event.target == this && event.which == 1) DOM_Deselect();
            }
            DIV_children.onmousedown = function(event) {
                if (event.target == this) {
                    if (event.which == 2 && event.target == this) {
                        event.stopImmediatePropagation();
                        Groups_ActionClickGroup(this.parentNode, opt.midclick_group);
                    }
                    if (event.which == 3) Menu_ShowFGlobalMenu(event);
                }
            }
            DIV_children.ondblclick = function(event) {
                if (event.target == this) Groups_ActionClickGroup(this.parentNode, opt.dbclick_group);
            }
            DIV_expand.onmousedown = function(event) {
                if (tt.DOMmenu.style.top != "-1000px") Menu_HideMenus();
                if (event.which == 1 && !event.shiftKey && !event.ctrlKey) DOM_EventExpandBox(this.parentNode.parentNode);
            }
            DIV_expand.onmouseenter = function(event) {
                this.classList.add("hover");
            }
            DIV_expand.onmouseleave = function(event) {
                this.classList.remove("hover");
            }
            if (!opt.never_show_close) {
                DIV_close_button.onmousedown = function(event) {
                    event.stopImmediatePropagation();
                    if (event.which != 3) Tabs_CloseTabs([parseInt(this.parentNode.parentNode.id)]);
                }
                DIV_close_button.onmouseenter = function(event) {
                    this.classList.add("close_hover");
                }
                DIV_close_button.onmouseleave = function(event) {
                    this.classList.remove("close_hover");
                }
            }
            DIV_header.ondblclick = function(event) {
                if (event.target.classList && event.target.classList.contains("tab_header")) Tabs_ActionClickTab(this.parentNode, opt.dbclick_tab);
            }
            DIV_header.onmousedown = function(event) {
                if (browserId == "V") {
                    chrome.windows.getCurrent({populate: false}, function(window) {
                        if (tt.CurrentWindowId != window.id && window.focused) location.reload();
                    });
                }
                event.stopImmediatePropagation();
                if (event.which == 1) {
                    if (tt.DOMmenu.style.top != "-1000px") {
                        Menu_HideMenus();
                    } else {
                        
                        if (event.shiftKey || event.ctrlKey) {
                            DOM_Select(event, this.parentNode);
                        }
                        
                        // let tabId = parseInt(this.parentNode.id);
                        // setTimeout(function() {
                            // if (tt.Dragging == false && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("tab_header") && event.target.parentNode.classList.contains("selected") == false) {
                                // chrome.tabs.update(tabId, {active: true});
                            // }
                        // }, 90);
                    }
                }
                if (event.which == 2) {
                    event.preventDefault();
                    Tabs_ActionClickTab(this.parentNode, opt.midclick_tab);
                }
                if (event.which == 3) Menu_ShowTabMenu(this.parentNode, event);
            }
            
            DIV_header.onclick = function(event) {
                if (!event.shiftKey && !event.ctrlKey) {
                    DOM_Deselect();
                    
                    // let tabId = parseInt(this.parentNode.id);
                    
                    if (event.target.classList.contains("tab_header")) {
                        chrome.tabs.update(parseInt(this.parentNode.id), {active: true});
                        // , function(tab) {
                            // if (was_selected) tt.tab[tab.id].Node.classList.add("selected");
                        // });
                    }
                }
            }
            
            
            
            // DIV_header.onmouseup = function(event) {
                // event.stopImmediatePropagation();
                // if (tt.DOMmenu.style.top != "-1000px") {
                    // Menu_HideMenus();
                // } else {
                    // if (event.which == 1 && !event.shiftKey && !event.ctrlKey && event.target.classList.contains("tab_header")) {
                        // DOM_Deselect();
                        // chrome.tabs.update(parseInt(this.parentNode.id), {active: true});
                    // }
                // }
            // }
            DIV_header.onmouseover = function(event) {
                this.classList.add("tab_header_hover");
                if (opt.never_show_close == false && opt.always_show_close == false) this.classList.add("close_show");
            }
            DIV_header.onmouseleave = function(event) {
                this.classList.remove("tab_header_hover");
                if (opt.never_show_close == false && opt.always_show_close == false) this.classList.remove("close_show");
            }
            DIV_header.ondragstart = function(event) { // DRAG START
                tt.Dragging = true;
                tt.DraggingGroup = false;
                event.stopPropagation();
                event.dataTransfer.setDragImage(document.getElementById("DragImage"), 0, 0);
                event.dataTransfer.setData("text", "");
                event.dataTransfer.setData("SourceWindowId", tt.CurrentWindowId);
                DOM_CleanUpDragAndDrop();
                let Nodes = [];
                if (this.parentNode.classList.contains("selected")) {
                    DOM_FreezeSelection(false);
                } else {
                    DOM_FreezeSelection(true);
                    DOM_SetClasses(this.parentNode, ["selected_temporarly", "selected"], [], []);
                }
                DOM_RemoveHeadersHoverClass();
                let selected = document.querySelectorAll(".selected, .selected .tab, .selected .folder");
                for (let s of selected) {
                    s.classList.add("dragged_tree");
                    if (s.classList.contains("pin")) {
                        tt.DraggingPin = true;
                        Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "pin"});
                    }
                    if (s.classList.contains("tab")) {
                        tt.DraggingTab = true;
                        Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "tab"});
                    }
                    if (s.classList.contains("folder")) {
                        tt.DraggingFolder = true;
                        Nodes.push({id: s.id, parent: s.parentNode.id, selected: s.classList.contains("selected"), temporary: s.classList.contains("selected_temporarly"), NodeClass: "folder", index: (tt.folders[s.id] ? tt.folders[s.id].index : 0), name: (tt.folders[s.id] ? tt.folders[s.id].name : labels.noname_group), expand: (tt.folders[s.id] ? tt.folders[s.id].expand : "")});
                    }
                }
                if (opt.max_tree_drag_drop && opt.max_tree_depth >= 0) {
                    let dragged_tree = document.querySelectorAll(".dragged_tree .tab, .dragged_tree .folder");
                    for (let s of dragged_tree) {
                        let parents = DOM_GetParentsByClass(s.parentNode, "dragged_tree");
                        if (parents.length > tt.DragTreeDepth) tt.DragTreeDepth = parents.length;
                    }
                } else {
                    tt.DragTreeDepth = -1;
                }
                let Parents = DOM_GetAllParents(this.parentNode);
                for (let s of Parents) {
                    if (s.classList && (s.classList.contains("tab") || s.classList.contains("folder"))) s.classList.add("dragged_parents");
                }
                event.dataTransfer.setData("Nodes", JSON.stringify(Nodes));
                event.dataTransfer.setData("NodesTypes", JSON.stringify({DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder}));
                chrome.runtime.sendMessage({command: "drag_start", DragTreeDepth: tt.DragTreeDepth, DraggingGroup: tt.DraggingGroup, DraggingPin: tt.DraggingPin, DraggingTab: tt.DraggingTab, DraggingFolder: tt.DraggingFolder});
            }
            DIV_header.ondragenter = function(event) {
                this.classList.remove("tab_header_hover");
            }
            DIV_header.ondragleave = function(event) {
                DOM_RemoveHighlight();
            }
            DIV_header.ondragover = function(event) {
                if (tt.DraggingGroup == false && (tt.DraggingPin || tt.DraggingTab || tt.DraggingFolder) && this.parentNode.classList.contains("dragged_tree") == false) {
                    if (this.parentNode.classList.contains("pin")) {
                        if (this.parentNode.classList.contains("before") == false && event.layerX < this.clientWidth / 2) {
                            DOM_RemoveHighlight();
                            DOM_SetClasses(this.parentNode, ["before", "highlighted_drop_target"], ["after"], []);
                        }
                        if (this.parentNode.classList.contains("after") == false && event.layerX >= this.clientWidth / 2) {
                            DOM_RemoveHighlight();
                            DOM_SetClasses(this.parentNode, ["after", "highlighted_drop_target"], ["before"], []);
                        }
                    }
                    if (this.parentNode.classList.contains("tab")) {
                        let TabDepth = Tabs_GetTabDepthInTree(this);
                        let PDepth = TabDepth + tt.DragTreeDepth;
                        let PIsGroup = this.parentNode.parentNode.parentNode.classList.contains("group");
                        // let PIsTab = this.parentNode.parentNode.parentNode.classList.contains("tab");
                        let PIsFolder = this.parentNode.parentNode.parentNode.classList.contains("folder");
                        let PIsDraggedParents = this.parentNode.classList.contains("dragged_parents");
                        if ((PIsFolder == tt.DraggingFolder || tt.DraggingFolder == false || PIsGroup == true) && this.parentNode.classList.contains("before") == false && event.layerY < this.clientHeight / 3 && (PDepth <= opt.max_tree_depth + 1 || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) {
                            DOM_RemoveHighlight();
                            DOM_SetClasses(this.parentNode, ["before", "highlighted_drop_target"], ["inside", "after"], []);
                        }
                        if (tt.DraggingFolder == false && this.parentNode.classList.contains("inside") == false && event.layerY > this.clientHeight / 3 && event.layerY <= 2 * (this.clientHeight / 3) && (PDepth <= opt.max_tree_depth || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) {
                            DOM_RemoveHighlight();
                            DOM_SetClasses(this.parentNode, ["inside", "highlighted_drop_target"], ["before", "after"], []);
                        }
                        if ((PIsFolder == tt.DraggingFolder || tt.DraggingFolder == false || PIsGroup == true) && this.parentNode.classList.contains("after") == false && this.parentNode.classList.contains("o") == false && event.layerY > 2 * (this.clientHeight / 3) && (PDepth <= opt.max_tree_depth + 1 || opt.max_tree_depth < 0 || opt.max_tree_drag_drop == false || PIsDraggedParents == true)) {
                            DOM_RemoveHighlight();
                            DOM_SetClasses(this.parentNode, ["after", "highlighted_drop_target"], ["before", "inside"], []);
                        }
                    }
                }
                if (opt.open_tree_on_hover && tt.DragOverId != this.id) {
                    if (this.parentNode.classList.contains("c") && this.parentNode.classList.contains("dragged_tree") == false) {
                        clearTimeout(tt.DragOverTimer);
                        tt.DragOverId = this.id;
                        let This = this;
                        tt.DragOverTimer = setTimeout(function() {
                            if (tt.DragOverId == This.id) DOM_SetClasses(This.parentNode, ["o"], ["c"], []);
                        }, 1500);
                    }
                }
            }
            DIV_header.ondragend = function(event) {
                if (opt.open_tree_on_hover) {
                    clearTimeout(tt.DragOverTimer);
                    tt.DragOverId = "";
                }
                setTimeout(function() {DOM_CleanUpDragAndDrop();}, 300);
                setTimeout(function() {chrome.runtime.sendMessage({command: "drag_end"});}, 500);
            }
            DIV_audio_indicator.onmousedown = function(event) {
                event.stopImmediatePropagation();
                if (event.which == 1 && (this.parentNode.parentNode.classList.contains("audible") || this.parentNode.parentNode.classList.contains("muted"))) {
                    chrome.tabs.get(parseInt(this.parentNode.parentNode.id), function(tab) {
                        if (tab) chrome.tabs.update(tab.id, {muted: !tab.mutedInfo.muted});
                    });
                }
            }
        }
        let parent;
        if (p.tab.pinned == true) {
            parent = document.getElementById("pin_list");
        } else {
            if (p.ParentId == false || p.ParentId == undefined || p.ParentId == "pin_list") {
                parent = document.getElementById("°" + tt.active_group);
            } else {
                parent = document.getElementById(p.ParentId);
                if (parent == null || parent.classList.contains("pin") || parent.parentNode.classList.contains("pin")) {
                    parent = document.getElementById("°" + tt.active_group);
                } else {
                    parent = document.getElementById("°" + p.ParentId);
                    if (parent.children.length == 0) DOM_SetClasses(parent.parentNode, ["o"], ["c"], []);
                }
            }
        }
        if (p.Append == true && parent) parent.appendChild(DIV_Tab);
        if ((p.Append == false || p.Append == undefined) && parent) {parent.prepend(DIV_Tab);}
        if (p.InsertAfterId) {
            let After = document.getElementById(p.InsertAfterId);
            if (After != null) {
                if ((p.tab.pinned && After.classList.contains("pin")) || (p.tab.pinned == false && (After.classList.contains("tab") || After.classList.contains("folder")))) {
                    DOM_InsterAfterNode(DIV_Tab, After);
                } else {
                    parent.appendChild(DIV_Tab);
                }
            } else {
                parent.appendChild(DIV_Tab);
            }
        }
        this.Node = DIV_Tab;
        this.title = DIV_title;
        if (!p.SkipFavicon) this.GetFaviconAndTitle(p.addCounter);
        if (!p.SkipMediaIcon) this.RefreshMediaIcon(p.tab.id);
        if (p.RefreshDiscarded) this.RefreshDiscarded();
        if (p.tab.active && !p.SkipSetActive) Tabs_SetActiveTab(p.tab.id);
        if (p.Scroll) this.ScrollToTab();
    }
    RemoveTab() {
        if (opt.debug) Utils_log("f: RemoveTab, tabId: " + this.id);
        if (this.Node != null) {
            this.Node.parentNode.removeChild(this.Node);
            if (tt.tabs[this.id]) delete tt.tabs[this.id];
        }
    }
    ScrollToTab() {
        let Tab = this.Node;
        let P = document.getElementById("pin_list");
        let G = document.getElementById(tt.active_group);
        if (Tab != null) {
            if (Tab.classList.contains("pin")) {
                if (Tab.getBoundingClientRect().left - P.getBoundingClientRect().left < 0) {
                    P.scrollLeft = P.scrollLeft + Tab.getBoundingClientRect().left - P.getBoundingClientRect().left - 2;
                } else {
                    if (Tab.getBoundingClientRect().left - P.getBoundingClientRect().left > G.getBoundingClientRect().width - document.querySelector(".tab_header").getBoundingClientRect().width) {
                        P.scrollLeft = P.scrollLeft + Tab.getBoundingClientRect().left - P.getBoundingClientRect().left - P.getBoundingClientRect().width + document.querySelector(".tab_header").getBoundingClientRect().width + 2;
                    }
                }
            } else if (Tab.classList.contains("tab") && document.querySelector("#" + tt.active_group + " [id='" + this.id + "']") != null) {
                let Parents = DOM_GetParentsByClass(Tab, "c");
                if (Parents.length > 0) {
                    for (let s of Parents) {
                        DOM_SetClasses(s, ["o"], ["c"], []);
                    }
                }
                if (Tab.getBoundingClientRect().top - G.getBoundingClientRect().top < 0) {
                    G.scrollTop = G.scrollTop + Tab.getBoundingClientRect().top - G.getBoundingClientRect().top - 2;
                } else {
                    if (Tab.getBoundingClientRect().top - G.getBoundingClientRect().top > G.getBoundingClientRect().height - document.querySelector(".tab_header").getBoundingClientRect().height) {
                        G.scrollTop = G.scrollTop + Tab.getBoundingClientRect().top - G.getBoundingClientRect().top - G.getBoundingClientRect().height + document.querySelector(".tab_header").getBoundingClientRect().height + 10;
                    }
                }
            }
        }
    }
    SetTabClass(pin) {
        let GroupList = document.getElementById("°" + tt.active_group);
        let Tab = this.Node;
        if (Tab != null) {
            if (pin) {
                if (Tab.parentNode.id != "pin_list") document.getElementById("pin_list").appendChild(Tab);
                DOM_SetClasses(Tab, ["pin"], ["tab", "o", "c"], []);
                if (Tab.childNodes[1].childNodes.length > 0) { // flatten out children
                    let tabs = document.querySelectorAll("#°" + Tab.id + " .pin, #°" + Tab.id + " .tab");
                    for (let tab of tabs) {
                        DOM_SetClasses(tab, ["pin"], ["tab", "o", "c"], []);
                        DOM_InsterAfterNode(tab, Tab);
                        chrome.tabs.update(parseInt(tab.id), {pinned: true});
                    }
                    let folders = document.querySelectorAll("#°" + Tab.id + " .folder");
                    for (let i = folders.length - 1; i >= 0; i--) {
                        GroupList.prepend(folders[i]);
                    }
                }
                chrome.tabs.update(parseInt(Tab.id), {pinned: true});
            } else {
                if (Tab.parentNode.id == "pin_list") { // if coming from pin_list
                    if (GroupList.childNodes.length > 0) {
                        GroupList.insertBefore(Tab, GroupList.childNodes[0]);
                    } else {
                        GroupList.appendChild(Tab);
                    }
                }
                DOM_SetClasses(Tab, ["tab"], ["pin", "attention"], []);
                DOM_RefreshExpandStates();
                chrome.tabs.update(parseInt(Tab.id), {pinned: false});
            }
            DOM_RefreshGUI();
        }
    }
    DuplicateTab() {
        let OriginalTabNode = this.Node;
        chrome.tabs.duplicate(parseInt(this.id), function(tab) {
            let DupRetry = setInterval(function() {
                let DupTab = document.getElementById(tab.id);
                if (DupTab != null && OriginalTabNode != null) {
                    if (browserId == "F" && tab.pinned) DOM_SetClasses(DupTab, ["pin"], ["tab"], []);
                    DOM_InsterAfterNode(DupTab, OriginalTabNode);
                    DOM_RefreshExpandStates();
                    tt.schedule_update_data++;
                    DOM_RefreshCounters();
                    clearInterval(DupRetry);
                }
            }, 10);
            setTimeout(function() {
                if (DupRetry) clearInterval(DupRetry);
            }, 500);
        });
    }
    GetFaviconAndTitle(addCounter) {
        let t = document.getElementById(this.id);
        let tTitle = this.title;
        if (t != null) {
            chrome.tabs.get(parseInt(t.id), async function(tab) {
                if (tab) {
                    let title = tab.title ? tab.title : tab.url;
                    let tHeader = t.childNodes[0];
                    if (tab.status == "complete" || tab.discarded) {
                        t.classList.remove("loading");
                        tTitle.textContent = title;
                        tHeader.title = title;
                        if (opt.show_counter_tabs_hints) tHeader.setAttribute("tabTitle", title);
                        let Img = new Image();
                        let CachedFavicon = browserId == "F" ? await browser.sessions.getTabValue(tab.id, "CachedFaviconUrl") : "chrome://favicon/" + tab.url;
                        let TryCases = [tab.favIconUrl, CachedFavicon, "./theme/icon_empty.svg"];
                        Tabs_LoadFavicon(tab.id, Img, TryCases, tHeader, 0);
                    }
                    if (tab.status == "loading" && tab.discarded == false) {
                        title = tab.title ? tab.title : labels.loading;
                        t.classList.add("loading");
                        tHeader.style.backgroundImage = "";
                        tHeader.title = labels.loading;
                        if (opt.show_counter_tabs_hints) tHeader.setAttribute("tabTitle", labels.loading);
                        tTitle.textContent = labels.loading;
                        setTimeout(function() {
                            if (document.getElementById(tab.id) != null && tt.tabs[tab.id]) tt.tabs[tab.id].GetFaviconAndTitle(addCounter);
                        }, 1000);
                    }
                    if (addCounter && (opt.show_counter_tabs || opt.show_counter_tabs_hints)) tt.tabs[t.id].RefreshTabCounter();
                }
            });
        }
    }
    RefreshDiscarded() { // set discarded class
        let t = document.getElementById(this.id);
        if (t != null) {
            chrome.tabs.get(parseInt(t.id), function(tab) {
                if (tab) {
                    if (tab.discarded) {
                        DOM_SetClasses(t, ["discarded"], ["audible", "muted"], []);
                    } else {
                        t.classList.remove("discarded");
                    }
                }
            });
        }
    }
    SetAttentionIcon() { // set attention class
        let t = document.getElementById(this.id);
        if (t != null) t.classList.add("attention");
    }
    RefreshMediaIcon() { // change media icon
        let t = document.getElementById(this.id);
        if (t != null) {
            chrome.tabs.get(parseInt(t.id), function(tab) {
                if (tab) {
                    if (tab.mutedInfo.muted && !tab.discarded) DOM_SetClasses(t, ["muted"], ["audible"], []);
                    if (!tab.mutedInfo.muted && tab.audible && !tab.discarded) DOM_SetClasses(t, ["audible"], ["muted"], []);
                    if ((!tab.mutedInfo.muted && !tab.audible) || tab.discarded) DOM_SetClasses(t, [], ["audible", "muted"], []);
                }
            });
        }
    }
    RefreshTabCounter() {
        let t = document.getElementById(this.id);
        if (t != null && t.childNodes[0]) {
            let title = t.childNodes[0].getAttribute("tabTitle");
            if (t != null && title != null) {
                if (t.classList.contains("o") || t.classList.contains("c")) {
                    if (opt.show_counter_tabs) t.childNodes[0].childNodes[1].childNodes[0].textContent = document.querySelectorAll("[id='" + t.id + "'] .tab").length;
                    if (opt.show_counter_tabs_hints) t.childNodes[0].title = (document.querySelectorAll("[id='" + t.id + "'] .tab").length + " • ") + title;
                } else {
                    t.childNodes[0].title = title;
                }
            }
        }
    }
}

async function Tabs_LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, i) {
    if (TabHeaderNode) {
        Img.src = TryUrls[i];
        Img.onload = function() {
            TabHeaderNode.style.backgroundImage = "url(" + TryUrls[i] + ")";
            if (browserId == "F") browser.sessions.setTabValue(tabId, "CachedFaviconUrl", TryUrls[i]); // cache Firefox favicon - solution for bug with empty favicons in unloaded tabs
        };
        Img.onerror = function() {
            if (i < TryUrls.length) Tabs_LoadFavicon(tabId, Img, TryUrls, TabHeaderNode, (i + 1));
        }
    }
}

async function Tabs_SaveTabs() {
    setInterval(function() {
    if (opt.debug) Utils_log("f: Tabs_SaveTabs");
        if (tt.schedule_update_data > 1) tt.schedule_update_data = 1;
        if (tt.schedule_update_data > 0) {
            let pins_data = [];
            let tabs_data = [];
            for (let tabId in tt.tabs) {
                if (tt.tabs[tabId].Node != null && tt.tabs[tabId].Node.parentNode != null) {
                    if (tt.tabs[tabId].pinned) {
                        pins_data.push({id: tabId, parent: "pin_list", index: Array.from(tt.tabs[tabId].Node.parentNode.children).indexOf(tt.tabs[tabId].Node), expand: ""});
                    } else {
                        tabs_data.push({id: tabId, parent: tt.tabs[tabId].Node.parentNode.parentNode.id, index: Array.from(tt.tabs[tabId].Node.parentNode.children).indexOf(tt.tabs[tabId].Node), expand: (tt.tabs[tabId].Node.classList.contains("c") ? "c" : (tt.tabs[tabId].Node.classList.contains("o") ? "o" : ""))});
                    }
                }
            }
            chrome.runtime.sendMessage({command: "update_all_tabs", pins: pins_data, tabs: tabs_data});
            tt.schedule_update_data--;
        }
    }, 1000);
}

async function Tabs_RearrangeBrowserTabs() {
    if (opt.debug) Utils_log("f: Tabs_RearrangeBrowserTabs");
    setInterval(function() {
        if (tt.schedule_rearrange_tabs > 0) {
            tt.schedule_rearrange_tabs--;
            if (opt.debug) Utils_log("f: RearrangeBrowserTabs");
            chrome.tabs.query({currentWindow: true}, function(tabs) {
                let ttTabIds = Array.prototype.map.call(document.querySelectorAll(".pin, .tab"), function(s) {return parseInt(s.id);});
                let tabIds = Array.prototype.map.call(tabs, function(t) {return t.id;});
                Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, ttTabIds.length - 1);
            });
        }
    }, 1000);
}

async function Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, tabIndex) {
    if (opt.debug) Utils_log("f: RearrangeBrowserTabsLoop");
    if (tabIndex >= 0 && tt.schedule_rearrange_tabs == 0) {
        if (ttTabIds[tabIndex] != tabIds[tabIndex]) chrome.tabs.move(ttTabIds[tabIndex], {index: tabIndex});
        setTimeout(function() {
            Tabs_RearrangeBrowserTabsLoop(ttTabIds, tabIds, (tabIndex - 1));
        }, 0);
    }
}

function Tabs_RearrangeTree(TTtabs, TTfolders, show_finish_in_status) {
    if (opt.debug) Utils_log("f: Tabs_RearrangeTree");
    Manager_ShowStatusBar({show: true, spinner: true, message: chrome.i18n.getMessage("status_bar_rearranging_tabs")});
    let Nodes = document.querySelectorAll(".pin, .tab, .folder");
    for (let Node of Nodes) {
        let Sibling = Node.nextElementSibling;
        if (Sibling) {
            let NodeIndex = TTtabs[Node.id] ? TTtabs[Node.id].index : (TTfolders[Node.id] ? TTfolders[Node.id].index : undefined);
            while (Sibling && NodeIndex) {
                let SiblingIndex = TTtabs[Sibling.id] ? TTtabs[Sibling.id].index : (TTfolders[Sibling.id] ? TTfolders[Sibling.id].index : 0);
                if (NodeIndex > SiblingIndex) DOM_InsterAfterNode(Node, Sibling);
                Sibling = Sibling.nextElementSibling ? Sibling.nextElementSibling : false;
            }
        }
        if (show_finish_in_status) Manager_ShowStatusBar({show: true, spinner: false, message: chrome.i18n.getMessage("status_bar_rearranging_finished"), hideTimeout: 1000});
    }
}

function Tabs_Detach(Nodes, NodesTypes, Group) {
    if (opt.debug) Utils_log("f: Detach");
    let folderNodes = {};
    let TabsIds = [];
    for (let Node of Nodes) {
        if (Node.NodeClass == "folder") folderNodes[Node.id] = {id: Node.id, parent: (Node.parent).substr(1), name: Node.name, index: Node.index, expand: Node.expand};
        if (Node.NodeClass == "pin") TabsIds.push(parseInt(Node.id));
        if (Node.NodeClass == "tab") TabsIds.push(parseInt(Node.id));
    }
    chrome.windows.get(tt.CurrentWindowId, {populate : true}, function(window) {
        if (window.tabs.length == 1) return;
        if (TabsIds.length == window.tabs.length) {
            if (opt.debug) Utils_log("You are trying to detach all tabs! Skipping!");
            return;
        }
        let params = TabsIds.length > 0 ? {tabId: TabsIds[0], state: window.state} : {state: window.state};
        chrome.windows.create(params, function(new_window) {
            chrome.tabs.update(new_window.tabs[0].id, {active: true});
            chrome.runtime.sendMessage({command: "get_groups", windowId: new_window.id}, function(g) {
                if (NodesTypes.DraggingGroup) {
                    let GroupsToDetach = Object.assign({}, g); // if there will be a multi groups selection, below I will need for each group loop
                    GroupsToDetach[Group.id] = Group;
                    chrome.runtime.sendMessage({command: "save_groups", groups: GroupsToDetach, windowId: new_window.id});
                    setTimeout(function() {Groups_GroupRemove(Group.id, false);}, 2000);
                }
                chrome.runtime.sendMessage({command: "save_folders", folders: folderNodes, windowId: new_window.id});
                for (let Node of Nodes) {
                    if (Node.NodeClass == "pin") {
                        chrome.tabs.update(parseInt(Node.id), {pinned: true});
                        chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: "pin_list"}});
                    }
                    if (Node.NodeClass == "tab") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: (Node.parent).substr(1)}});
                    if (Node.NodeClass == "folder") Folders_RemoveFolder(Node.id);
                }
                if (TabsIds.length > 1) {
                    TabsIds.splice(0, 1);
                    chrome.tabs.move(TabsIds, {windowId: new_window.id, index:-1}, function(MovedTabs) {
                        for (let Node of Nodes) {
                            if (Node.NodeClass == "pin") {chrome.tabs.update(parseInt(Node.id), {pinned: true});}
                            if (Node.NodeClass == "folder") {Folders_RemoveFolder(Node.id);}
                        }
                        let Stop = 500;
                        let DetachNodes = setInterval(function() {
                            Stop--;
                            let all_moved = true;
                            for (let Node of Nodes) {
                                if (document.getElementById(Node.id) != null) all_moved = false;
                                if (Node.NodeClass == "pin") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: "pin_list"}});
                                if (Node.NodeClass == "tab") chrome.runtime.sendMessage({command: "update_tab", tabId: Node.id, tab: {parent: (Node.parent).substr(1)}});
                            }
                            if (all_moved || Stop < 0) {
                                setTimeout(function() {
                                    clearInterval(DetachNodes);
                                }, 300);
                            }
                        }, 100);
                    });
                }
            });
        });
    });
}

function Tabs_DiscardTabs(tabsIds) {
    let delay = 100;
    let tabNode = document.getElementById(tabsIds[0]);
    if (tabNode == null || tabNode.classList.contains("discarded") || tabNode.classList.contains("active_tab")) {
        delay = 5;
    } else {
        chrome.tabs.discard(tabsIds[0]);
    }
    tabsIds.splice(0, 1);
    if (tabsIds.length > 0) {
        setTimeout(function() {
            Tabs_DiscardTabs(tabsIds);
        }, delay);
    }
}

function Tabs_FindTab(input) { // find and select tabs
    let ButtonFilterClear = document.getElementById("button_filter_clear");
    let Nodes = document.querySelectorAll(".filtered, .highlighted_search");
    for (let s of Nodes) {
        DOM_SetClasses(s, [], ["selected", "selected_last", "filtered", "highlighted_search"], []);
    }
    if (input.length == 0) {
        document.getElementById("filter_box").value = "";
        ButtonFilterClear.style.opacity = "0"; ButtonFilterClear.title = "";
        return;
    } else {
        ButtonFilterClear.style.opacity = "1"; ButtonFilterClear.title = labels.clear_filter;
    }
    tt.SearchIndex = 0;
    let FilterType = document.getElementById("button_filter_type");
    let searchUrl = FilterType.classList.contains("url");
    let searchTitle = FilterType.classList.contains("title");
    let query = {windowId: tt.CurrentWindowId, pinned: false};
    if (input == "*audible") query = {windowId: tt.CurrentWindowId, discarded: false, audible: true, muted: false, pinned: false};
    if (input == "*muted") query = {windowId: tt.CurrentWindowId, discarded: false, muted: true, pinned: false};
    if (input == "*unloaded") query = {windowId: tt.CurrentWindowId, discarded: true, pinned: false};
    if (input == "*loaded") query = {windowId: tt.CurrentWindowId, discarded: false, pinned: false};
    chrome.tabs.query(query, function(tabs) {
        for (let Tab of tabs) {
            let t = document.getElementById(Tab.id);
            if (input == "*audible" || input == "*muted" || input == "*unloaded" || input == "*loaded") {
                DOM_SetClasses(t, ["filtered", "selected"], [], []);
            } else {
                if (searchUrl) {
                    if (Tab.url.toLowerCase().match(input.toLowerCase())) DOM_SetClasses(t, ["filtered", "selected"], [], []);
                }
                if (searchTitle) {
                    if (Tab.title.toLowerCase().match(input.toLowerCase())) DOM_SetClasses(t, ["filtered", "selected"], [], []);
                }
            }
        }
    });
}

function Tabs_CloseTabs(tabsIds) {
    if (opt.debug) Utils_log("f: Tabs_CloseTabs, tabsIds are: " + JSON.stringify(tabsIds));
    for (let tabId of tabsIds) {
        let t = document.getElementById(tabId);
        if (t != null) t.classList.add("will_be_closed");
    }
    let activeTab = document.querySelector(".pin.active_tab, #" + tt.active_group + " .tab.active_tab");
    if (activeTab != null && tabsIds.indexOf(parseInt(activeTab.id)) != -1) Tabs_SwitchActiveTabBeforeClose(tt.active_group);
    setTimeout(function() {
        for (let tabId of tabsIds) {
            let t = document.getElementById(tabId);
            if (t != null && t.classList.contains("pin") && opt.allow_pin_close) {
                t.parentNode.removeChild(t);
                chrome.tabs.update(tabId, {pinned: false});
                chrome.runtime.sendMessage({command: "update_tab", tabId: tabId, tab: {parent: "pin_list"}});
            }
            if (tabId == tabsIds[tabsIds.length - 1]) {
                setTimeout(function() {chrome.tabs.remove(tabsIds, null);}, 10);
                DOM_RefreshGUI();
            }
        }
    }, 200);
}

function Tabs_OpenNewTab(pin, InsertAfterNode, AppendToNode) {
    // if (pin) {
        chrome.tabs.create({pinned: pin}, function(tab) {
            // console.log(tt.tabs[tab.id])

            let Retry = setInterval(function() {
                if (tt.tabs[tab.id]) {
                    if (InsertAfterNode) {
                        DOM_InsterAfterNode(tt.tabs[tab.id].Node, InsertAfterNode);
                    }
                    if (AppendToNode) {
                        DOM_AppendToNode(tt.tabs[tab.id].Node, AppendToNode);
                    }
                    tt.schedule_update_data++;
                    clearInterval(Retry);
                }
            }, 10);
            setTimeout(function() {
                if (Retry) clearInterval(Retry);
            }, 500);
            if (!pin && opt.move_tabs_on_url_change == "from_empty") chrome.runtime.sendMessage({command: "remove_tab_from_empty_tabs", tabId: tab.id});


            // if (InsertAfterNode && tt.tabs[tab.id]) {
                // let parent = document.getElementById("#pin_list");
                // if (parent != null && tt.tabs[tab.id]) parent.appendChild(tt.tabs[tab.id].Node);
            // }
        });
    // } else {
    //     chrome.tabs.create({}, function(tab) {
    //         if (parentId) {
    //             let parent = document.getElementById("#°"+parentId);
    //             if (parent != null && tt.tabs[tab.id]) parent.appendChild(tt.tabs[tab.id].Node);
    //             tt.schedule_update_data++;
    //         }
    //     });
    // }
}

function Tabs_GetTabDepthInTree(Node) {
    let Depth = 0;
    let ParentNode = Node;
    if (ParentNode == null) return Parents;
    let Stop = false;
    while (!Stop && ParentNode.parentNode != null) {
        if (ParentNode.parentNode.classList != undefined) {
            if (ParentNode.parentNode.classList.contains("tab")) Depth++;
            if (ParentNode.parentNode.classList.contains("folder") || ParentNode.parentNode.classList.contains("group")) {
                Stop = true;
            } else {
                ParentNode = ParentNode.parentNode;
            }
        } else {
            Stop = true;
        }
    }
    return Depth;
}

function Tabs_ActionClickTab(TabNode, bgOption) {
    if (bgOption == "new_tab") Tabs_OpenNewTab(TabNode.classList.contains("pin"), TabNode);
    if (bgOption == "expand_collapse") DOM_EventExpandBox(TabNode);
    if (bgOption == "close_tab") {
        if ((TabNode.classList.contains("pin") && opt.allow_pin_close) || TabNode.classList.contains("tab")) Tabs_CloseTabs([parseInt(TabNode.id)]);
    }
    if (bgOption == "undo_close_tab") {
        chrome.sessions.getRecentlyClosed(null, function(sessions) {
            if (sessions.length > 0) chrome.sessions.restore(null, function(restored) {});
        });
    }
    if (bgOption == "reload_tab") {chrome.tabs.reload(parseInt(TabNode.id));}
    if (bgOption == "unload_tab") {
        if (TabNode.classList.contains("active_tab")) {
            Tabs_SwitchActiveTabBeforeClose(tt.active_group);
            setTimeout(function() {Tabs_DiscardTabs([parseInt(TabNode.id)]);}, 500);
        } else {
            Tabs_DiscardTabs([parseInt(TabNode.id)]);
        }
    }
    if (bgOption == "activate_previous_active" && TabNode.classList.contains("active_tab")) {
        let PrevActiveTabId = parseInt(tt.groups[tt.active_group].prev_active_tab);
        if (isNaN(PrevActiveTabId) == false) chrome.tabs.update(PrevActiveTabId, {active: true});
    }
}

function Tabs_SetActiveTab(tabId, switchToGroup) {
    if (opt.debug) Utils_log("f: SetActiveTab, tabId: " + tabId);
    let Tab = document.getElementById(tabId);
    if (Tab != null) {
        let TabGroup = DOM_GetParentsByClass(Tab, "group");
        if (TabGroup.length) {
            if (Tab.classList.contains("tab")) Groups_SetActiveTabInGroup(TabGroup[0].id, tabId);
            if (switchToGroup) Groups_SetActiveGroup(TabGroup[0].id, false, false); // not going to scroll, because mostly it's going to change to a new active in group AFTER switch, so we are not going to scroll to previous active tab
        }
        // let selected = document.querySelectorAll(".selected");
        // for (let s of selected) {
            // s.classList.remove("selected");
        // }
        // let selected_not_in_group = document.querySelectorAll(".pin, #" + tt.active_group + " .tab");
        // for (let s of selected_not_in_group) {
            // DOM_SetClasses(s, [], ["active_tab", "selected", "selected_last", "selected_frozen", "selected_temporarly", "tab_header_hover"], []);
        // }
        
        
        let active_tabs = document.querySelectorAll(".pin.active_tab, #" + tt.active_group + " .active_tab");
        for (let s of active_tabs) {
            DOM_SetClasses(s, [], ["active_tab"], []);
        }
        DOM_RemoveHighlight();
        DOM_SetClasses(Tab, ["active_tab"], ["attention"], []);
        if (tt.tabs[tabId]) tt.tabs[tabId].ScrollToTab();
    }
}

function Tabs_SwitchActiveTabBeforeClose(ActiveGroupId) {
    if (opt.debug) Utils_log("f: SwitchActiveTabBeforeClose");
    let activeGroup = document.getElementById(ActiveGroupId);
    if (document.querySelectorAll("#" + ActiveGroupId + " .tab:not(.will_be_closed)").length <= 1 && document.querySelector(".pin.active_tab") == null) { // CHECK IF CLOSING LAST TAB IN ACTIVE GROUP
        let pins = document.querySelectorAll(".pin");
        if (pins.length > 0) { // IF THERE ARE ANY PINNED TABS, ACTIVATE IT
            if (opt.debug) Utils_log("available pin, switching to: " + pins[pins.length - 1].id);
            chrome.tabs.update(parseInt(pins[pins.length - 1].id), {active: true});
            return;
        } else { // NO OTHER CHOICE BUT TO SEEK IN ANOTHER GROUP
            if (opt.after_closing_active_tab == "above" || opt.after_closing_active_tab == "above_seek_in_parent") {
                if (activeGroup.previousSibling != null) {
                    if (document.querySelectorAll("#" + activeGroup.previousSibling.id + " .tab").length > 0) {
                        Groups_SetActiveGroup(activeGroup.previousSibling.id, true, true);
                    } else {
                        Tabs_SwitchActiveTabBeforeClose(activeGroup.previousSibling.id);
                        return;
                    }
                } else {
                    Groups_SetActiveGroup("tab_list", true, true);
                }
            } else {
                if (activeGroup.nextSibling != null) {
                    if (document.querySelectorAll("#" + activeGroup.nextSibling.id + " .tab").length > 0) {
                        Groups_SetActiveGroup(activeGroup.nextSibling.id, true, true);
                    } else {
                        Tabs_SwitchActiveTabBeforeClose(activeGroup.nextSibling.id);
                        return;
                    }
                } else {
                    Groups_SetActiveGroup("tab_list", true, true);
                }
            }
        }
    } else {
        if (opt.debug) Utils_log("available tabs in current group, switching option is: " + opt.after_closing_active_tab);
        if (opt.after_closing_active_tab == "above") Tabs_ActivatePrevTab(true);
        if (opt.after_closing_active_tab == "below") Tabs_ActivateNextTab(true);
        if (opt.after_closing_active_tab == "above_seek_in_parent") Tabs_ActivatePrevTabSameLevel();
        if (opt.after_closing_active_tab == "below_seek_in_parent") Tabs_ActivateNextTabSameLevel();
    }
}

function Tabs_ActivateNextTabSameLevel() {
    let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab");
    if (activeTab == null) return;
    let NewActiveId;
    let Node = activeTab;
    if (activeTab.classList.contains("tab")) {
        if (opt.promote_children && activeTab.childNodes[1].firstChild != null && activeTab.childNodes[1].firstChild.classList.contains("tab") && activeTab.childNodes[1].firstChild.classList.contains("will_be_closed") == false) NewActiveId = activeTab.childNodes[1].firstChild.id;
    }
    if (NewActiveId == undefined) {
        while (NewActiveId == undefined && Node.nextSibling != null && Node.classList != undefined) {
            if ((Node.nextSibling.classList.contains("pin") || Node.nextSibling.classList.contains("tab")) && Node.nextSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.nextSibling.id;
            Node = Node.nextSibling;
        }
    }
    if (NewActiveId == undefined) {
        while (NewActiveId == undefined && Node.previousSibling != null && Node.classList != undefined) {
            if ((Node.previousSibling.classList.contains("pin") || Node.previousSibling.classList.contains("tab")) && Node.previousSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.previousSibling.id;
            Node = Node.previousSibling;
        }
    }
    if (NewActiveId == undefined) {Tabs_ActivatePrevTab();}
    if (NewActiveId != undefined) {
        let tabId = parseInt(NewActiveId);
        if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true});
    }
}

function Tabs_ActivatePrevTabSameLevel() {
    let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab");
    if (activeTab == null) return;
    let NewActiveId;
    let Node = activeTab;
    if (activeTab.classList.contains("tab")) {
        if (opt.promote_children && activeTab.childNodes[1].firstChild != null && activeTab.childNodes[1].firstChild.classList.contains("tab") && activeTab.childNodes[1].firstChild.classList.contains("will_be_closed") == false) NewActiveId = activeTab.childNodes[1].firstChild.id;
    }
    if (NewActiveId == undefined) {
        while (NewActiveId == undefined && Node.previousSibling != null && Node.classList != undefined) {
            if ((Node.previousSibling.classList.contains("pin") || Node.previousSibling.classList.contains("tab")) && Node.previousSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.previousSibling.id;
            Node = Node.previousSibling;
        }
    }
    if (NewActiveId == undefined) {
        while (NewActiveId == undefined && Node.nextSibling != null && Node.classList != undefined) {
            if ((Node.nextSibling.classList.contains("pin") || Node.nextSibling.classList.contains("tab")) && Node.nextSibling.classList.contains("will_be_closed") == false) NewActiveId = Node.nextSibling.id;
            Node = Node.nextSibling;
        }
    }
    if (NewActiveId == undefined) Tabs_ActivateNextTab();
    if (NewActiveId != undefined) {
        let tabId = parseInt(NewActiveId);
        if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true});
    }
}

function Tabs_ActivateNextTab(allow_loop) {
    let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab");
    if (activeTab == null) return;
    let NewActiveId;
    let Node = activeTab;
    let parents = DOM_GetAllParents(activeTab);
    while (Node != null && Node.classList != undefined) {
        if (parents.indexOf(Node) == -1 && Node != activeTab && (Node.classList.contains("pin") || Node.classList.contains("tab")) && Node.classList.contains("will_be_closed") == false) {
            NewActiveId = Node.id;
            Node = null;
        } else {
            if (parents.indexOf(Node) == -1 && Node.childNodes[1] && Node.childNodes[1].classList.contains("children") && Node.childNodes[1].childNodes.length > 0 && Node.classList.contains("c") == false) { // GO TO CHILDREN
                Node = Node.childNodes[1].firstChild;
            } else {
                if (Node.nextSibling) { // GO TO NEXT SIBLING
                    Node = Node.nextSibling;
                } else { // GO UP TO PARENT
                    Node = Node.parentNode.parentNode;
                }
            }
        }
    }
    if (allow_loop && NewActiveId == undefined) {
        let RestartLoopFromPin = document.querySelector(".pin");
        let RestartLoopFromTab = document.querySelector("#°" + tt.active_group + " .tab");
        if (activeTab.classList.contains("pin")) {
            if (RestartLoopFromTab != null) {
                NewActiveId = RestartLoopFromTab.id;
            } else {
                if (RestartLoopFromPin != null) NewActiveId = RestartLoopFromPin.id;
            }
        }
        if (activeTab.classList.contains("tab")) {
            if (RestartLoopFromPin != null) {
                NewActiveId = RestartLoopFromPin.id;
            } else {
                if (RestartLoopFromTab != null) NewActiveId = RestartLoopFromTab.id;
            }
        }
    }
    if (NewActiveId != undefined) {
        let tabId = parseInt(NewActiveId);
        if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true});
    }
}

function Tabs_ActivatePrevTab(allow_loop) {
    let activeTab = document.querySelector("#" + tt.active_group + " .tab.active_tab") != null ? document.querySelector("#" + tt.active_group + " .tab.active_tab") : document.querySelector(".pin.active_tab");
    if (activeTab == null) return;
    let NewActiveId;
    let Node = activeTab;
    while (Node != null && Node.classList != undefined) {
        if (Node != activeTab && (Node.classList.contains("pin") || Node.classList.contains("tab")) && Node.classList.contains("will_be_closed") == false) {
            NewActiveId = Node.id;
            Node = null;
        } else {
            if (Node.previousSibling) { // GO TO PREV SIBLING
                Node = Node.previousSibling;
                while (Node != null && Node.classList != undefined && Node.childNodes[1] && Node.childNodes[1].classList.contains("children") && Node.childNodes[1].childNodes.length > 0 && Node.classList.contains("c") == false) {
                    Node = Node.childNodes[1].lastChild;
                }
            } else { // GO UP TO PARENT
                Node = Node.parentNode.parentNode;
            }
        }
    }
    if (allow_loop && NewActiveId == undefined) {
        let RestartLoopFromPin = document.querySelector(".pin:last-child");
        let RestartLoopFromTab = document.querySelectorAll("#°" + tt.active_group + " .tab");
        if (activeTab.classList.contains("pin")) {
            if (RestartLoopFromTab.length > 0) {
                NewActiveId = RestartLoopFromTab[RestartLoopFromTab.length - 1].id;
            } else {
                if (RestartLoopFromPin != null) NewActiveId = RestartLoopFromPin.id;
            }
        }
        if (activeTab.classList.contains("tab")) {
            if (RestartLoopFromPin != null) {
                NewActiveId = RestartLoopFromPin.id;
            } else {
                if (RestartLoopFromTab != null) NewActiveId = RestartLoopFromTab[RestartLoopFromTab.length - 1].id;
            }
        }
    }
    if (NewActiveId != undefined) {
        let tabId = parseInt(NewActiveId);
        if (isNaN(tabId) == false) chrome.tabs.update(tabId, {active: true});
    }
}