<commit_before>/* 
  TTTTTTTTTTT        OOOOOOO       CCCCCCCCC        AAA        SSSSSSSS       
  TTTTTTTTTTT       OOOOOOOOO     CCCCCCCCCC      AA  AA     SSSSSSSSS
     TTT          OO       OO   CCCC           AAA   AAA    SS
    TTT         OO       OO   CCCC            AAAAAAAAAA     SSSSSSSS            ver. 1.1.9.9
   TTT        OO       OO   CCCC            AAA     AAA            SS
  TTT        OOOOOOOOO     CCCCCCCCCCC    AAA      AAA     SSSSSSSSS   
  TTT        OOOOOOO       CCCCCCCCCC   AAA       AAA     SSSSSSSS     
  
                      Here Comes Another World.

                TeaMeow / Open / Colorful / A.S.O / Simple
                茶葉貓   / 開闊 /  多彩多姿 / 藍.白.澄 / 簡潔
              
              
                            Basic colors
                                
                   A oi    -    Blue     -    #00ADEA
                   S hiroi -    White    -    #FFFFFF
                   O renji -    Orange   -    #FFA500        
                   
                         Object of elements
                         
             ts_eventHandler      -      store event handlers.
             ts_longPressTimer    -      store the timer of longpress detection.
*/

/**
 * For someone who think I'm copy other one's source code,
 * here comes the list which I used A LITTLE PART OF their source code.
 *
 * 給那些誰認為我是抄襲他人原始碼的，
 * 這裡是一份我用了它們「少部分」原始碼的來源清單。
 *
 * We used a little part of, yes, A LITTLE PART OF :
 * ZeptoJS     - zeptojs.com
 * Serialize   - code.google.com/p/form-serialize/downloads/list
 * AvgColor    - http://tech.mozilla.com.tw/posts/5355/%E5%9C%A8-firefox-os-%E5%8F%96%E5%9C%96%E7%89%87%E8%89%B2%E5%BD%A9%E5%B9%B3%E5%9D%87%E5%80%BC%E4%B9%8B%E4%BA%8C%E4%B8%89%E4%BA%8B
 * Library     - youmightnotneedjquery.com/
 */



/**
 * Tocas Main Library
 *
 * The main tocas code.
 */

var Tocas = (function ()
{
    var $, EmptyArray = [], Slice = EmptyArray.slice, Filter = EmptyArray.filter, Queue = []
    tocas = {}
    isArray = Array.isArray || function(Obj){ return Obj instanceof Array }
    isObject = function(Obj){ return Obj instanceof Object }
    
    isEmptyOrWhiteSpace = function(Str){ return str === null || str.match(/^\s*$/) !== null }

    /** Filter those thing which is we don't need it */
    function Compact(Array){ return Filter.call(Array, function(Item){ return Item != null }) }

    tocas.Init = function(Selector)
    {
        var Dom
        /** If Selector is a normal string */
        if(typeof Selector == 'string')
        {
            /** Remove the space */
            Selector = Selector.trim()
            Dom = tocas.Select(document, Selector)
        }
        else if(tocas.IsTocas(Selector)) return Selector
        else
        {
            /** Filter for eq function */
            if(isArray(Selector))
                Dom = Compact(Selector)
            /** If Selector is object, which means it may generated by Tocas */
            else if(isObject(Selector))
                Dom = [Selector], Selector = null
        }
        return tocas.Tocas(Dom, Selector)
    }
    
    tocas.IsTocas = function(Obj)
    {
        return Obj instanceof tocas.Tocas
    }
    
    tocas.Select = function(Element, Selector)
    {
        try
        {
            return Slice.call(Element.querySelectorAll(Selector))
        }
        catch(e)
        {
            console.log('TOCAS ERROR: Something wrong while selecting ' + Selector + ' element.')
        }
    }
                  
    tocas.Tocas = function(Dom, Selector)
    {
        Dom = Dom || []
        Dom.__proto__ = $.fn
        Dom.Selector = Selector || ''
        return Dom
    }
    
    
    
    
    /**
     * $
     *
     * Call to Init to get everything ready.
     */
    
    $ = function(Selector)
    {
        return tocas.Init(Selector)
    };
    
    
    
    
    /**
     * Library
     */
    
    $.fn =
    {
        /**
         * Each
         */
        
        each: function(Callback)
        {
            EmptyArray.every.call(this, function(Index, Element)
            {
                return Callback.call(Index, Element, Index) !== false
            })
            
            return this
        },
        
        
        
        
        /**
         * Slice
         */
        
        slice: function()
        {
            /** Regenerate a new object */
            return $(Slice.apply(this, arguments))
        },

        
        
        
        /**
         * Eq
         *
         * Jump to target element.
         */
        
        eq: function(Index)
        {
            return this.slice(Index, + Index + 1)
        },
     
        
        
        
        /**
         * Hide
         */
        
        hide: function()
        {
            return this.css('display', 'none')
        },
 
        
        
        
        /**
         * Show
         */
        
        show: function(Display)
        {
            Display = Display || 'block'
            return this.css('display', Display)
        },
        
        
        
        
        /**
         * Toggle
         *
         * When it's showed, we hide it, but if it's hidden, then you should know it.
         */
        
        toggle: function(Display)
        {
            Display = Display || null
            return this.each(function()
            {
                if($(this).getCSS('display') != 'none')
                    return $(this).hide()
                else
                    return $(this).show(Display)
            })
        },
        
        
        
        
        /**
         * Get CSS
         */
    
        getCSS: function(Property)
        {
            /** Get computed style */
            try
            {
                return 0 in this ? document.defaultView.getComputedStyle(this[0], null).getPropertyValue(Property) : null
            }
            catch(Err)
            {
                return null
            }
        },
        
        
        
        
        /**
         * Text
         *
         * Set textContent.
         */
    
        text: function(Text)
        {
            Text = Text || null;
            return this.each(function()
            {
                this.textContent = Text
            })
        },
        
        
        
        
        /**
         * HTML
         *
         * Set HTML if variable is not empty, otherwise we get the HTML content.
         */
    
        html: function(HTML)
        {
            HTML = HTML || null
            if(!HTML)
                return 0 in this ? this[0].innerHTML : null
            else 
                return this.each(function(){ this.innerHTML = HTML })
        },
        
        
        
        
        /**
         * Empty
         *
         * Clean value or innerHTML.
         */
        
        empty: function()
        {
            return this.each(function()
            {
                if(this.innerHTML != 'undefined') this.innerHTML = ''
                if(this.value != 'undefined')     this.value = ''
            })
        },

        
        
        
        /**
         * Val
         *
         * Set the value of element or get a value if Value is null.
         */
        
        val: function(Value)
        {
            if(Value == null)
            {
                if(0 in this)
                {
                    /** Return the value based on selected option if it's a select element*/
                    if(this[0].nodeName == 'SELECT')
                        return this[0].options[this[0].selectedIndex].value
                    else
                        return this[0].value
                }
                else
                {
                    return null
                }
            }
            else 
            {
                return this.each(function(){ this.value = Value })
            }
        },
        
        
        
        
        /**
         * On
         *
         * Add an event into the handler list.
         */
        
        on: function(EventName, Selector, Handler, Once)
        {
            Once = Once || false
            var HasSelector = true
            
            if(typeof Selector !== 'string')
            {
                HasSelector = false
                Handler     = Selector
            }
            
            if(typeof Handler !== 'function') Once = Handler
            
            /**
             * [ts_eventHandler]
             *
             *        registered   :bool
             *      /
             * Click      func :func
             *      \   /
             *       [0] 
             *          \
             *            once :bool         
             */
            
            return this.each(function()
            {
                if(typeof this.addEventListener == 'undefined')
                {
                    console.log('TOCAS ERROR: Event listener is not worked with this element.')
                    return false
                }
                /** If the main event list of the element is not existed, we create one */
                if(typeof this.ts_eventHandler == 'undefined') this.ts_eventHandler = {}
                /** Split the event by space */
                var Events = EventName.split(' ')
                
                for(var i in Events)
                {
                    var Event = Events[i]
                    
                    /** If the event handler list is not existed, we create an object, we will store function in here */
                    /** so if someone triggered the event, we can just call this list. */
                    if(typeof this.ts_eventHandler[Event] == 'undefined') this.ts_eventHandler[Event] = {registered: false, list: []}
                    
                    /** Bind if haven't bind yet */
                    if(this.ts_eventHandler[Event].registered === false)
                    {
                        this.addEventListener(Event, function(evt)
                        {
                            /** Just make sure this event still existed */
                            if(typeof this.ts_eventHandler[Event] != 'undefined')
                            {
                                /** Execute all of the functions */
                                for(var e in this.ts_eventHandler[Event].list)
                                {
                                    /** If there's a selector */
                                    if(typeof this.ts_eventHandler[Event].list[e].selector !== 'undefined')
                                    {
                                        var InSelector = false
                                        
                                        /** If this element is in the selector, then we set InSelector as true */
                                        $(this.ts_eventHandler[Event].list[e].selector).each(function(i, el)
                                        {
                                            if(evt.target === el) InSelector = true
                                        })
                                        
                                        /** We won't call this function if this elements which is triggered is not in the selector */
                                        if(!InSelector) return
                                    }
                                
                                    /** Execute */
                                    this.ts_eventHandler[Event].list[e].func.call(this, evt)
                                    
                                    /** If "once" is true, we remove it after call it */
                                    if(this.ts_eventHandler[Event].list[e].once)
                                        delete this.ts_eventHandler[Event].list[e]
                                }
                            }
                        })
                        this.ts_eventHandler[Event].registered = true
                    }
                    
                    /** Push handler or anonymous function into that event list */
                    var eventHandler = this.ts_eventHandler[Event].list,
                        Data = {func: Handler, once: Once}
                    /** Store the selector if there's selector */     
                    if(HasSelector) Data.selector = Selector
                        
                    /** Store the function info*/
                    eventHandler.push(Data)
                    this.ts_eventHandler[Event].list = eventHandler
                }
            })
        },
        

        
        
        /**
         * One
         *
         * Something that only happens once, for example: your life.
         */
        
        one: function(EventName, Selector, Handler)
        {   
            return this.each(function()
            {
                /** Set "once" true, it will auto remove once we call it */
                $(this).on(EventName, Selector, Handler, true)
            })
        },
        
        
        
        
        /**
         * Off
         *
         * Remove an event handler.
         */
        
        off: function(EventName, Handler)
        {
            return this.each(function()
            {
                /** No list no talk */
                if(typeof this.ts_eventHandler == 'undefined') return
                if(typeof this.ts_eventHandler[EventName] == 'undefined') return

                /** If there's no handler name, we remove all handler */
                if(Handler == null){ this.ts_eventHandler[EventName].list = []; return; }
                
                /** Otherwise we search for the index of function, then remove it */
                for(var e in this.ts_eventHandler[EventName].list)
                    if(Handler === this.ts_eventHandler[EventName].list[e].func) delete this.ts_eventHandler[EventName].list[e]
            })
        },
        
        
        
        
        /**
         * Ready
         *
         * Execute function after load complete.
         */
        
        ready: function(Callback)
        {
            if(0 in this)
                //if($.inArray(this['Selector'], ['document', 'body'])
                this[0].addEventListener('DOMContentLoaded', Callback)
        },
        
        
        
        /**
         * Load
         *
         * Load a html by XHR, then push the content to this element.
         */
        
        load: function(URL, Data, Callback)
        {
            if(!this.length) return this
            
            return this.each(function()
            {
                var that = this,
                    Options = {type: 'POST',
                               url: URL,
                               dataType: 'html',
                               data: Data},
                    /** Split URL to two parts, first one is the URL, second one is the selector */
                    Split = URL.split(/\s/), Selector
                
                /** If selector is existed, then we get it */
                if(Split.length > 1) Options.url = Split[0], Selector = Split[1] 
                
                Options.success = function(Result)
                {
                    var ScriptTag = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi

                    /** Replace the html, use selector if existed */
                    $(that).html(Selector ? $(document.createElement('div')).html(Result.replace(ScriptTag, ' ')).find(Selector).html() : Result)
                }
                
                $.ajax(Options)
            })
        },
        
        
        
       /**
         * Events
         */
        
        mousedown: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmousedown = Callback; })
        },
        mouseup: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmouseup = Callback; })
        },
        mousemove: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmousemove = Callback; })
        },
        click: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onclick = Callback(); })
        },
        dragstart: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.ondragstart = Callback; })
        },
        longpress: function(Callback, ClickCallback, Timer)
        {
            /** If callback is not an number, which means it must be a function */
            if(!isNaN(ClickCallback)) Timer = ClickCallback
                                      Timer = Timer || 500
            
            return this.each(function()
            {
                $(this).mousedown(function(event)
                {
                    var that = this
                    /** Haven't trigger long press yet, so we set this to false */
                    that.ts_longPressed = false
                    this.ts_longPressTimer = setTimeout(function()
                    {
                        /** Call long press callback */
                        Callback.call(that)
                        /** Long press has been triggered */
                        that.ts_longPressed = true
                        
                    }, Timer)
                    return false
                })
                .mouseup(function(event)
                {
                    /** If it's not long press, we call the 'click' callback */
                    if(!this.ts_longPressed) if(typeof ClickCallback !== 'undefined') ClickCallback.call(this)
                    
                    clearTimeout(this.ts_longPressTimer)
                    return false
                })
                .mousemove(function(event)
                { 
                    clearTimeout(this.ts_longPressTimer)
                    return false
                })
            })
        },
        click: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onclick = Callback })
        },
        
        
        
        
        /**
         * Trigger
         *
         * trigger an element by specific event.
         */
        
        trigger: function(Event)
        {
            return this.each(function(){ this[Event]() })
        },
        
        
        
        /**
         * From Bottom
         *
         * How long did we away from the bottom? 
         */
        
        scrollBottom: function(Scroll, ReachBottom)
        {
            $(this).on('scroll', function()
            {
                var Distance = this.scrollHeight - this.scrollTop - this.clientHeight
                
                /** Call ReachBottom if user scroll to the bottom */
                if(typeof Scroll !== 'undefined' || Scroll != null) Scroll.call(this, Distance) //Pass distance from the bottom to the function.
                    
                /** Call ReachBottom if user scroll to the bottom */
                if(Distance == 0 && typeof ReachBottom !== 'undefined') ReachBottom.call(this, Distance)
            })
        },
        
        
        
        
        /**
         * Has Class
         */
        
        hasClass: function(Class)
        {
            if(0 in this)
                if(this[0].classList)
                    return this[0].classList.contains(Class)
                else
                    return new RegExp('(^| )' + Class + '( |$)', 'gi').test(this[0].className)
        },
        
        
        
        /**
         * Class List
         */
        
        classList: function()
        {
            var Classes = []
            
            if(0 in this)
                if(this[0].classList)
                    for(var i=0; i<this[0].classList.length; i++)
                        Classes.push(this[0].classList[i])
                else
                    for(var i in this[0].className.split(' '))
                        Classes.push(this[0].className.split(' ')[i])
                        
            return Classes
        },
        
        
        
        /**
         * Add Class
         */
        
        addClass: function(Class)
        {
            return this.each(function()
            {
                List = Class.split(' ')
                for(var i in List)
                {
                    if(this.classList)
                    {
                        this.classList.add(List[i]) 
                    }
                    else
                    {
                        this.className += ' ' + List[i]
                    }
                }
            })
        },
   
        
                             
        
        /**
         * Remove Class
         */
        
        removeClass: function(Class)
        {
            return this.each(function()
            {
                if(!Class)
                {
                    this.className = ''
                }
                else
                {
                    List = Class.split(' ')
                    for(var i in List)
                    {
                        /** If there's classList, the just remove it from classList, otherwise we replace the string which is in the (class="")*/
                        if(this.classList)
                            this.classList.remove(List[i]) 
                        else if(typeof this.className !== 'undefined')
                            this.className = this.className.replace(new RegExp('(^|\\b)' + Class.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
                    }
                }
            })
        },
                             
        
                             
        
        /**
         * Toggle Class
         */
        
        toggleClass: function(Class)
        {
            return this.each(function()
            {
                var List, Index
                
                List = Class.split(' ')
                for(var i in List)
                {
                    if(this.classList)
                    {
                        this.classList.toggle(List[i])
                    }
                    else
                    {
                        /** Split the class */
                        ObjClassList = this.className.split(' ')
                        /** Is the class in class list already? */
                        Index = List.indexOf(List[i])

                        /** If already existed, we remove it, otherwise we add it */
                        if(Index >= 0)
                            ObjClassList.splice(Index, 1)
                        else
                            ObjClassList.push(List[i])

                        this.className = List[i].join(' ')
                    }
                }
            })
        },
        
        
        
        
        /**
         * Append
         * 
         * Insert new content behind the HTML.
         */
    
        append: function(HTML)
        {
            if(HTML != null && typeof HTML == 'object')
                return this.each(function(){ this.appendChild(HTML) })
            else if(HTML != null)
                return this.each(function(){ this.innerHTML += HTML })
        },
        
        after: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.insertAdjacentHTML('afterend', HTML) })
        },
        
        before: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.insertAdjacentHTML('beforeBegin', HTML) })
        },
        
        prepend: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.parentNode.insertBefore(HTML, this.nextSibling) })
        },
        
        prependTo: function(Selector)
        {
            return this.each(function()
            {
               
                var that = this
                $(Selector).each(function()
                {
                    
                    this.appendChild(that, this.nextSibling);  
                })
            })
        },
    
        
        
        
        /**
         * Clone
         *
         * Copy an element or an node.
         */
        
        clone: function(Deep)
        {
            /** Copy child too? */
            Deep = (typeof Deep == 'undefined') ? true : Deep;

            var CloneList = []
            
            /** Clone the elements */
            this.each(function()
            {
                CloneList.push(this.cloneNode(Deep))
            })

            /** Using the elements which we cloned */
            return $(CloneList)
        },
        
        
        
        
        /**
         * Remove
         */

        remove: function()
        {
            return this.each(function(){ this.parentNode.removeChild(this) })
        },
        
        
        
        
        /**
         * Parent
         */

        parent: function()
        {
            return 0 in this ? $(this[0].parentNode) : null
        },
        

        
        
        /**
         * Children
         */
        
        children: function()
        {
            var List = []
                
            this.each(function(i, el)
            { 
                /** Get child nodes */
                var ChildNodes = el.childNodes
                /** Push the child nodes to the list*/
                List.push.apply(List, ChildNodes)
            })
            
            /** Return the list with $ */
            return $(List)
        },
        
        
        
        
        /**
         * Find
         */
        
        find: function(Selector)
        {
            var List = []
            
            this.each(function(i, el)
            { 
                /** Push the child nodes to the list*/
                List.push.apply(List, el.querySelectorAll(Selector))
            })
        
            /** Return the list with $ */
            return $(List)
        },
        
        
        
        
        /**
         * Attr
         *
         * Set attr when value is not empty, otherwise we get the attr value.
         */
    
        attr: function(Attr, Value)
        {
            //if(typeof this.setAttribute !== 'function') return null
            
            Value = Value || null
            
            /** Set multiple Attr if Attr is object */
            if(typeof Attr === 'object' && !Value)
                return this.each(function(){ for(var i in Attr) this.setAttribute(i, Attr[i])})
            
            /** Set single attr */
            else if(Attr != null && Value != null)
                return this.each(function(){ this.setAttribute(Attr, Value) })

            /** Get single attr only if Attr is not null */
            else if(Attr != null && !Value)
                return 0 in this ? this[0].getAttribute(Attr) : null
            
            /** Or return all attrs */
            /*else
                var AttrObject = {}
                alert(Object.keys(this[0].attributes[0]))*/
        },
        
        
        
        
        /**
         * CSS Animate
         */

        cssAnimate: function(Animate, Callback, Time)
        {            
            /** If someone using callback field as time.. */
            if(typeof Callback == 'number') Time = Callback
            
            /** Turn millionsecond to float (ex: 300 -> 0.3), then turn float to string and remove the dot (0.3 -> 03)*/
            var Timer = (Time / 1000).toString().replace('.', '')
            
            /** Select animation duration by Time */      
            Time = (typeof Time !== 'undefined') ? ' animated' + Timer + 's' : ''
            
            return this.each(function()
            {
                /** For passing $(this) to inside function */
                var that = this
                
                /** If last animation not end .. */
                if($(this).hasClass(Animate))
                    $(this).off('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend').removeClass(Animate + ' animated' + Time)
                
                /** Add animation */
                $(this).addClass(Animate + ' animated' + Time)
                       /** Once the animation end, we remove the animate class and callback **/
                       .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function()
                       {
                           $(that).removeClass(Animate + ' animated' + Time)
                           if(typeof Callback !== 'undefined' && typeof Callback !== 'number') Callback.call(that) 
                        })
            })
        },
        
        
        
        
        /**
         * Parent
         */
        
        parent: function()
        {
            return 0 in this ? $(this[0].parentNode) : null
        },
        
        
        
        
        /**
         * Closest
         *
         * Get all the element with the selector, then check the element which we want to search for the closest thing is in the selector or not
         */
        
        closest: function(Selector)
        {
            var Selector = $(Selector),
                List     = []
            
            /** Loop for each element which is in the closest selector */
            for(var si = 0; si < Selector.length; si++)
            {
                /** Loop for the Tocas selector(not closest selector), */
                /** so we can collect all the closest containers if we select many of the main elements */
                this.each(function(i, el)
                {
                    /** Get the single element from the closest selector */
                    var Con = Selector[si]
                    
                    /** Now, we need to make sure this container contains the element */
                    if(Con.contains(el))
                        /** And it's the parent of the element */
                        /** Just make sure it's the parent of the element, not the parent's parent of the element or more further.. */
                        if(el.parentNode === Con)
                            /** And the element has been pushed in the List before */
                            if(List.indexOf(Con) == -1)
                                /** Then we push it to the list */
                                List.push(Con)
                })
            }
            
            return List.length ? $(List) : null
        },
         
        
        

        /**
         * CSS<commit_msg>fixed .closest(), and not testing with .contains()<commit_after>/* 
  TTTTTTTTTTT        OOOOOOO       CCCCCCCCC        AAA        SSSSSSSS       
  TTTTTTTTTTT       OOOOOOOOO     CCCCCCCCCC      AA  AA     SSSSSSSSS
     TTT          OO       OO   CCCC           AAA   AAA    SS
    TTT         OO       OO   CCCC            AAAAAAAAAA     SSSSSSSS            ver. 1.1.9.9.1
   TTT        OO       OO   CCCC            AAA     AAA            SS
  TTT        OOOOOOOOO     CCCCCCCCCCC    AAA      AAA     SSSSSSSSS   
  TTT        OOOOOOO       CCCCCCCCCC   AAA       AAA     SSSSSSSS     
  
                      Here Comes Another World.

                TeaMeow / Open / Colorful / A.S.O / Simple
                茶葉貓   / 開闊 /  多彩多姿 / 藍.白.澄 / 簡潔
              
              
                            Basic colors
                                
                   A oi    -    Blue     -    #00ADEA
                   S hiroi -    White    -    #FFFFFF
                   O renji -    Orange   -    #FFA500        
                   
                         Object of elements
                         
             ts_eventHandler      -      store event handlers.
             ts_longPressTimer    -      store the timer of longpress detection.
*/

/**
 * For someone who think I'm copy other one's source code,
 * here comes the list which I used A LITTLE PART OF their source code.
 *
 * 給那些誰認為我是抄襲他人原始碼的，
 * 這裡是一份我用了它們「少部分」原始碼的來源清單。
 *
 * We used a little part of it, yes, A LITTLE PART OF :
 * ZeptoJS     - zeptojs.com
 * Serialize   - code.google.com/p/form-serialize/downloads/list
 * AvgColor    - http://tech.mozilla.com.tw/posts/5355/%E5%9C%A8-firefox-os-%E5%8F%96%E5%9C%96%E7%89%87%E8%89%B2%E5%BD%A9%E5%B9%B3%E5%9D%87%E5%80%BC%E4%B9%8B%E4%BA%8C%E4%B8%89%E4%BA%8B
 * Library     - youmightnotneedjquery.com/
 */



/**
 * Tocas Main Library
 *
 * The main tocas code.
 */

var Tocas = (function ()
{
    var $, EmptyArray = [], Slice = EmptyArray.slice, Filter = EmptyArray.filter, Queue = []
    tocas = {}
    isArray = Array.isArray || function(Obj){ return Obj instanceof Array }
    isObject = function(Obj){ return Obj instanceof Object }
    
    isEmptyOrWhiteSpace = function(Str){ return str === null || str.match(/^\s*$/) !== null }

    /** Filter those thing which is we don't need it */
    function Compact(Array){ return Filter.call(Array, function(Item){ return Item != null }) }

    tocas.Init = function(Selector)
    {
        var Dom
        /** If Selector is a normal string */
        if(typeof Selector == 'string')
        {
            /** Remove the space */
            Selector = Selector.trim()
            Dom = tocas.Select(document, Selector)
        }
        else if(tocas.IsTocas(Selector)) return Selector
        else
        {
            /** Filter for eq function */
            if(isArray(Selector))
                Dom = Compact(Selector)
            /** If Selector is object, which means it may generated by Tocas */
            else if(isObject(Selector))
                Dom = [Selector], Selector = null
        }
        return tocas.Tocas(Dom, Selector)
    }
    
    tocas.IsTocas = function(Obj)
    {
        return Obj instanceof tocas.Tocas
    }
    
    tocas.Select = function(Element, Selector)
    {
        try
        {
            return Slice.call(Element.querySelectorAll(Selector))
        }
        catch(e)
        {
            console.log('TOCAS ERROR: Something wrong while selecting ' + Selector + ' element.')
        }
    }
                  
    tocas.Tocas = function(Dom, Selector)
    {
        Dom = Dom || []
        Dom.__proto__ = $.fn
        Dom.Selector = Selector || ''
        return Dom
    }
    
    
    
    
    /**
     * $
     *
     * Call to Init to get everything ready.
     */
    
    $ = function(Selector)
    {
        return tocas.Init(Selector)
    };
    
    
    
    
    /**
     * Library
     */
    
    $.fn =
    {
        /**
         * Each
         */
        
        each: function(Callback)
        {
            EmptyArray.every.call(this, function(Index, Element)
            {
                return Callback.call(Index, Element, Index) !== false
            })
            
            return this
        },
        
        
        
        
        /**
         * Slice
         */
        
        slice: function()
        {
            /** Regenerate a new object */
            return $(Slice.apply(this, arguments))
        },

        
        
        
        /**
         * Eq
         *
         * Jump to target element.
         */
        
        eq: function(Index)
        {
            return this.slice(Index, + Index + 1)
        },
     
        
        
        
        /**
         * Hide
         */
        
        hide: function()
        {
            return this.css('display', 'none')
        },
 
        
        
        
        /**
         * Show
         */
        
        show: function(Display)
        {
            Display = Display || 'block'
            return this.css('display', Display)
        },
        
        
        
        
        /**
         * Toggle
         *
         * When it's showed, we hide it, but if it's hidden, then you should know it.
         */
        
        toggle: function(Display)
        {
            Display = Display || null
            return this.each(function()
            {
                if($(this).getCSS('display') != 'none')
                    return $(this).hide()
                else
                    return $(this).show(Display)
            })
        },
        
        
        
        
        /**
         * Get CSS
         */
    
        getCSS: function(Property)
        {
            /** Get computed style */
            try
            {
                return 0 in this ? document.defaultView.getComputedStyle(this[0], null).getPropertyValue(Property) : null
            }
            catch(Err)
            {
                return null
            }
        },
        
        
        
        
        /**
         * Text
         *
         * Set textContent.
         */
    
        text: function(Text)
        {
            Text = Text || null;
            return this.each(function()
            {
                this.textContent = Text
            })
        },
        
        
        
        
        /**
         * HTML
         *
         * Set HTML if variable is not empty, otherwise we get the HTML content.
         */
    
        html: function(HTML)
        {
            HTML = HTML || null
            if(!HTML)
                return 0 in this ? this[0].innerHTML : null
            else 
                return this.each(function(){ this.innerHTML = HTML })
        },
        
        
        
        
        /**
         * Empty
         *
         * Clean value or innerHTML.
         */
        
        empty: function()
        {
            return this.each(function()
            {
                if(this.innerHTML != 'undefined') this.innerHTML = ''
                if(this.value != 'undefined')     this.value = ''
            })
        },

        
        
        
        /**
         * Val
         *
         * Set the value of element or get a value if Value is null.
         */
        
        val: function(Value)
        {
            if(Value == null)
            {
                if(0 in this)
                {
                    /** Return the value based on selected option if it's a select element*/
                    if(this[0].nodeName == 'SELECT')
                        return this[0].options[this[0].selectedIndex].value
                    else
                        return this[0].value
                }
                else
                {
                    return null
                }
            }
            else 
            {
                return this.each(function(){ this.value = Value })
            }
        },
        
        
        
        
        /**
         * On
         *
         * Add an event into the handler list.
         */
        
        on: function(EventName, Selector, Handler, Once)
        {
            Once = Once || false
            var HasSelector = true
            
            if(typeof Selector !== 'string')
            {
                HasSelector = false
                Handler     = Selector
            }
            
            if(typeof Handler !== 'function') Once = Handler
            
            /**
             * [ts_eventHandler]
             *
             *        registered   :bool
             *      /
             * Click      func :func
             *      \   /
             *       [0] 
             *          \
             *            once :bool         
             */
            
            return this.each(function()
            {
                if(typeof this.addEventListener == 'undefined')
                {
                    console.log('TOCAS ERROR: Event listener is not worked with this element.')
                    return false
                }
                /** If the main event list of the element is not existed, we create one */
                if(typeof this.ts_eventHandler == 'undefined') this.ts_eventHandler = {}
                /** Split the event by space */
                var Events = EventName.split(' ')
                
                for(var i in Events)
                {
                    var Event = Events[i]
                    
                    /** If the event handler list is not existed, we create an object, we will store function in here */
                    /** so if someone triggered the event, we can just call this list. */
                    if(typeof this.ts_eventHandler[Event] == 'undefined') this.ts_eventHandler[Event] = {registered: false, list: []}
                    
                    /** Bind if haven't bind yet */
                    if(this.ts_eventHandler[Event].registered === false)
                    {
                        this.addEventListener(Event, function(evt)
                        {
                            /** Just make sure this event still existed */
                            if(typeof this.ts_eventHandler[Event] != 'undefined')
                            {
                                /** Execute all of the functions */
                                for(var e in this.ts_eventHandler[Event].list)
                                {
                                    /** If there's a selector */
                                    if(typeof this.ts_eventHandler[Event].list[e].selector !== 'undefined')
                                    {
                                        var InSelector = false
                                        
                                        /** If this element is in the selector, then we set InSelector as true */
                                        $(this.ts_eventHandler[Event].list[e].selector).each(function(i, el)
                                        {
                                            if(evt.target === el) InSelector = true
                                        })
                                        
                                        /** We won't call this function if this elements which is triggered is not in the selector */
                                        if(!InSelector) return
                                    }
                                
                                    /** Execute */
                                    this.ts_eventHandler[Event].list[e].func.call(this, evt)
                                    
                                    /** If "once" is true, we remove it after call it */
                                    if(this.ts_eventHandler[Event].list[e].once)
                                        delete this.ts_eventHandler[Event].list[e]
                                }
                            }
                        })
                        this.ts_eventHandler[Event].registered = true
                    }
                    
                    /** Push handler or anonymous function into that event list */
                    var eventHandler = this.ts_eventHandler[Event].list,
                        Data = {func: Handler, once: Once}
                    /** Store the selector if there's selector */     
                    if(HasSelector) Data.selector = Selector
                        
                    /** Store the function info*/
                    eventHandler.push(Data)
                    this.ts_eventHandler[Event].list = eventHandler
                }
            })
        },
        

        
        
        /**
         * One
         *
         * Something that only happens once, for example: your life.
         */
        
        one: function(EventName, Selector, Handler)
        {   
            return this.each(function()
            {
                /** Set "once" true, it will auto remove once we call it */
                $(this).on(EventName, Selector, Handler, true)
            })
        },
        
        
        
        
        /**
         * Off
         *
         * Remove an event handler.
         */
        
        off: function(EventName, Handler)
        {
            return this.each(function()
            {
                /** No list no talk */
                if(typeof this.ts_eventHandler == 'undefined') return
                if(typeof this.ts_eventHandler[EventName] == 'undefined') return

                /** If there's no handler name, we remove all handler */
                if(Handler == null){ this.ts_eventHandler[EventName].list = []; return; }
                
                /** Otherwise we search for the index of function, then remove it */
                for(var e in this.ts_eventHandler[EventName].list)
                    if(Handler === this.ts_eventHandler[EventName].list[e].func) delete this.ts_eventHandler[EventName].list[e]
            })
        },
        
        
        
        
        /**
         * Ready
         *
         * Execute function after load complete.
         */
        
        ready: function(Callback)
        {
            if(0 in this)
                //if($.inArray(this['Selector'], ['document', 'body'])
                this[0].addEventListener('DOMContentLoaded', Callback)
        },
        
        
        
        /**
         * Load
         *
         * Load a html by XHR, then push the content to this element.
         */
        
        load: function(URL, Data, Callback)
        {
            if(!this.length) return this
            
            return this.each(function()
            {
                var that = this,
                    Options = {type: 'POST',
                               url: URL,
                               dataType: 'html',
                               data: Data},
                    /** Split URL to two parts, first one is the URL, second one is the selector */
                    Split = URL.split(/\s/), Selector
                
                /** If selector is existed, then we get it */
                if(Split.length > 1) Options.url = Split[0], Selector = Split[1] 
                
                Options.success = function(Result)
                {
                    var ScriptTag = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi

                    /** Replace the html, use selector if existed */
                    $(that).html(Selector ? $(document.createElement('div')).html(Result.replace(ScriptTag, ' ')).find(Selector).html() : Result)
                }
                
                $.ajax(Options)
            })
        },
        
        
        
       /**
         * Events
         */
        
        mousedown: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmousedown = Callback; })
        },
        mouseup: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmouseup = Callback; })
        },
        mousemove: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onmousemove = Callback; })
        },
        click: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onclick = Callback(); })
        },
        dragstart: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.ondragstart = Callback; })
        },
        longpress: function(Callback, ClickCallback, Timer)
        {
            /** If callback is not an number, which means it must be a function */
            if(!isNaN(ClickCallback)) Timer = ClickCallback
                                      Timer = Timer || 500
            
            return this.each(function()
            {
                $(this).mousedown(function(event)
                {
                    var that = this
                    /** Haven't trigger long press yet, so we set this to false */
                    that.ts_longPressed = false
                    this.ts_longPressTimer = setTimeout(function()
                    {
                        /** Call long press callback */
                        Callback.call(that)
                        /** Long press has been triggered */
                        that.ts_longPressed = true
                        
                    }, Timer)
                    return false
                })
                .mouseup(function(event)
                {
                    /** If it's not long press, we call the 'click' callback */
                    if(!this.ts_longPressed) if(typeof ClickCallback !== 'undefined') ClickCallback.call(this)
                    
                    clearTimeout(this.ts_longPressTimer)
                    return false
                })
                .mousemove(function(event)
                { 
                    clearTimeout(this.ts_longPressTimer)
                    return false
                })
            })
        },
        click: function(Callback)
        {
            return this.each(function(){ if(!Callback) return false; this.onclick = Callback })
        },
        
        
        
        
        /**
         * Trigger
         *
         * trigger an element by specific event.
         */
        
        trigger: function(Event)
        {
            return this.each(function(){ this[Event]() })
        },
        
        
        
        /**
         * From Bottom
         *
         * How long did we away from the bottom? 
         */
        
        scrollBottom: function(Scroll, ReachBottom)
        {
            $(this).on('scroll', function()
            {
                var Distance = this.scrollHeight - this.scrollTop - this.clientHeight
                
                /** Call ReachBottom if user scroll to the bottom */
                if(typeof Scroll !== 'undefined' || Scroll != null) Scroll.call(this, Distance) //Pass distance from the bottom to the function.
                    
                /** Call ReachBottom if user scroll to the bottom */
                if(Distance == 0 && typeof ReachBottom !== 'undefined') ReachBottom.call(this, Distance)
            })
        },
        
        
        
        
        /**
         * Has Class
         */
        
        hasClass: function(Class)
        {
            if(0 in this)
                if(this[0].classList)
                    return this[0].classList.contains(Class)
                else
                    return new RegExp('(^| )' + Class + '( |$)', 'gi').test(this[0].className)
        },
        
        
        
        /**
         * Class List
         */
        
        classList: function()
        {
            var Classes = []
            
            if(0 in this)
                if(this[0].classList)
                    for(var i=0; i<this[0].classList.length; i++)
                        Classes.push(this[0].classList[i])
                else
                    for(var i in this[0].className.split(' '))
                        Classes.push(this[0].className.split(' ')[i])
                        
            return Classes
        },
        
        
        
        /**
         * Add Class
         */
        
        addClass: function(Class)
        {
            return this.each(function()
            {
                List = Class.split(' ')
                for(var i in List)
                {
                    if(this.classList)
                    {
                        this.classList.add(List[i]) 
                    }
                    else
                    {
                        this.className += ' ' + List[i]
                    }
                }
            })
        },
   
        
                             
        
        /**
         * Remove Class
         */
        
        removeClass: function(Class)
        {
            return this.each(function()
            {
                if(!Class)
                {
                    this.className = ''
                }
                else
                {
                    List = Class.split(' ')
                    for(var i in List)
                    {
                        /** If there's classList, the just remove it from classList, otherwise we replace the string which is in the (class="")*/
                        if(this.classList)
                            this.classList.remove(List[i]) 
                        else if(typeof this.className !== 'undefined')
                            this.className = this.className.replace(new RegExp('(^|\\b)' + Class.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
                    }
                }
            })
        },
                             
        
                             
        
        /**
         * Toggle Class
         */
        
        toggleClass: function(Class)
        {
            return this.each(function()
            {
                var List, Index
                
                List = Class.split(' ')
                for(var i in List)
                {
                    if(this.classList)
                    {
                        this.classList.toggle(List[i])
                    }
                    else
                    {
                        /** Split the class */
                        ObjClassList = this.className.split(' ')
                        /** Is the class in class list already? */
                        Index = List.indexOf(List[i])

                        /** If already existed, we remove it, otherwise we add it */
                        if(Index >= 0)
                            ObjClassList.splice(Index, 1)
                        else
                            ObjClassList.push(List[i])

                        this.className = List[i].join(' ')
                    }
                }
            })
        },
        
        
        
        
        /**
         * Append
         * 
         * Insert new content behind the HTML.
         */
    
        append: function(HTML)
        {
            if(HTML != null && typeof HTML == 'object')
                return this.each(function(){ this.appendChild(HTML) })
            else if(HTML != null)
                return this.each(function(){ this.innerHTML += HTML })
        },
        
        after: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.insertAdjacentHTML('afterend', HTML) })
        },
        
        before: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.insertAdjacentHTML('beforeBegin', HTML) })
        },
        
        prepend: function(HTML)
        {
            if(HTML != null) return this.each(function(){ this.parentNode.insertBefore(HTML, this.nextSibling) })
        },
        
        prependTo: function(Selector)
        {
            return this.each(function()
            {
               
                var that = this
                $(Selector).each(function()
                {
                    
                    this.appendChild(that, this.nextSibling);  
                })
            })
        },
    
        
        
        
        /**
         * Clone
         *
         * Copy an element or an node.
         */
        
        clone: function(Deep)
        {
            /** Copy child too? */
            Deep = (typeof Deep == 'undefined') ? true : Deep;

            var CloneList = []
            
            /** Clone the elements */
            this.each(function()
            {
                CloneList.push(this.cloneNode(Deep))
            })

            /** Using the elements which we cloned */
            return $(CloneList)
        },
        
        
        
        
        /**
         * Remove
         */

        remove: function()
        {
            return this.each(function(){ this.parentNode.removeChild(this) })
        },

        
        
        
        /**
         * Children
         */
        
        children: function()
        {
            var List = []
                
            this.each(function(i, el)
            { 
                /** Get child nodes */
                var ChildNodes = el.childNodes
                /** Push the child nodes to the list*/
                List.push.apply(List, ChildNodes)
            })
            
            /** Return the list with $ */
            return $(List)
        },
        
        
        
        
        /**
         * Find
         */
        
        find: function(Selector)
        {
            /** The selector must be string */
            if(typeof Selector !== 'string')
                return null
            
            var List = []

            this.each(function(i, el)
            { 
                /** Push the child nodes to the list*/
                List.push.apply(List, el.querySelectorAll(Selector))
            })
        
            /** Return the list with $ */
            return List.length ? $(List) : null
        },
        
        
        
        
        /**
         * Attr
         *
         * Set attr when value is not empty, otherwise we get the attr value.
         */
    
        attr: function(Attr, Value)
        {
            //if(typeof this.setAttribute !== 'function') return null
            
            Value = Value || null
            
            /** Set multiple Attr if Attr is object */
            if(typeof Attr === 'object' && !Value)
                return this.each(function(){ for(var i in Attr) this.setAttribute(i, Attr[i])})
            
            /** Set single attr */
            else if(Attr != null && Value != null)
                return this.each(function(){ this.setAttribute(Attr, Value) })

            /** Get single attr only if Attr is not null */
            else if(Attr != null && !Value)
                return 0 in this ? this[0].getAttribute(Attr) : null
            
            /** Or return all attrs */
            /*else
                var AttrObject = {}
                alert(Object.keys(this[0].attributes[0]))*/
        },
        
        
        
        
        /**
         * CSS Animate
         */

        cssAnimate: function(Animate, Callback, Time)
        {            
            /** If someone using callback field as time.. */
            if(typeof Callback == 'number') Time = Callback
            
            /** Turn millionsecond to float (ex: 300 -> 0.3), then turn float to string and remove the dot (0.3 -> 03)*/
            var Timer = (Time / 1000).toString().replace('.', '')
            
            /** Select animation duration by Time */      
            Time = (typeof Time !== 'undefined') ? ' animated' + Timer + 's' : ''
            
            return this.each(function()
            {
                /** For passing $(this) to inside function */
                var that = this
                
                /** If last animation not end .. */
                if($(this).hasClass(Animate))
                    $(this).off('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend').removeClass(Animate + ' animated' + Time)
                
                /** Add animation */
                $(this).addClass(Animate + ' animated' + Time)
                       /** Once the animation end, we remove the animate class and callback **/
                       .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function()
                       {
                           $(that).removeClass(Animate + ' animated' + Time)
                           if(typeof Callback !== 'undefined' && typeof Callback !== 'number') Callback.call(that) 
                        })
            })
        },
        
        
        
        
        /**
         * Parent
         */
        
        parent: function()
        {
            return 0 in this ? $(this[0].parentNode) : null
        },
        
        
        
        
        /**
         * Closest
         *
         * Get all the element with the selector, then check the element which we want to search for the closest thing is in the selector or not
         */
        
        closest: function(Selector)
        {
            var that     = this,
                Selector = $(Selector)

            /** Non stop loop, until there's no parent of the element */
            while(true)
            {     
                /** Not this one, we go upper */
                that = $(that).parent()[0]

                /** No parent? */
                if(!that) return null;
                
                /** Is the parent in the closest selector? If it do, then the parent is the closest element which we want */
                if(Array.prototype.indexOf.call(Selector, that) !== -1)
                    return $(that)
            }
        },
         
        
        
        
        /**
         * Contains
         *
         * Is the node contains something we want?
         */
        
        contains: function(Wants)
        {
            var Selector = $(Wants),
                IsTrue   = false

            this.each(function(i, el)
            {
                var ChildNodes = el.childNodes
                
                for(var si = 0; si < Selector.length; si++)
                {
                    if(Array.prototype.indexOf.call(ChildNodes, Selector[si]) != -1)
                        IsTrue = true
                }
            })

            return IsTrue
        },
        

        /**
         * CSS
{'fraction_non_alphanumeric': 0.09706034706034707, 'fraction_numerical': 0.003642191142191142, 'mean_word_length': 0.9103531449069207, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 32, 'word_list_counts': {'cursed_substrings.json': 64, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3325670', 'n_tokens_mistral': 15348, 'n_tokens_neox': 14539, 'n_words': 3560}