<commit_before>var MenuIO, Util;

(function (window) {
    'use strict';
    
    MenuIO = function(element, options, menuData) {
        if (!(this instanceof MenuIO)) {
            return new MenuIO(element, options, menuData);
        }
        
        var ElementMenu,
            Element,
            Options         = {},
            ElementFuncs    = new ElementFuncsProto(),
            ElementHeight,
            ElementEvent,
            MenuFuncs       = {},
            TEMPLATE        = {
                MAIN:   '<ul data-name="js-menu" class="menu menu-hidden">'                             +
                            '{{ items }}'                                                               +
                        '</ul>',
                ITEM:   '<li data-name="js-menu-item" class="menu-item{{ className }}"{{ attribute }}>' +
                            '<label data-menu-path="{{ path }}">{{ name }}</label>'                     +
                            '{{ subitems }}'                                                            +
                        '</li>'
            };
        
        if (menuData) {
            Element         =
            ElementEvent    = element;
            Options         = options;
        } else if (options) {
            Element         =
            ElementEvent    = element;
            menuData        = options;
        } else {
            Element         = document.body;
            ElementEvent    = window;
            menuData        = element;
        }
        
        function init() {
            var name, isObj = Util.type.object(menuData);
            
            if (!isObj) {
                name            = menuData;
                menuData        = {};
                menuData[name]  = null;
            }
            
            ElementMenu         = createMenu(menuData);
            
            ElementEvent.addEventListener('click', onClick);
            ElementEvent.addEventListener('contextmenu', onContextMenu);
        }
        
        function createMenu(menuData) {
            var menu,
                items       = '',
                buildItems  = function(menuData, path) {
                    var DATA_MENU   = 'data-menu="js-submenu"',
                        Data_KEY    = 'data-key=',
                        items       = '';
                    
                    if (path)
                        path        += '.';
                    else
                        path        = '';
                    
                    Object.keys(menuData).forEach(function(name) {
                        var nameIcon,
                            key         = '',
                            subitems    = '',
                            className   = '',
                            attribute   = '',
                            pathName    = path + name,
                            
                            data        = menuData[name],
                            isObj       = Util.type.object(data);
                        
                        if (!isObj) {
                            MenuFuncs[pathName] = data;
                        } else {
                            subitems    = Util.render(TEMPLATE.MAIN, {
                                items: buildItems(data, pathName)
                            });
                            
                            className   = ' menu-submenu';
                            attribute   = ' ' + DATA_MENU;
                        }
                        
                        if (Options.icon) {
                            nameIcon    = Util.rmStr(name, ['(', ')']);
                            nameIcon    = Util.replaceStr(nameIcon, ' ', '-');
                            nameIcon    = nameIcon.toLowerCase();
                            
                            className  += ' icon icon-' + nameIcon;
                        }
                        
                        if (Options.keys) {
                            key = Options.keys[name];
                            
                            if (key)
                                attribute = ' ' + Data_KEY + key;
                        }
                        
                        items           += Util.render(TEMPLATE.ITEM, {
                            name        : name,
                            subitems    : subitems,
                            className   : className,
                            attribute   : attribute,
                            path        : pathName
                        });
                    });
                    
                    return items;
                };
            
            items = buildItems(menuData);
            
            menu  = document.createElement('ul');
            menu.setAttribute('data-name', 'js-menu');
            menu.className  = 'menu menu-hidden';
            menu.innerHTML  = items;
            
            Element.appendChild(menu);
            
            return menu;
        }
        
        this.show   = showMenuElement;
        this.hide   = hideMenuElement;
        
        function checkElement(target, position) {
            var is,
                element = ElementFuncs.getItem(target),
                isName  = ElementFuncs.isName(element),
                isItem  = ElementFuncs.isItem(element),
                isSub   = ElementFuncs.isSubMenu(element);
            
            if (!isName || !isItem) {
                element = document.elementFromPoint(position.x, position.y);
                isSub   = ElementFuncs.isSubMenu(element);
                isName  = ElementFuncs.isName(element);
                isItem  = ElementFuncs.isItem(element);
            }
            
            is = {
                name    : isName,
                item    : isItem,
                sub     : isSub,
            };
            
            return is;
        }
        
        function onClick(event, checkResult) {
            var itemData, notClick,
                afterClick  = Options.afterClick,
                beforeClick = Options.beforeClick,
                name        = Options.name,
                
                element     = event.target,
                is          = checkResult || checkElement(element, {
                    x: event.clientX,
                    y: event.clientY
                });
            
            notClick        = Util.exec(beforeClick, name);
            
            if (is.sub) {
                event.preventDefault();
            } else {
                hideMenuElement();
                
                if (!notClick && (is.name || is.item)) {
                    itemData = getMenuItemData(element);
                    Util.exec(itemData);
                    Util.exec(afterClick);
                }
            }
        }
        
        function onContextMenu(event) {
            var element = event.target,
                x       = event.clientX,
                y       = event.clientY,
                is      = checkElement(element, {
                    x: x,
                    y: y
                });
            
            if (is.name || is.item || is.sub)
                onClick(event, is);
            else {
                hideMenuElement();
                showMenuElement(x, y);
            }
            
            event.preventDefault();
        }
        
        function setMenuPosition(x, y) {
            var isNumberX   = Util.type.number(x),
                isNumberY   = Util.type.number(y),
                heightMenu  = getMenuHeight(),
                heightInner = window.innerHeight;
            
            if (heightInner < heightMenu + y)
                y -= heightMenu;
            
            if (isNumberX)
                ElementMenu.style.left  = x + 'px';
            
            if (isNumberY)
                ElementMenu.style.top   = y - 15 + 'px';
        }
        
        function showMenuElement(x, y) {
            var beforeShow  = Options.beforeShow,
                name        = Options.name,
                params      = {
                    x       : x,
                    y       : y,
                    name    : name
                },<commit_msg>feature(menu) position y: -15 -> -14<commit_after>var MenuIO, Util;

(function (window) {
    'use strict';
    
    MenuIO = function(element, options, menuData) {
        if (!(this instanceof MenuIO)) {
            return new MenuIO(element, options, menuData);
        }
        
        var ElementMenu,
            Element,
            Options         = {},
            ElementFuncs    = new ElementFuncsProto(),
            ElementHeight,
            ElementEvent,
            MenuFuncs       = {},
            TEMPLATE        = {
                MAIN:   '<ul data-name="js-menu" class="menu menu-hidden">'                             +
                            '{{ items }}'                                                               +
                        '</ul>',
                ITEM:   '<li data-name="js-menu-item" class="menu-item{{ className }}"{{ attribute }}>' +
                            '<label data-menu-path="{{ path }}">{{ name }}</label>'                     +
                            '{{ subitems }}'                                                            +
                        '</li>'
            };
        
        if (menuData) {
            Element         =
            ElementEvent    = element;
            Options         = options;
        } else if (options) {
            Element         =
            ElementEvent    = element;
            menuData        = options;
        } else {
            Element         = document.body;
            ElementEvent    = window;
            menuData        = element;
        }
        
        function init() {
            var name, isObj = Util.type.object(menuData);
            
            if (!isObj) {
                name            = menuData;
                menuData        = {};
                menuData[name]  = null;
            }
            
            ElementMenu         = createMenu(menuData);
            
            ElementEvent.addEventListener('click', onClick);
            ElementEvent.addEventListener('contextmenu', onContextMenu);
        }
        
        function createMenu(menuData) {
            var menu,
                items       = '',
                buildItems  = function(menuData, path) {
                    var DATA_MENU   = 'data-menu="js-submenu"',
                        Data_KEY    = 'data-key=',
                        items       = '';
                    
                    if (path)
                        path        += '.';
                    else
                        path        = '';
                    
                    Object.keys(menuData).forEach(function(name) {
                        var nameIcon,
                            key         = '',
                            subitems    = '',
                            className   = '',
                            attribute   = '',
                            pathName    = path + name,
                            
                            data        = menuData[name],
                            isObj       = Util.type.object(data);
                        
                        if (!isObj) {
                            MenuFuncs[pathName] = data;
                        } else {
                            subitems    = Util.render(TEMPLATE.MAIN, {
                                items: buildItems(data, pathName)
                            });
                            
                            className   = ' menu-submenu';
                            attribute   = ' ' + DATA_MENU;
                        }
                        
                        if (Options.icon) {
                            nameIcon    = Util.rmStr(name, ['(', ')']);
                            nameIcon    = Util.replaceStr(nameIcon, ' ', '-');
                            nameIcon    = nameIcon.toLowerCase();
                            
                            className  += ' icon icon-' + nameIcon;
                        }
                        
                        if (Options.keys) {
                            key = Options.keys[name];
                            
                            if (key)
                                attribute = ' ' + Data_KEY + key;
                        }
                        
                        items           += Util.render(TEMPLATE.ITEM, {
                            name        : name,
                            subitems    : subitems,
                            className   : className,
                            attribute   : attribute,
                            path        : pathName
                        });
                    });
                    
                    return items;
                };
            
            items = buildItems(menuData);
            
            menu  = document.createElement('ul');
            menu.setAttribute('data-name', 'js-menu');
            menu.className  = 'menu menu-hidden';
            menu.innerHTML  = items;
            
            Element.appendChild(menu);
            
            return menu;
        }
        
        this.show   = showMenuElement;
        this.hide   = hideMenuElement;
        
        function checkElement(target, position) {
            var is,
                element = ElementFuncs.getItem(target),
                isName  = ElementFuncs.isName(element),
                isItem  = ElementFuncs.isItem(element),
                isSub   = ElementFuncs.isSubMenu(element);
            
            if (!isName || !isItem) {
                element = document.elementFromPoint(position.x, position.y);
                isSub   = ElementFuncs.isSubMenu(element);
                isName  = ElementFuncs.isName(element);
                isItem  = ElementFuncs.isItem(element);
            }
            
            is = {
                name    : isName,
                item    : isItem,
                sub     : isSub,
            };
            
            return is;
        }
        
        function onClick(event, checkResult) {
            var itemData, notClick,
                afterClick  = Options.afterClick,
                beforeClick = Options.beforeClick,
                name        = Options.name,
                
                element     = event.target,
                is          = checkResult || checkElement(element, {
                    x: event.clientX,
                    y: event.clientY
                });
            
            notClick        = Util.exec(beforeClick, name);
            
            if (is.sub) {
                event.preventDefault();
            } else {
                hideMenuElement();
                
                if (!notClick && (is.name || is.item)) {
                    itemData = getMenuItemData(element);
                    Util.exec(itemData);
                    Util.exec(afterClick);
                }
            }
        }
        
        function onContextMenu(event) {
            var element = event.target,
                x       = event.clientX,
                y       = event.clientY,
                is      = checkElement(element, {
                    x: x,
                    y: y
                });
            
            if (is.name || is.item || is.sub)
                onClick(event, is);
            else {
                hideMenuElement();
                showMenuElement(x, y);
            }
            
            event.preventDefault();
        }
        
        function setMenuPosition(x, y) {
            var isNumberX   = Util.type.number(x),
                isNumberY   = Util.type.number(y),
                heightMenu  = getMenuHeight(),
                heightInner = window.innerHeight;
            
            if (heightInner < heightMenu + y)
                y -= heightMenu;
            
            if (isNumberX)
                ElementMenu.style.left  = x + 'px';
            
            if (isNumberY)
                ElementMenu.style.top   = y - 14 + 'px';
        }
        
        function showMenuElement(x, y) {
            var beforeShow  = Options.beforeShow,
                name        = Options.name,
                params      = {
                    x       : x,
                    y       : y,
                    name    : name
                },
{'fraction_non_alphanumeric': 0.08672331706141144, 'fraction_numerical': 0.0004821310191044416, 'mean_word_length': 0.7316080559323802, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '163640', 'n_tokens_mistral': 3752, 'n_tokens_neox': 3583, 'n_words': 670}