<commit_before>'use strict'; /* global screenfull */

if (screenfull.enabled) {
    document.addEventListener(screenfull.raw.fullscreenchange, () => {
        if (screenfull.isFullscreen)
            screenfull.element.classList.add('is-fullscreen');
        else
            document.querySelector('.is-fullscreen').classList.remove('is-fullscreen');
    });

    document.addEventListener(screenfull.raw.fullscreenerror, () =>
        document.body.classList.add('no-fullscreen'));
} else
    document.body.classList.add('no-fullscreen');

let RPC = function(url, ...objects) {
    let cbs_by_id   = {};
    let cbs_by_code = {};
    let id = 0;

    let socket = new WebSocket(url);
    let self = {
        send: (method, ...params) => {
            return new Promise((resolve, reject) => {
                socket.send(JSON.stringify({ jsonrpc: '2.0', id, method, params }));
                cbs_by_id[id] = { resolve, reject };
                id = (id + 1) & 0x7FFF;
            });
        },

        callback: (code, cb) => {
            if (cb === undefined)
                delete cbs_by_code[code];
            else
                cbs_by_code[code] = cb;
        },
    };

    socket.onopen = () => {
        for (let object of objects)
            object.onLoad(self);
    };

    socket.onclose = (ev) => {
        for (let object of objects)
            object.onUnload();
    };

    socket.onmessage = (ev) => {
        let msg = JSON.parse(ev.data);

        if (msg.id === undefined) {
            if (msg.method in cbs_by_code)
                cbs_by_code[msg.method](...msg.params);
            else
                console.log('unhandled notification', msg);
        }

        if (msg.id in cbs_by_id) {
            let cb = cbs_by_id[msg.id];
            delete cbs_by_id[msg.id];
            if (msg.error === undefined)
                cb.resolve(msg.result);
            else
                cb.reject(msg.error);
        }
    };

    return self;
};

let ViewNode = function (root, info, stream) {
    let rpc    = null;
    let view   = root.querySelector('video');
    let status = root.querySelector('.status');
    let volume = root.querySelector('.volume');

    let onVolumeSelect = (e) => {
        e.preventDefault();
        let r = volume.getBoundingClientRect();
        let x = Math.min(r.right, Math.max(r.left, e.touches ? e.touches[0].clientX : e.clientX));
        view.volume = (x - r.left) / (r.right - r.left);
    };

    let onVolumeChange = (v, muted) => {
        let e = volume.querySelector('.slider');
        let r = volume.getBoundingClientRect();
        e.style.left = `${v * (r.right - r.left)}px`;
        e.style.top = `${(1 - v) * (r.bottom - r.top)}px`;
        if (muted)
            root.classList.add('muted');
        else
            root.classList.remove('muted');
    };

    let onTimeUpdate = (t) => {
        // let leftPad = require('left-pad');
        status.textContent = `${(t / 60)|0}:${t % 60 < 10 ? '0' : ''}${(t|0) % 60}`;
    };

    let onDone = () => {
        root.setAttribute('data-status',
            view.error === null || view.error.code === 4 ? 'ended' : 'error');
        status.textContent = view.error === null   ? 'stream ended'
                           : view.error.code === 1 ? 'aborted'
                           : view.error.code === 2 ? 'network error'
                           : view.error.code === 3 ? 'decoding error'
                           : /* view.error.code === 4 ? */ 'stream ended';
    };

    let onLoad = () => {
        root.setAttribute('data-status', 'loading');
        status.textContent = 'loading';
    };

    let onPlay = () => {
        root.setAttribute('data-status', 'playing');
        status.textContent = 'playing';
    };

    let hideCursorTimeout = null;
    let hideCursorLater = () => {
        showCursor();
        hideCursorTimeout = window.setTimeout(() => {
            hideCursorTimeout = null;
            root.classList.add('hide-cursor');
        }, 3000);
    };

    let showCursor = () => {
        if (hideCursorTimeout !== null)
            window.clearTimeout(hideCursorTimeout);
        else
            root.classList.remove('hide-cursor');
        hideCursorTimeout = null;
    };

    view.addEventListener('loadstart',      onLoad);
    view.addEventListener('loadedmetadata', onPlay);
    view.addEventListener('error',          onDone);
    view.addEventListener('ended',          onDone);
    view.addEventListener('timeupdate', () => onTimeUpdate(view.currentTime));
    view.addEventListener('volumechange', () => onVolumeChange(view.volume, view.muted));
    // TODO playing, waiting, stalled (not sure whether these events are actually emitted)

    view.addEventListener('mouseenter', hideCursorLater);
    view.addEventListener('mouseleave', showCursor);
    view.addEventListener('mouseenter', () =>
        view.addEventListener('mousemove', hideCursorLater));
    view.addEventListener('mouseleave', () =>
        view.removeEventListener('mousemove', hideCursorLater));

    volume.addEventListener('mousedown',  onVolumeSelect);
    volume.addEventListener('touchstart', onVolumeSelect);
    volume.addEventListener('touchmove',  onVolumeSelect);
    volume.addEventListener('mousedown', (e) =>
        volume.addEventListener('mousemove', onVolumeSelect));
    volume.addEventListener('mouseup', () =>
        volume.removeEventListener('mousemove', onVolumeSelect));
    volume.addEventListener('mouseleave', () =>
        volume.removeEventListener('mousemove', onVolumeSelect));
    onVolumeChange(view.volume, view.muted);

    root.querySelector('.mute').addEventListener('click', () => {
        view.muted = !view.muted;
    });

    root.querySelector('.theatre').addEventListener('click', () =>
        document.body.classList.add('theatre'));

    root.querySelector('.fullscreen').addEventListener('click', () =>
        screenfull.request(root));

    root.querySelector('.collapse').addEventListener('click', () => {
        document.body.classList.remove('theatre');
        screenfull.exit();
    });

    onLoad();
    return {
        onLoad: (socket) => {
            rpc = socket;
            rpc.callback('Stream.ViewerCount', (n) => {
                info.querySelector('.viewers').textContent = n;
            });
            // TODO measure connection speed, request a stream
            view.src = `/stream/${stream}`;
            view.play();
        },

        onUnload: () => {
            rpc = null;
            onDone();
        },
    };
};

let ChatNode = function (root) {
    let form = root.querySelector('.input-form');
    let text = form.querySelector('.input');
    let log  = root.querySelector('.log');
    let msg  = root.querySelector('.message-template');
    let rpc  = null;

    text.addEventListener('keydown', (ev) =>
        (ev.keyCode === 13 && !ev.shiftKey ? ev.preventDefault() : null));

    text.addEventListener('keyup', (ev) =>
        (ev.keyCode === 13 && !ev.shiftKey ?
            form.dispatchEvent(new Event('submit', {cancelable: true})) : null));

    form.addEventListener('submit', (ev) => {
        ev.preventDefault();
        if (rpc && text.value) {
            rpc.send('Chat.SendMessage', text.value).then(() => {
                log.scrollTop = log.scrollHeight;
                text.value = '';
                text.focus();
            });
        }
    });

    let lform = root.querySelector('.login-form');
    let login = lform.querySelector('.input');

    lform.addEventListener('submit', (ev) => {
        ev.preventDefault();
        if (rpc && login.value) {
            rpc.send('Chat.SetName', login.value);
        }
    });

    return {
        onLoad: (socket) => {
            rpc = socket;
            rpc.callback('Chat.Message', (name, text) => {
                let rect = log.getBoundingClientRect();
                let scroll = log.scrollTop + (rect.bottom - rect.top) >= log.scrollHeight;
                let entry = document.importNode(msg.content, true);
                entry.querySelector('.name').textContent = name;
                entry.querySelector('.text').textContent = text;
                log.appendChild(entry);
                if (scroll)
                    log.scrollTop = log.scrollHeight;
            });

            rpc.callback('Chat.AcquiredName', (name) => {
                root.classList.add('logged-in');
                text.focus();
                log.scrollTop = log.scrollHeight;
            });

            rpc.send('Chat.RequestHistory');
            root.classList.add('online');
        },

        onUnload: () => {
            rpc = null;
            root.classList.remove('online');
        },
    };
};

let nativeScrollbarWidth = (() => {
    let e = document.createElement('div');
    e.style.position = 'absolute';
    e.style.top      = '-200px';
    e.style.width    = '100px';
    e.style.height   = '100px';
    e.style.overflow = 'scroll';
    document.body.appendChild(e);
    let r = e.offsetWidth - e.clientWidth;
    e.remove();
    return r;
})();

let createCustomScrollbar = (e) => {
    if (nativeScrollbarWidth === 0)
        return;

    e.style.overflowY   = 'scroll';
    e.style.marginRight = `-${nativeScrollbarWidth}px`;

    let track = document.createElement('div');
    let thumb = document.createElement('div');
    thumb.classList.add('thumb');
    track.classList.add('scrollbar');
    track.classList.add('hidden');
    track.appendChild(thumb);

    let timeout = null;
    let show = () => {
        thumb.style.top          =  `${e.scrollTop    / e.scrollHeight * track.clientHeight}px`;
        thumb.style.height       =  `${e.clientHeight / e.scrollHeight * track.clientHeight}px`;
        track.style.marginTop    =  `${e.scrollTop}px`;
        track.style.marginBottom = `-${e.scrollTop}px`;
        if (e.scrollHeight > e.clientHeight) {
            if (timeout !== null)
                window.clearTimeout(timeout);
            track.classList.remove('hidden');
            timeout = window.setTimeout(() => track.classList.add('hidden'), 1000);
        } else
            timeout = null;
    };

    e.appendChild(track);
    e.addEventListener('scroll',    show);
    e.addEventListener('mousemove', show);
};

for (let es = document.querySelectorAll('[data-scrollable]'), i = 0; i < es.length; i++)
    createCustomScrollbar(es[i]);

let stream = document.body.getAttribute('data-stream-id');
let view   = new ViewNode(document.querySelector('.player'),
                          document.querySelector('.meta'), stream);
let chat   = new ChatNode(document.querySelector('.chat'));
let rpc    = new RPC(`ws${window.location.protocol == 'https:' ? 's' : ''}://`
                     + `${window.location.host}/stream/${encodeURIComponent(stream)}`,
                     chat, view);
<commit_msg>Auto-unmute when changing volume.<commit_after>'use strict'; /* global screenfull */

if (screenfull.enabled) {
    document.addEventListener(screenfull.raw.fullscreenchange, () => {
        if (screenfull.isFullscreen)
            screenfull.element.classList.add('is-fullscreen');
        else
            document.querySelector('.is-fullscreen').classList.remove('is-fullscreen');
    });

    document.addEventListener(screenfull.raw.fullscreenerror, () =>
        document.body.classList.add('no-fullscreen'));
} else
    document.body.classList.add('no-fullscreen');

let RPC = function(url, ...objects) {
    let cbs_by_id   = {};
    let cbs_by_code = {};
    let id = 0;

    let socket = new WebSocket(url);
    let self = {
        send: (method, ...params) => {
            return new Promise((resolve, reject) => {
                socket.send(JSON.stringify({ jsonrpc: '2.0', id, method, params }));
                cbs_by_id[id] = { resolve, reject };
                id = (id + 1) & 0x7FFF;
            });
        },

        callback: (code, cb) => {
            if (cb === undefined)
                delete cbs_by_code[code];
            else
                cbs_by_code[code] = cb;
        },
    };

    socket.onopen = () => {
        for (let object of objects)
            object.onLoad(self);
    };

    socket.onclose = (ev) => {
        for (let object of objects)
            object.onUnload();
    };

    socket.onmessage = (ev) => {
        let msg = JSON.parse(ev.data);

        if (msg.id === undefined) {
            if (msg.method in cbs_by_code)
                cbs_by_code[msg.method](...msg.params);
            else
                console.log('unhandled notification', msg);
        }

        if (msg.id in cbs_by_id) {
            let cb = cbs_by_id[msg.id];
            delete cbs_by_id[msg.id];
            if (msg.error === undefined)
                cb.resolve(msg.result);
            else
                cb.reject(msg.error);
        }
    };

    return self;
};

let ViewNode = function (root, info, stream) {
    let rpc    = null;
    let view   = root.querySelector('video');
    let status = root.querySelector('.status');
    let volume = root.querySelector('.volume');

    let onVolumeSelect = (e) => {
        e.preventDefault();
        let r = volume.getBoundingClientRect();
        let x = Math.min(r.right, Math.max(r.left, e.touches ? e.touches[0].clientX : e.clientX));
        view.volume = (x - r.left) / (r.right - r.left);
        view.muted  = false;
    };

    let onVolumeChange = (v, muted) => {
        let e = volume.querySelector('.slider');
        let r = volume.getBoundingClientRect();
        e.style.left = `${v * (r.right - r.left)}px`;
        e.style.top = `${(1 - v) * (r.bottom - r.top)}px`;
        if (muted)
            root.classList.add('muted');
        else
            root.classList.remove('muted');
    };

    let onTimeUpdate = (t) => {
        // let leftPad = require('left-pad');
        status.textContent = `${(t / 60)|0}:${t % 60 < 10 ? '0' : ''}${(t|0) % 60}`;
    };

    let onDone = () => {
        root.setAttribute('data-status',
            view.error === null || view.error.code === 4 ? 'ended' : 'error');
        status.textContent = view.error === null   ? 'stream ended'
                           : view.error.code === 1 ? 'aborted'
                           : view.error.code === 2 ? 'network error'
                           : view.error.code === 3 ? 'decoding error'
                           : /* view.error.code === 4 ? */ 'stream ended';
    };

    let onLoad = () => {
        root.setAttribute('data-status', 'loading');
        status.textContent = 'loading';
    };

    let onPlay = () => {
        root.setAttribute('data-status', 'playing');
        status.textContent = 'playing';
    };

    let hideCursorTimeout = null;
    let hideCursorLater = () => {
        showCursor();
        hideCursorTimeout = window.setTimeout(() => {
            hideCursorTimeout = null;
            root.classList.add('hide-cursor');
        }, 3000);
    };

    let showCursor = () => {
        if (hideCursorTimeout !== null)
            window.clearTimeout(hideCursorTimeout);
        else
            root.classList.remove('hide-cursor');
        hideCursorTimeout = null;
    };

    view.addEventListener('loadstart',      onLoad);
    view.addEventListener('loadedmetadata', onPlay);
    view.addEventListener('error',          onDone);
    view.addEventListener('ended',          onDone);
    view.addEventListener('timeupdate', () => onTimeUpdate(view.currentTime));
    view.addEventListener('volumechange', () => onVolumeChange(view.volume, view.muted));
    // TODO playing, waiting, stalled (not sure whether these events are actually emitted)

    view.addEventListener('mouseenter', hideCursorLater);
    view.addEventListener('mouseleave', showCursor);
    view.addEventListener('mouseenter', () =>
        view.addEventListener('mousemove', hideCursorLater));
    view.addEventListener('mouseleave', () =>
        view.removeEventListener('mousemove', hideCursorLater));

    volume.addEventListener('mousedown',  onVolumeSelect);
    volume.addEventListener('touchstart', onVolumeSelect);
    volume.addEventListener('touchmove',  onVolumeSelect);
    volume.addEventListener('mousedown', (e) =>
        volume.addEventListener('mousemove', onVolumeSelect));
    volume.addEventListener('mouseup', () =>
        volume.removeEventListener('mousemove', onVolumeSelect));
    volume.addEventListener('mouseleave', () =>
        volume.removeEventListener('mousemove', onVolumeSelect));
    onVolumeChange(view.volume, view.muted);

    root.querySelector('.mute').addEventListener('click', () => {
        view.muted = !view.muted;
    });

    root.querySelector('.theatre').addEventListener('click', () =>
        document.body.classList.add('theatre'));

    root.querySelector('.fullscreen').addEventListener('click', () =>
        screenfull.request(root));

    root.querySelector('.collapse').addEventListener('click', () => {
        document.body.classList.remove('theatre');
        screenfull.exit();
    });

    onLoad();
    return {
        onLoad: (socket) => {
            rpc = socket;
            rpc.callback('Stream.ViewerCount', (n) => {
                info.querySelector('.viewers').textContent = n;
            });
            // TODO measure connection speed, request a stream
            view.src = `/stream/${stream}`;
            view.play();
        },

        onUnload: () => {
            rpc = null;
            onDone();
        },
    };
};

let ChatNode = function (root) {
    let form = root.querySelector('.input-form');
    let text = form.querySelector('.input');
    let log  = root.querySelector('.log');
    let msg  = root.querySelector('.message-template');
    let rpc  = null;

    text.addEventListener('keydown', (ev) =>
        (ev.keyCode === 13 && !ev.shiftKey ? ev.preventDefault() : null));

    text.addEventListener('keyup', (ev) =>
        (ev.keyCode === 13 && !ev.shiftKey ?
            form.dispatchEvent(new Event('submit', {cancelable: true})) : null));

    form.addEventListener('submit', (ev) => {
        ev.preventDefault();
        if (rpc && text.value) {
            rpc.send('Chat.SendMessage', text.value).then(() => {
                log.scrollTop = log.scrollHeight;
                text.value = '';
                text.focus();
            });
        }
    });

    let lform = root.querySelector('.login-form');
    let login = lform.querySelector('.input');

    lform.addEventListener('submit', (ev) => {
        ev.preventDefault();
        if (rpc && login.value) {
            rpc.send('Chat.SetName', login.value);
        }
    });

    return {
        onLoad: (socket) => {
            rpc = socket;
            rpc.callback('Chat.Message', (name, text) => {
                let rect = log.getBoundingClientRect();
                let scroll = log.scrollTop + (rect.bottom - rect.top) >= log.scrollHeight;
                let entry = document.importNode(msg.content, true);
                entry.querySelector('.name').textContent = name;
                entry.querySelector('.text').textContent = text;
                log.appendChild(entry);
                if (scroll)
                    log.scrollTop = log.scrollHeight;
            });

            rpc.callback('Chat.AcquiredName', (name) => {
                root.classList.add('logged-in');
                text.focus();
                log.scrollTop = log.scrollHeight;
            });

            rpc.send('Chat.RequestHistory');
            root.classList.add('online');
        },

        onUnload: () => {
            rpc = null;
            root.classList.remove('online');
        },
    };
};

let nativeScrollbarWidth = (() => {
    let e = document.createElement('div');
    e.style.position = 'absolute';
    e.style.top      = '-200px';
    e.style.width    = '100px';
    e.style.height   = '100px';
    e.style.overflow = 'scroll';
    document.body.appendChild(e);
    let r = e.offsetWidth - e.clientWidth;
    e.remove();
    return r;
})();

let createCustomScrollbar = (e) => {
    if (nativeScrollbarWidth === 0)
        return;

    e.style.overflowY   = 'scroll';
    e.style.marginRight = `-${nativeScrollbarWidth}px`;

    let track = document.createElement('div');
    let thumb = document.createElement('div');
    thumb.classList.add('thumb');
    track.classList.add('scrollbar');
    track.classList.add('hidden');
    track.appendChild(thumb);

    let timeout = null;
    let show = () => {
        thumb.style.top          =  `${e.scrollTop    / e.scrollHeight * track.clientHeight}px`;
        thumb.style.height       =  `${e.clientHeight / e.scrollHeight * track.clientHeight}px`;
        track.style.marginTop    =  `${e.scrollTop}px`;
        track.style.marginBottom = `-${e.scrollTop}px`;
        if (e.scrollHeight > e.clientHeight) {
            if (timeout !== null)
                window.clearTimeout(timeout);
            track.classList.remove('hidden');
            timeout = window.setTimeout(() => track.classList.add('hidden'), 1000);
        } else
            timeout = null;
    };

    e.appendChild(track);
    e.addEventListener('scroll',    show);
    e.addEventListener('mousemove', show);
};

for (let es = document.querySelectorAll('[data-scrollable]'), i = 0; i < es.length; i++)
    createCustomScrollbar(es[i]);

let stream = document.body.getAttribute('data-stream-id');
let view   = new ViewNode(document.querySelector('.player'),
                          document.querySelector('.meta'), stream);
let chat   = new ChatNode(document.querySelector('.chat'));
let rpc    = new RPC(`ws${window.location.protocol == 'https:' ? 's' : ''}://`
                     + `${window.location.host}/stream/${encodeURIComponent(stream)}`,
                     chat, view);
<|endoftext|>


<commit_before>jQuery(function($){

    $("ul.tabs").tabs("> .pane",  {effect: 'fade'} );

    // Flexslider init
    if( $('.flexslider').length ) {
        $('.flexslider').flexslider({
            slideshow: true,
            animation: "slide",
            directionNav: false,
            start: function(slider){
                $('body').removeClass('loading');
            }
        });
    }

    $("#main-menu").tinyNav({header: 'Navigation'});

    $(".portfolio-item").hover(function(){
        $(this).find('.image-overlay').animate({opacity : '1'}, 300);
    }, function(){
        $(this).find('.image-overlay').animate({opacity : '0'}, 300 ,function(){
        });
    });

    /* Classes for prefooter & services widgets */
    var sidebars = $('#services, #footer-inner');

    $.each(sidebars, function() {

        var widgetCount = $(this).find('.widget').length;
        var widgetArray = $(this).find('.widget');

        widgetArray.last().addClass( 'last' );

        if ( widgetCount == 2) {
            widgetArray.addClass('one-half');
        }else if ( widgetCount == 3 ) {
            widgetArray.addClass('one-third');
        }else if ( widgetCount == 4 ) {
            widgetArray.addClass('one-fourth');
        };

    });

});
<commit_msg>added maxmedia check to disable lightbox on mobile<commit_after>jQuery(function($){

    $("ul.tabs").tabs("> .pane",  {effect: 'fade'} );

    // Flexslider init
    if( $('.flexslider').length ) {
        $('.flexslider').flexslider({
            slideshow: true,
            animation: "slide",
            directionNav: false,
            start: function(slider){
                $('body').removeClass('loading');
            }
        });
    }

    $("#main-menu").tinyNav({header: 'Navigation'});

    $(".portfolio-item").hover(function(){
        $(this).find('.image-overlay').animate({opacity : '1'}, 300);
    }, function(){
        $(this).find('.image-overlay').animate({opacity : '0'}, 300 ,function(){
        });
    });

    /* Classes for prefooter & services widgets */
    var sidebars = $('#services, #footer-inner');

    $.each(sidebars, function() {

        var widgetCount = $(this).find('.widget').length;
        var widgetArray = $(this).find('.widget');

        widgetArray.last().addClass( 'last' );

        if ( widgetCount == 2) {
            widgetArray.addClass('one-half');
        }else if ( widgetCount == 3 ) {
            widgetArray.addClass('one-third');
        }else if ( widgetCount == 4 ) {
            widgetArray.addClass('one-fourth');
        };

    });

    // disable lightbox on mobile
    if (window.matchMedia("(max-width: 400px)").matches) {
        $('a.cboxElement').removeClass('cboxElement').removeAttr('data-lightboxplus');
    }
});<|endoftext|>


<commit_before>/*
General-purpose JS utility functions can go here.
*/

var util = {

    /*
    Add a JS event that will run when the page is loaded.
    This will just add to the "events to run" list, it won't
    override previously specified events.

    From http://simonwillison.net/2004/May/26/addLoadEvent/
    */
    addLoadEvent: function(func) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = func;
        } else {
            window.onload = function() {
                if (oldonload) {
                    oldonload();
                }
                func();
            }
        }
    },

    /*
    Take a mouse event and return "LEFT", "MIDDLE", or "RIGHT" depending
    on which mouse button was clicked.

    From http://unixpapa.com/js/mouse.html
    "The following test works for all browsers except Opera 7."
    As of Aug 17, 2011
    */
    identifyMouseButton: function(event) {
        if (event.which == null)
           /* IE case */
           return (event.button < 2) ? "LEFT" :
                     ((event.button == 4) ? "MIDDLE" : "RIGHT");
        else
           /* All others */
           return (event.which < 2) ? "LEFT" :
                     ((event.which == 2) ? "MIDDLE" : "RIGHT");
    },

    /*
    Trim leading and trailing spaces from a string.

    From http://blog.stevenlevithan.com/archives/faster-trim-javascript
    */
    trimSpaces: function(str) {
        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }

};

/*
 * Extensions of standard types can go here.
 * Always make sure these don't conflict with third-party JS files' extensions of standard types.
 */

/* Array indexOf(), in case the browser doesn't have it (hi, IE)
 * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/IndexOf
 */
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this === void 0 || this === null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n !== n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n !== 0 && n !== Infinity && n !== -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

/* String format function, similar to printf in C.
 * Example usage: "{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
 * Example output: ASP is dead, but ASP.NET is alive! ASP {2}
 *
 * Source: http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format/4673436#4673436
 */
String.prototype.format = function() {
  var args = arguments;
  return this.replace(/{(\d+)}/g, function(match, number) {
    return typeof args[number] != 'undefined'
      ? args[number]
      : match
    ;
  });
};

/*
 * jQuery extensions can go here.
 */

/* Selector - exactlycontains
 *
 * Variation of the jQuery selector 'contains':
 * 'exactlycontains' will match an element if its entire inner text is
 * exactly what is specified in the argument, as opposed to simply
 * finding the argument as a substring.
 *
 * Source: http://api.jquery.com/contains-selector/ - see comment by Gibran
 */
$.expr[":"].exactlycontains = function(obj, index, meta, stack){
    return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
};<commit_msg>Dajaxice default exception behavior has been changed.  It now logs to the error console, if there is one (requires something like Firebug), instead of popping up a JS alert.<commit_after>/*
General-purpose JS utility functions can go here.
*/

var util = {

    /*
    Add a JS event that will run when the page is loaded.
    This will just add to the "events to run" list, it won't
    override previously specified events.

    From http://simonwillison.net/2004/May/26/addLoadEvent/
    */
    addLoadEvent: function(func) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = func;
        } else {
            window.onload = function() {
                if (oldonload) {
                    oldonload();
                }
                func();
            }
        }
    },

    /*
    Take a mouse event and return "LEFT", "MIDDLE", or "RIGHT" depending
    on which mouse button was clicked.

    From http://unixpapa.com/js/mouse.html
    "The following test works for all browsers except Opera 7."
    As of Aug 17, 2011
    */
    identifyMouseButton: function(event) {
        if (event.which == null)
           /* IE case */
           return (event.button < 2) ? "LEFT" :
                     ((event.button == 4) ? "MIDDLE" : "RIGHT");
        else
           /* All others */
           return (event.which < 2) ? "LEFT" :
                     ((event.which == 2) ? "MIDDLE" : "RIGHT");
    },

    /*
    Trim leading and trailing spaces from a string.

    From http://blog.stevenlevithan.com/archives/faster-trim-javascript
    */
    trimSpaces: function(str) {
        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }

};

/*
 * Extensions of standard types can go here.
 * Always make sure these don't conflict with third-party JS files' extensions of standard types.
 */

/* Array indexOf(), in case the browser doesn't have it (hi, IE)
 * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/IndexOf
 */
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this === void 0 || this === null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n !== n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n !== 0 && n !== Infinity && n !== -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

/* String format function, similar to printf in C.
 * Example usage: "{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
 * Example output: ASP is dead, but ASP.NET is alive! ASP {2}
 *
 * Source: http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format/4673436#4673436
 */
String.prototype.format = function() {
  var args = arguments;
  return this.replace(/{(\d+)}/g, function(match, number) {
    return typeof args[number] != 'undefined'
      ? args[number]
      : match
    ;
  });
};

/*
 * jQuery extensions can go here.
 */

/* Selector - exactlycontains
 *
 * Variation of the jQuery selector 'contains':
 * 'exactlycontains' will match an element if its entire inner text is
 * exactly what is specified in the argument, as opposed to simply
 * finding the argument as a substring.
 *
 * Source: http://api.jquery.com/contains-selector/ - see comment by Gibran
 */
$.expr[":"].exactlycontains = function(obj, index, meta, stack){
    return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
};

/*
 * Dajaxice settings can go here.
 */

if (Dajaxice) {

    /* Override Dajaxice's default exception behavior (the "Something goes wrong" alert).
     */
    Dajaxice.setup({'default_exception_callback': function(){
        if (console) {
            console.error("A Dajaxice error occurred.  Are you having Internet connection problems?  If not, this may be a CoralNet bug.  Please let us know about it.");
        }
    }});
}<|endoftext|>


<commit_before>var isNumber = require('is-number');
module.localFunctions = {
    decideBlackList: function (inEvaluatedValueForBlackList, inBlackListArray, inValueToEvaluate) {
        if (inEvaluatedValueForBlackList && (inBlackListArray.indexOf(inValueToEvaluate) === -1)) {
            return true;
        }
        return false;
    },
    decideWhiteList: function (inEvaluatedValueForWhiteList, inWhiteListArray, inValueToEvaluate) {
        if (inEvaluatedValueForWhiteList && (inWhiteListArray.indexOf(inValueToEvaluate) > -1)) {
            return true;
        }
        return false;
    },
    isNumeric: function (val) {
        return isNumber(val);
//        return (Number(parseFloat(val)) === val);
    },
    manageDateField: function (inCurrentList, crtIndex) {
        var crtResult = '';
        if (inCurrentList[crtIndex] === null) {
            crtResult = 'null';
        } else {
            crtResult = inCurrentList[crtIndex].replace('T', ' ').replace('Z', '');
        }
        return crtResult;
    },
    manageFieldsOfAllTypes: function (crtFieldAttributes, item) {
        if (crtFieldAttributes['Type'] === 'DateTime') {
            return module.localFunctions.manageDateField(item, crtFieldAttributes['Technical Name']);
        }
        var idFieldsType = ['Lookup', 'User'];
        if (idFieldsType.indexOf(crtFieldAttributes['Type']) > -1) {
            return item[crtFieldAttributes['Technical Name'] + 'Id'];
        }
        if (isNumber(item[crtFieldAttributes['Technical Name']])) {
            return item[crtFieldAttributes['Technical Name']];
        } else {
            return '"' + item[crtFieldAttributes['Technical Name']] + '"';
        }
    }
};
module.exports = {
    buildAuthenticationHeader: function (inAuthenticationArray) {
        var aReturn;
        switch (inAuthenticationArray.type) {
            case 'Addin':
                aReturn = inAuthenticationArray.credentials_Addin;
                break;
            case 'SAML':
                aReturn = inAuthenticationArray.credentials_SAML;
                break;
            default:
                aReturn = false;
                break;
        }
        return aReturn;
    },
    buildCurrentListAttributeValues: function (inObjectListsConfiguredAttributes, inCurrentList) {
        var crtListAttributes = [];
        Object.keys(inObjectListsConfiguredAttributes).map(function (itemList) {
            if (itemList.substring(0, 4) === 'Date') {
                crtListAttributes[itemList] = module.localFunctions.manageDateField(inCurrentList, inObjectListsConfiguredAttributes[itemList]);
            } else {
                crtListAttributes[itemList] = inCurrentList[inObjectListsConfiguredAttributes[itemList]];
            }
        });
        return crtListAttributes;
    },
    buildCurrentItemValues: function (fieldAttributes, item) {
        var crtRecord = [];
        var counterF = 0;
        Object.keys(fieldAttributes).map(function (itemF) {
            crtRecord[counterF] = module.localFunctions.manageFieldsOfAllTypes(fieldAttributes[itemF], item);
            counterF++;
        });
        return crtRecord;
    },
    buildCurrentRecordValues: function (inFieldsArray, crtRecordValues) {
        var specialColumns = ['Aggregations', 'HtmlSchemaXml'];
        var crtRecordGM = [];
        var counterGM = 0;
        Object.keys(inFieldsArray).map(function (itemGM) {
            if (specialColumns.indexOf(inFieldsArray[itemGM]) > -1) {
                crtRecordGM[counterGM] = '"' + JSON.stringify(crtRecordValues[inFieldsArray[itemGM]]) + '"';
            } else {
                if (isNumber(crtRecordValues[inFieldsArray[itemGM]])) {
                    crtRecordGM[counterGM] = crtRecordValues[inFieldsArray[itemGM]];
                } else {
                    crtRecordGM[counterGM] = '"' + crtRecordValues[inFieldsArray[itemGM]] + '"';
                }
            }
            counterGM++;
        });
        return crtRecordGM;
    },
    buildRequestQuery: function (targetSharePointURL, arStandardLists, crtListName, queryType, inData) {
        var queryPrefix = '';
        if (Object.keys(arStandardLists).indexOf(queryType) > -1) {
            queryPrefix = '_api/Web/' + arStandardLists[queryType]['APItrunk']
                    + '/' + arStandardLists[queryType]['APIfunction'] + '(\''
                    + crtListName + '\')/' + arStandardLists[queryType]['APIelement'];
        } else {
            queryPrefix = '_api/Web/' + queryType;
        }
        var headerOptions = inData.headers;
        headerOptions['Accept'] = 'application/json;odata=verbose';
        return {
            url: targetSharePointURL + queryPrefix,
            headers: headerOptions,
            json: true
        };
    },
    createOutputFileWithHeader: function (inParameters, fs) {
        var writeStream = fs.createWriteStream(inParameters['filePath'] + inParameters['fileName'] + '.csv', {encoding: 'utf8'}); // initiate file stream
        writeStream.write(inParameters['fileHeader'] + '"\n'); // Headers content
        return writeStream;
    },
    decideBlackListWhiteList: function (inDecisionValue, inBlackListArray, inWhiteListArray, inValueToEvaluate) {
        return (module.localFunctions.decideBlackList(inDecisionValue, inBlackListArray, inValueToEvaluate) || module.localFunctions.decideWhiteList(!inDecisionValue, inWhiteListArray, inValueToEvaluate));
    },
    internalQueryStructureArray: function (maxRecords) {
        return {
            'Fields': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Fields'},
            'GroupMembers': {'APItrunk': 'SiteGroups', 'APIfunction': 'GetById', 'APIelement': 'Users'},
            'Items': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Items' + '?$top=' + maxRecords},
            'Views': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Views'}
        };
    },
    manageRequestIntoCSVfile: function (inParameters, crtListParameters, responseListRecord, fieldAttributes, fs) {
        var writeStream = module.exports.createOutputFileWithHeader({'filePath': inParameters['filePath'], 'fileName': inParameters['fileName'], 'fileHeader': '"' + Object.keys(fieldAttributes).join('"' + inParameters['ListSeparator'] + '"') + (crtListParameters['Versioning Enabled'] ? '"' + inParameters['ListSeparator'] + '"Version' : '')}, fs);
        if (Object.keys(responseListRecord.d.results).length > 0) {
            responseListRecord.d.results.forEach(function (itemFieldValue) {
                writeStream.write(module.exports.buildCurrentItemValues(fieldAttributes, itemFieldValue).join(inParameters['ListSeparator']) + (crtListParameters['Versioning Enabled'] ? inParameters['ListSeparator'] + itemFieldValue.OData__UIVersionString : '') + '\n'); // writing rows
            });
        }
        writeStream.end();
    }
};
<commit_msg>additional error treatment<commit_after>var isNumber = require('is-number');
module.localFunctions = {
    decideBlackList: function (inEvaluatedValueForBlackList, inBlackListArray, inValueToEvaluate) {
        if (inEvaluatedValueForBlackList && (inBlackListArray.indexOf(inValueToEvaluate) === -1)) {
            return true;
        }
        return false;
    },
    decideWhiteList: function (inEvaluatedValueForWhiteList, inWhiteListArray, inValueToEvaluate) {
        if (inEvaluatedValueForWhiteList && (inWhiteListArray.indexOf(inValueToEvaluate) > -1)) {
            return true;
        }
        return false;
    },
    isNumeric: function (val) {
        return isNumber(val);
    },
    manageDateField: function (inCurrentList, crtIndex) {
        var crtResult = '';
        if ((inCurrentList[crtIndex] === null) || (inCurrentList[crtIndex] === undefined)) {
            crtResult = 'null';
        } else {
            crtResult = inCurrentList[crtIndex].replace('T', ' ').replace('Z', '');
        }
        return crtResult;
    },
    manageFieldsOfAllTypes: function (crtFieldAttributes, item) {
        if (crtFieldAttributes['Type'] === 'DateTime') {
            return module.localFunctions.manageDateField(item, crtFieldAttributes['Technical Name']);
        }
        var idFieldsType = ['Lookup', 'User'];
        if (idFieldsType.indexOf(crtFieldAttributes['Type']) > -1) {
            return item[crtFieldAttributes['Technical Name'] + 'Id'];
        }
        if (isNumber(item[crtFieldAttributes['Technical Name']])) {
            return item[crtFieldAttributes['Technical Name']];
        } else {
            return '"' + item[crtFieldAttributes['Technical Name']] + '"';
        }
    }
};
module.exports = {
    buildAuthenticationHeader: function (inAuthenticationArray) {
        var aReturn;
        switch (inAuthenticationArray.type) {
            case 'Addin':
                aReturn = inAuthenticationArray.credentials_Addin;
                break;
            case 'SAML':
                aReturn = inAuthenticationArray.credentials_SAML;
                break;
            default:
                aReturn = false;
                break;
        }
        return aReturn;
    },
    buildCurrentListAttributeValues: function (inObjectListsConfiguredAttributes, inCurrentList) {
        var crtListAttributes = [];
        Object.keys(inObjectListsConfiguredAttributes).map(function (itemList) {
            if (itemList.substring(0, 4) === 'Date') {
                crtListAttributes[itemList] = module.localFunctions.manageDateField(inCurrentList, inObjectListsConfiguredAttributes[itemList]);
            } else {
                crtListAttributes[itemList] = inCurrentList[inObjectListsConfiguredAttributes[itemList]];
            }
        });
        return crtListAttributes;
    },
    buildCurrentItemValues: function (fieldAttributes, item) {
        var crtRecord = [];
        var counterF = 0;
        Object.keys(fieldAttributes).map(function (itemF) {
            crtRecord[counterF] = module.localFunctions.manageFieldsOfAllTypes(fieldAttributes[itemF], item);
            counterF++;
        });
        return crtRecord;
    },
    buildCurrentRecordValues: function (inFieldsArray, crtRecordValues) {
        var specialColumns = ['Aggregations', 'HtmlSchemaXml'];
        var crtRecordGM = [];
        var counterGM = 0;
        Object.keys(inFieldsArray).map(function (itemGM) {
            if (specialColumns.indexOf(inFieldsArray[itemGM]) > -1) {
                crtRecordGM[counterGM] = '"' + JSON.stringify(crtRecordValues[inFieldsArray[itemGM]]) + '"';
            } else {
                if (isNumber(crtRecordValues[inFieldsArray[itemGM]])) {
                    crtRecordGM[counterGM] = crtRecordValues[inFieldsArray[itemGM]];
                } else {
                    crtRecordGM[counterGM] = '"' + crtRecordValues[inFieldsArray[itemGM]] + '"';
                }
            }
            counterGM++;
        });
        return crtRecordGM;
    },
    buildRequestQuery: function (targetSharePointURL, arStandardLists, crtListName, queryType, inData) {
        var queryPrefix = '';
        if (Object.keys(arStandardLists).indexOf(queryType) > -1) {
            queryPrefix = '_api/Web/' + arStandardLists[queryType]['APItrunk']
                    + '/' + arStandardLists[queryType]['APIfunction'] + '(\''
                    + crtListName + '\')/' + arStandardLists[queryType]['APIelement'];
        } else {
            queryPrefix = '_api/Web/' + queryType;
        }
        var headerOptions = inData.headers;
        headerOptions['Accept'] = 'application/json;odata=verbose';
        return {
            url: targetSharePointURL + queryPrefix,
            headers: headerOptions,
            json: true
        };
    },
    createOutputFileWithHeader: function (inParameters, fs) {
        var writeStream = fs.createWriteStream(inParameters['filePath'] + inParameters['fileName'] + '.csv', {encoding: 'utf8'}); // initiate file stream
        writeStream.write(inParameters['fileHeader'] + '"\n'); // Headers content
        return writeStream;
    },
    decideBlackListWhiteList: function (inDecisionValue, inBlackListArray, inWhiteListArray, inValueToEvaluate) {
        return (module.localFunctions.decideBlackList(inDecisionValue, inBlackListArray, inValueToEvaluate) || module.localFunctions.decideWhiteList(!inDecisionValue, inWhiteListArray, inValueToEvaluate));
    },
    internalQueryStructureArray: function (maxRecords) {
        return {
            'Fields': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Fields'},
            'GroupMembers': {'APItrunk': 'SiteGroups', 'APIfunction': 'GetById', 'APIelement': 'Users'},
            'Items': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Items' + '?$top=' + maxRecords},
            'Views': {'APItrunk': 'Lists', 'APIfunction': 'GetByTitle', 'APIelement': 'Views'}
        };
    },
    manageRequestIntoCSVfile: function (inParameters, crtListParameters, responseListRecord, fieldAttributes, fs) {
        var writeStream = module.exports.createOutputFileWithHeader({'filePath': inParameters['filePath'], 'fileName': inParameters['fileName'], 'fileHeader': '"' + Object.keys(fieldAttributes).join('"' + inParameters['ListSeparator'] + '"') + (crtListParameters['Versioning Enabled'] ? '"' + inParameters['ListSeparator'] + '"Version' : '')}, fs);
        if (Object.keys(responseListRecord.d.results).length > 0) {
            responseListRecord.d.results.forEach(function (itemFieldValue) {
                writeStream.write(module.exports.buildCurrentItemValues(fieldAttributes, itemFieldValue).join(inParameters['ListSeparator']) + (crtListParameters['Versioning Enabled'] ? inParameters['ListSeparator'] + itemFieldValue.OData__UIVersionString : '') + '\n'); // writing rows
            });
        }
        writeStream.end();
    }
};
<|endoftext|>


<commit_before>var doUpdate=1;
var data=null;
var mpver=9;
var msgline="";

/**
 * used cmd's so far are:
 *  mpc_play,
 *  mpc_prev,
 *  mpc_next,
 *  mpc_favtitle,
 *  mpc_repl,
 *  mpc_dnptitle,
 *	mpc_ivol,
 *	mpc_dvol,
 *  mpc_quit - just terminate pmixplay
 */
function sendCMD( cmd ) {
	var xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=function() {
  		if ( xmlhttp.readyState==4 && xmlhttp.status!=204 ) {
			alert( "Error "+xmlhttp.status );
  		}
	}

	xmlhttp.open("GET", "/cmd/"+cmd, true);
	xmlhttp.send();
}

function setElement( e, val ) {
	document.getElementById( e ).innerHTML=val;
}

function updateUI( ){
	var xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=function() {
  		if (xmlhttp.readyState==4 ) {
  			if( xmlhttp.status==200 ) {
	  			data=JSON.parse(xmlhttp.responseText);
	  			if( data !== undefined ) {
	  				if( data.version != mpver ) {
	  					doUpdate=0;
	  					alert("Version clash, expected "+mpver+" and got "+data.version );
	  					return;
	  				}
	  				document.title=data.current.artist+" - "+data.current.title;
		  			setElement( 'prev', data.prev.artist+" - "+data.prev.title );
		  			setElement( 'artist', data.current.artist );
		  			if( data.status == 0 ) {
			  			setElement( 'title', data.current.title );
			  		}
			  		else {
			  			setElement( 'title', ""+data.current.title+"" );
			  		}
		  			setElement( 'album', data.current.album );
		  			setElement( 'next', data.next.artist+" - "+data.next.title );
		  			setElement( 'playtime', data.playtime+" / "+data.remtime );
		  			setElement( 'volume', data.volume+"%" );
		  			if( data.msg != "" ) {
		  				msgline=msgline+"\n"+data.msg;
		  			}
		  			else {
		  				if( msgline!= "" ) {
			  				document.body.style.cursor='auto';
		  					alert(msgline);
		  					msgline="";
		  				}
		  			}
		  			if( data.current.flags & 1 )  {
			  			document.getElementById( 'fav' ).disabled=true;
		  			}
		  			else {
			  			document.getElementById( 'fav' ).disabled=false;
		  			}
		  		}
		  	}
		  	else if( xmlhttp.status==503 ) {
		  		if( confirm( "Try to restart?" ) ) {
		  			sendCMD( "mpc_start" );
		  		}
		  		else{
		  			alert( "Stopping updates.." );
		  			doUpdate=0;
		  		}
		  	}
		}
	}

	if( doUpdate != 0 ) {
		xmlhttp.open("GET", "/status", true);
		xmlhttp.send();
		setTimeout("updateUI()",500);
	}
}

function search() {
	var e=document.getElementById('range');
	var term=e.options[e.selectedIndex].value;
	if(document.getElementById('fuzzy').checked ) {
		term=term+"*";
	}
	else {
		term=term+"=";
	}
	term=term+document.getElementById('text').value;
	if( term.length > 4 ) {
		document.body.style.cursor='progress';
		sendCMD( "mpc_search?"+term );
	}
	else {
		alert("Need at least two letters to saearch!");
	}
}

updateUI();

<commit_msg>forgot to bump comm version number in webclient<commit_after>var doUpdate=1;
var data=null;
var mpver=10;
var msgline="";

/**
 * used cmd's so far are:
 *  mpc_play,
 *  mpc_prev,
 *  mpc_next,
 *  mpc_favtitle,
 *  mpc_repl,
 *  mpc_dnptitle,
 *	mpc_ivol,
 *	mpc_dvol,
 *  mpc_quit - just terminate pmixplay
 */
function sendCMD( cmd ) {
	var xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=function() {
  		if ( xmlhttp.readyState==4 && xmlhttp.status!=204 ) {
			alert( "Error "+xmlhttp.status );
  		}
	}

	xmlhttp.open("GET", "/cmd/"+cmd, true);
	xmlhttp.send();
}

function setElement( e, val ) {
	document.getElementById( e ).innerHTML=val;
}

function updateUI( ){
	var xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=function() {
  		if (xmlhttp.readyState==4 ) {
  			if( xmlhttp.status==200 ) {
	  			data=JSON.parse(xmlhttp.responseText);
	  			if( data !== undefined ) {
	  				if( data.version != mpver ) {
	  					doUpdate=0;
	  					alert("Version clash, expected "+mpver+" and got "+data.version );
	  					return;
	  				}
	  				document.title=data.current.artist+" - "+data.current.title;
		  			setElement( 'prev', data.prev.artist+" - "+data.prev.title );
		  			setElement( 'artist', data.current.artist );
		  			if( data.status == 0 ) {
			  			setElement( 'title', data.current.title );
			  		}
			  		else {
			  			setElement( 'title', ""+data.current.title+"" );
			  		}
		  			setElement( 'album', data.current.album );
		  			setElement( 'next', data.next.artist+" - "+data.next.title );
		  			setElement( 'playtime', data.playtime+" / "+data.remtime );
		  			setElement( 'volume', data.volume+"%" );
		  			if( data.msg != "" ) {
		  				msgline=msgline+"\n"+data.msg;
		  			}
		  			else {
		  				if( msgline!= "" ) {
			  				document.body.style.cursor='auto';
		  					alert(msgline);
		  					msgline="";
		  				}
		  			}
		  			if( data.current.flags & 1 )  {
			  			document.getElementById( 'fav' ).disabled=true;
		  			}
		  			else {
			  			document.getElementById( 'fav' ).disabled=false;
		  			}
		  		}
		  	}
		  	else if( xmlhttp.status==503 ) {
		  		if( confirm( "Try to restart?" ) ) {
		  			sendCMD( "mpc_start" );
		  		}
		  		else{
		  			alert( "Stopping updates.." );
		  			doUpdate=0;
		  		}
		  	}
		}
	}

	if( doUpdate != 0 ) {
		xmlhttp.open("GET", "/status", true);
		xmlhttp.send();
		setTimeout("updateUI()",500);
	}
}

function search() {
	var e=document.getElementById('range');
	var term=e.options[e.selectedIndex].value;
	if(document.getElementById('fuzzy').checked ) {
		term=term+"*";
	}
	else {
		term=term+"=";
	}
	term=term+document.getElementById('text').value;
	if( term.length > 4 ) {
		document.body.style.cursor='progress';
		sendCMD( "mpc_search?"+term );
	}
	else {
		alert("Need at least two letters to saearch!");
	}
}

updateUI();

<|endoftext|>


<commit_before>// ==UserScript==
// @name        Desire2learnForumFix
// @namespace   frcc.desire2learn.com
// @include     https://frcc.desire2learn.com/d2l/lms/discussions/messageLists/*
// @version     1
// @grant       none
// ==/UserScript==

var anchor, childHeader, count, excludedClasses, rows, rowsGrandParent ; //init

rows = document.getElementsByTagName("TR"); //D2L also uses tables for everything, including layout, which they shouldn't but they do.  Get all table rows
excludedClasses = ["d_gact", "dsearch", "dsearch_header", "d_FG", "d_t"]; //Array to hold classes with TRs we don't want to target

for (var i = 0; i < rows.length; i++) {
	var anchor, childHeader, count, rowsGrandParent; //init
	rowsGrandParent = rows[i].parentNode.parentNode; //Gets the grandparent of each row so we can check if the GP is one of the excluded classes above, because those are not the TRs we're looking for
	if (rows[i].className == "" ||  rows[i].className == " d_dbold") { //The TRs we're looking for either have no class or their class is d_dbold (if it's an unread message)
		if (excludedClasses.indexOf(rowsGrandParent.className) > -1) { //Check the array for excluded classes
			continue; //if so then end this iteration
		} else {
			count = countDgle(rows[i]); //Set count to determine how much to indent the messages
			rows[i].id = "trRow" + i; //Sets an id for the TR so we can select the child table header
			childHeader = document.querySelector("#trRow" + i + " > th:first-of-type"); //Selects the child table header
			if(!childHeader) { //If it doesn't have a child table header then it's not a message and we don't need it so...
				rows[i].id = ""; //remove the id
				continue; //End this iteration
			} else {
				childHeader.id = "childHeader" + i; //Set an ID for the table header so we can target the anchor
				anchor = document.querySelector("#childHeader" + i + " > a:first-of-type"); //Target the anchor
				if(anchor) { //Makes sure there is an anchor, otherwise we're in the wrong table header
					anchor.style.marginLeft = count + "px"; //Indents
					anchor.style.paddingLeft = "10px";
					if (count > 0) { //Checks if it's the top level message, if it's not then it adds a border and some padding to the subject to make it easier to follow
						anchor.style.borderLeft = "2px solid grey";
						anchor.style.borderRadius = "10px 0px 0px 10px";
					} else if (count === 0) { //Different border for the top level message
						anchor.style.borderLeft = "2px solid grey";
           				anchor.style.borderTopLeftRadius = "4px 0px 0px 4px";
					}
				}
			}
		}
	}
}

function countDgle(row) { //D2l uses a poorly named TH called "d_g_l_e" to indent the names of who sent the message (rather than, you know, CSS).  This function counts how many times this TH exists in order to determine how far to indent
	let count = 0; //init
	for (var i = 0; i < row.children.length; i++) { //Goes through all the children of the row to count the headers
		if (row.children[i].className == "d_g_l_e") { //Checks each class to see if it matches
			count++;
		}
	} return (count -1) * 20; //returns the number of pixels to indent.  E.g. one message deep = 20 px, two messages = 40px etc.  Change the multiplier if you need a different amount for your screen resulution
}
<commit_msg>Update d2lForumFix.user.js<commit_after>// ==UserScript==
// @name        Desire2learnForumFix
// @namespace   frcc.desire2learn.com
// @include     https://frcc.desire2learn.com/d2l/lms/discussions/messageLists/*
// @version     1
// @grant       none
// ==/UserScript==

var anchor, childHeader, count, excludedClasses, rows, rowsGrandParent ; //init

rows = document.getElementsByTagName("TR"); //D2L also uses tables for everything, including layout, which they shouldn't but they do.  Get all table rows
excludedClasses = ["d_gact", "dsearch", "dsearch_header", "d_FG", "d_t"]; //Array to hold classes with TRs we don't want to target

for (var i = 0; i < rows.length; i++) {
	rowsGrandParent = rows[i].parentNode.parentNode; //Gets the grandparent of each row so we can check if the GP is one of the excluded classes above, because those are not the TRs we're looking for
	if (rows[i].className == "" ||  rows[i].className == " d_dbold") { //The TRs we're looking for either have no class or their class is d_dbold (if it's an unread message)
		if (excludedClasses.indexOf(rowsGrandParent.className) > -1) { //Check the array for excluded classes
			continue; //if so then end this iteration
		} else {
			count = countDgle(rows[i]); //Set count to determine how much to indent the messages
			rows[i].id = "trRow" + i; //Sets an id for the TR so we can select the child table header
			childHeader = document.querySelector("#trRow" + i + " > th:first-of-type"); //Selects the child table header
			if(!childHeader) { //If it doesn't have a child table header then it's not a message and we don't need it so...
				rows[i].id = ""; //remove the id
				continue; //End this iteration
			} else {
				childHeader.id = "childHeader" + i; //Set an ID for the table header so we can target the anchor
				anchor = document.querySelector("#childHeader" + i + " > a:first-of-type"); //Target the anchor
				if(anchor) { //Makes sure there is an anchor, otherwise we're in the wrong table header
					anchor.style.marginLeft = count + "px"; //Indents
					anchor.style.paddingLeft = "10px";
					if (count > 0) { //Checks if it's the top level message, if it's not then it adds a border and some padding to the subject to make it easier to follow
						anchor.style.borderLeft = "2px solid grey";
						anchor.style.borderRadius = "10px 0px 0px 10px";
					} else if (count === 0) { //Different border for the top level message
						anchor.style.borderLeft = "2px solid grey";
           				anchor.style.borderTopLeftRadius = "4px 0px 0px 4px";
					}
				}
			}
		}
	}
}

function countDgle(row) { //D2l uses a poorly named TH called "d_g_l_e" to indent the names of who sent the message (rather than, you know, CSS).  This function counts how many times this TH exists in order to determine how far to indent
	let count = 0; //init
	for (var i = 0; i < row.children.length; i++) { //Goes through all the children of the row to count the headers
		if (row.children[i].className == "d_g_l_e") { //Checks each class to see if it matches
			count++;
		}
	} return (count -1) * 20; //returns the number of pixels to indent.  E.g. one message deep = 20 px, two messages = 40px etc.  Change the multiplier if you need a different amount for your screen resulution
}
<|endoftext|>


<commit_before>//  Description
//    A Hubot script to pull data from the USGS API
//    USGS API documentation can be found at
//    https://waterservices.usgs.gov/rest/IV-Service.html
//
//  Dependencies:
//    None
//
//  Configuration:
//    None
//
//  Commands:
//    usgs help - Display help in channel
//    usgs alias <friendly name> <usgs sensor>" - Alias a sensor to friendly name
//    usgs forget <friendly name>" - Forget an alias
//    usgs list" - List current aliases
//    usgs data <usgs sensor or alias>" - Get data from a sensor
//
//  Author:
//    Ed Brereton <edbrereton@gmail.com>
//

module.exports = function (robot) {
    robot.respond("/usgs help/i", (res) => {
        res.send("usgs Commands");
        res.send("usgs alias <friendly name> <usgs sensor>");
        res.send("usgs forget <friendly name>");
        res.send("usgs list");
        res.send("usgs data <usgs sensor or alias>");
    });

    robot.respond("/usgs alias (.*) (.*)/i", (res) => {
        alias = res.match[1];
        site = "usgs" + res.match[2];

        if(robot.brain.data[alias] != undefined) {
            reply = "I already have an alias called " + alias;
        }
        else {
            robot.brain.data[alias] = site;
            reply = "aliased " + site.replace("usgs", "") + " to " + alias
        }

        res.send(reply);
    });

    robot.respond("/usgs list/i", (res) => {
        res.send("Known Aliases: ")
        for (var key in robot.brain.data) {
            if(key != "_private"
                && robot.brain.data[key] != undefined
                && typeof(robot.brain.data[key]) != "object"){
                res.send(key + " is USGS site " + robot.brain.data[key]);
            }
        }
    });

    robot.respond("/usgs forget (.*)/i", (res) => {
        alias = res.match[1];

        reply = ""
        if(typeof(robot.brain.data[alias]) == "string"
        && robot.brain.data[alias].substring(0,4) == "usgs") {
            robot.brain.data[alias] = undefined;
            reply = "Alias " + alias + " has been forgotten"
        }
        else {
            reply = "I can't forget that"
        }

        res.send(reply);
    });

    robot.respond("/usgs data (.*)/i", (res) => {
        input = res.match[1];

        if (robot.brain.data[input] != undefined
        && typeof(robot.brain.data[alias]) == "string"
        && robot.brain.data[alias].substring(0,4) == "usgs") {
            site = robot.brain.data[input].replace("usgs", "");
        }
        else {
            site = input;
        }

        robot.http("https://waterservices.usgs.gov/nwis/iv/?format=json&sites=" + site + "&siteStatus=all")
            .header('Accept', 'application/json')
            .get()((err, resp, body) => {
                data = {};
                try {
                    data = JSON.parse(body);
                } catch (error) {
                    res.send("Something went wrong - did you use a missing alias?")
                    return;
                }

                res.send(data.value.timeSeries[0].sourceInfo.siteName)
                for (var i = 0; i < data.value.timeSeries.length; i++) {
                    res.send(data.value.timeSeries[i].values[0].value[0].dateTime + " - "
                    + data.value.timeSeries[i].variable.variableName + ", " +
					+ data.value.timeSeries[i].values[0].value[0].value
					+ data.value.timeSeries[i].variable.unit.unitCode);
				}

				res.send("Source: https://waterdata.usgs.gov/tx/nwis/uv/?site_no="+site)

				lat = data.value.timeSeries[0].sourceInfo.geoLocation.geogLocation.latitude;
				long = data.value.timeSeries[0].sourceInfo.geoLocation.geogLocation.longitude;
				res.send("Location: https://www.google.com/maps/place/"+lat+","+long)

            });
    });
}
<commit_msg>Fix formatting<commit_after>//  Description
//    A Hubot script to pull data from the USGS API
//    USGS API documentation can be found at
//    https://waterservices.usgs.gov/rest/IV-Service.html
//
//  Dependencies:
//    None
//
//  Configuration:
//    None
//
//  Commands:
//    usgs help - Display help in channel
//    usgs alias <friendly name> <usgs sensor>" - Alias a sensor to friendly name
//    usgs forget <friendly name>" - Forget an alias
//    usgs list" - List current aliases
//    usgs data <usgs sensor or alias>" - Get data from a sensor
//
//  Author:
//    Ed Brereton <edbrereton@gmail.com>
//

module.exports = function (robot) {
    robot.respond("/usgs help/i", (res) => {
        res.send("usgs Commands");
        res.send("usgs alias <friendly name> <usgs sensor>");
        res.send("usgs forget <friendly name>");
        res.send("usgs list");
        res.send("usgs data <usgs sensor or alias>");
    });

    robot.respond("/usgs alias (.*) (.*)/i", (res) => {
        alias = res.match[1];
        site = "usgs" + res.match[2];

        if (robot.brain.data[alias] != undefined) {
            reply = "I already have an alias called " + alias;
        } else {
            robot.brain.data[alias] = site;
            reply = "aliased " + site.replace("usgs", "") + " to " + alias
        }

        res.send(reply);
    });

    robot.respond("/usgs list/i", (res) => {
        res.send("Known Aliases: ")
        for (var key in robot.brain.data) {
            if (key != "_private" &&
                robot.brain.data[key] != undefined &&
                typeof (robot.brain.data[key]) != "object") {
                res.send(key + " is USGS site " + robot.brain.data[key]);
            }
        }
    });

    robot.respond("/usgs forget (.*)/i", (res) => {
        alias = res.match[1];

        reply = ""
        if (typeof (robot.brain.data[alias]) == "string" &&
            robot.brain.data[alias].substring(0, 4) == "usgs") {
            robot.brain.data[alias] = undefined;
            reply = "Alias " + alias + " has been forgotten"
        } else {
            reply = "I can't forget that"
        }

        res.send(reply);
    });

    robot.respond("/usgs data (.*)/i", (res) => {
        input = res.match[1];

        if (robot.brain.data[input] != undefined &&
            typeof (robot.brain.data[alias]) == "string" &&
            robot.brain.data[alias].substring(0, 4) == "usgs") {
            site = robot.brain.data[input].replace("usgs", "");
        } else {
            site = input;
        }

        robot.http("https://waterservices.usgs.gov/nwis/iv/?format=json&sites=" + site + "&siteStatus=all")
            .header('Accept', 'application/json')
            .get()((err, resp, body) => {
                data = {};
                try {
                    data = JSON.parse(body);
                } catch (error) {
                    res.send("Something went wrong - did you use a missing alias?")
                    return;
                }

                res.send(data.value.timeSeries[0].sourceInfo.siteName)
                for (var i = 0; i < data.value.timeSeries.length; i++) {
                    res.send(data.value.timeSeries[i].values[0].value[0].dateTime + " - " +
                        data.value.timeSeries[i].variable.variableName + ", " +
                        +data.value.timeSeries[i].values[0].value[0].value +
                        data.value.timeSeries[i].variable.unit.unitCode);
                }

                res.send("Source: https://waterdata.usgs.gov/tx/nwis/uv/?site_no=" + site)

                lat = data.value.timeSeries[0].sourceInfo.geoLocation.geogLocation.latitude;
                long = data.value.timeSeries[0].sourceInfo.geoLocation.geogLocation.longitude;
                res.send("Location: https://www.google.com/maps/place/" + lat + "," + long)

            });
    });
}
<|endoftext|>


<commit_before>"use strict";
var ASSERT = require("./assert");
var es5 = require("./es5");
// Assume CSP if browser
var canEvaluate = typeof navigator == "undefined";

//Try catch is not supported in optimizing
//compiler, so it is isolated
var errorObj = {e: {}};
var tryCatchTarget;
var globalObject = typeof self !== "undefined" ? self :
    typeof window !== "undefined" ? window :
    typeof global !== "undefined" ? global :
    this !== undefined ? this : null;

function tryCatcher() {
    try {
        var target = tryCatchTarget;
        tryCatchTarget = null;
        return target.apply(this, arguments);
    } catch (e) {
        errorObj.e = e;
        return errorObj;
    }
}
function tryCatch(fn) {
    ASSERT(typeof fn === "function");
    tryCatchTarget = fn;
    return tryCatcher;
}

//Un-magical enough that using this doesn't prevent
//extending classes from outside using any convention
var inherits = function(Child, Parent) {
    var hasProp = {}.hasOwnProperty;

    function T() {
        this.constructor = Child;
        this.constructor$ = Parent;
        for (var propertyName in Parent.prototype) {
            if (hasProp.call(Parent.prototype, propertyName) &&
                propertyName.charAt(propertyName.length-1) !== "$"
           ) {
                this[propertyName + "$"] = Parent.prototype[propertyName];
            }
        }
    }
    T.prototype = Parent.prototype;
    Child.prototype = new T();
    return Child.prototype;
};

function isPrimitive(val) {
    return val == null || val === true || val === false ||
        typeof val === "string" || typeof val === "number";

}

function isObject(value) {
    return typeof value === "function" ||
           typeof value === "object" && value !== null;
}

function maybeWrapAsError(maybeError) {
    if (!isPrimitive(maybeError)) return maybeError;

    return new Error(safeToString(maybeError));
}

function withAppended(target, appendee) {
    var len = target.length;
    var ret = new Array(len + 1);
    var i;
    for (i = 0; i < len; ++i) {
        ret[i] = target[i];
    }
    ret[i] = appendee;
    return ret;
}

function getDataPropertyOrDefault(obj, key, defaultValue) {
    if (es5.isES5) {
        var desc = Object.getOwnPropertyDescriptor(obj, key);

        if (desc != null) {
            return desc.get == null && desc.set == null
                    ? desc.value
                    : defaultValue;
        }
    } else {
        return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined;
    }
}

function notEnumerableProp(obj, name, value) {
    if (isPrimitive(obj)) return obj;
    var descriptor = {
        value: value,
        configurable: true,
        enumerable: false,
        writable: true
    };
    es5.defineProperty(obj, name, descriptor);
    return obj;
}

function thrower(r) {
    throw r;
}

var inheritedDataKeys = (function() {
    var excludedPrototypes = [
        Array.prototype,
        Object.prototype,
        Function.prototype
    ];

    var isExcludedProto = function(val) {
        for (var i = 0; i < excludedPrototypes.length; ++i) {
            if (excludedPrototypes[i] === val) {
                return true;
            }
        }
        return false;
    };

    if (es5.isES5) {
        var getKeys = Object.getOwnPropertyNames;
        return function(obj) {
            var ret = [];
            var visitedKeys = Object.create(null);
            while (obj != null && !isExcludedProto(obj)) {
                var keys;
                try {
                    keys = getKeys(obj);
                } catch (e) {
                    return ret;
                }
                for (var i = 0; i < keys.length; ++i) {
                    var key = keys[i];
                    if (visitedKeys[key]) continue;
                    visitedKeys[key] = true;
                    var desc = Object.getOwnPropertyDescriptor(obj, key);
                    if (desc != null && desc.get == null && desc.set == null) {
                        ret.push(key);
                    }
                }
                obj = es5.getPrototypeOf(obj);
            }
            return ret;
        };
    } else {
        var hasProp = {}.hasOwnProperty;
        return function(obj) {
            if (isExcludedProto(obj)) return [];
            var ret = [];

            /*jshint forin:false */
            enumeration: for (var key in obj) {
                if (hasProp.call(obj, key)) {
                    ret.push(key);
                } else {
                    for (var i = 0; i < excludedPrototypes.length; ++i) {
                        if (hasProp.call(excludedPrototypes[i], key)) {
                            continue enumeration;
                        }
                    }
                    ret.push(key);
                }
            }
            return ret;
        };
    }

})();

var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/;
function isClass(fn) {
    try {
        if (typeof fn === "function") {
            var keys = es5.names(fn.prototype);

            var hasMethods = es5.isES5 && keys.length > 1;
            var hasMethodsOtherThanConstructor = keys.length > 0 &&
                !(keys.length === 1 && keys[0] === "constructor");
            var hasThisAssignmentAndStaticMethods =
                thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0;

            if (hasMethods || hasMethodsOtherThanConstructor ||
                hasThisAssignmentAndStaticMethods) {
                return true;
            }
        }
        return false;
    } catch (e) {
        return false;
    }
}

function toFastProperties(obj) {
    /*jshint -W027,-W055,-W031*/
    function FakeConstructor() {}
    FakeConstructor.prototype = obj;
    var l = 8;
    while (l--) new FakeConstructor();
    ASSERT("%HasFastProperties", true, obj);
    return obj;
    // Prevent the function from being optimized through dead code elimination
    // or further optimizations. This code is never reached but even using eval
    // in unreachable code causes v8 to not optimize functions.
    eval(obj);
}

var rident = /^[a-z$_][a-z$_0-9]*$/i;
function isIdentifier(str) {
    return rident.test(str);
}

function filledRange(count, prefix, suffix) {
    var ret = new Array(count);
    for(var i = 0; i < count; ++i) {
        ret[i] = prefix + i + suffix;
    }
    return ret;
}

function safeToString(obj) {
    try {
        return obj + "";
    } catch (e) {
        return "[no string representation]";
    }
}

function isError(obj) {
    return obj !== null &&
           typeof obj === "object" &&
           typeof obj.message === "string" &&
           typeof obj.name === "string";
}

function markAsOriginatingFromRejection(e) {
    try {
        notEnumerableProp(e, OPERATIONAL_ERROR_KEY, true);
    }
    catch(ignore) {}
}

function originatesFromRejection(e) {
    if (e == null) return false;
    return ((e instanceof Error[BLUEBIRD_ERRORS].OperationalError) ||
        e[OPERATIONAL_ERROR_KEY] === true);
}

function canAttachTrace(obj) {
    return isError(obj) && es5.propertyIsWritable(obj, "stack");
}

var ensureErrorObject = (function() {
    if (!("stack" in new Error())) {
        return function(value) {
            if (canAttachTrace(value)) return value;
            try {throw new Error(safeToString(value));}
            catch(err) {return err;}
        };
    } else {
        return function(value) {
            if (canAttachTrace(value)) return value;
            return new Error(safeToString(value));
        };
    }
})();

function classString(obj) {
    return {}.toString.call(obj);
}

function copyDescriptors(from, to, filter) {
    var keys = es5.names(from);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        if (filter(key)) {
            try {
                es5.defineProperty(to, key, es5.getDescriptor(from, key));
            } catch (ignore) {}
        }
    }
}

var asArray = function(v) {
    if (es5.isArray(v)) {
        return v;
    }
    return null;
};

if (typeof Symbol !== "undefined" && Symbol.iterator) {
    var ArrayFrom = typeof Array.from === "function" ? function(v) {
        return Array.from(v);
    } : function(v) {
        var ret = [];
        var it = v[Symbol.iterator]();
        var itResult;
        while (!((itResult = it.next()).done)) {
            ret.push(itResult.value);
        }
        return ret;
    };

    asArray = function(v) {
        if (es5.isArray(v)) {
            return v;
        } else if (v != null && typeof v[Symbol.iterator] === "function") {
            return ArrayFrom(v);
        }
        return null;
    };
}

var isNode = typeof process !== "undefined" &&
        classString(process).toLowerCase() === "[object process]";

function env(key, def) {
    return isNode ? process.env[key] : def;
}

function getNativePromise() {
    if (typeof Promise === "function") {
        try {
            var promise = new Promise(function(){});
            if ({}.toString.call(promise) === "[object Promise]") {
                return Promise;
            }
        } catch (e) {}
    }
}

function domainBind(self, cb) {
    function runBound() {
        if (self._disposed) return;
        INLINE_SLICE(args, arguments);
        var ret;

        self.enter();
        try {
            if (args.length > 0) {
                ret = cb.apply(this, args);
            } else {
                ret = cb.call(this);
            }
            self.exit();
        } catch (e) {
            self.emit("error", e);
            self.exit();
        }

        return ret;
    }
    return runBound;
}

var ret = {
    isClass: isClass,
    isIdentifier: isIdentifier,
    inheritedDataKeys: inheritedDataKeys,
    getDataPropertyOrDefault: getDataPropertyOrDefault,
    thrower: thrower,
    isArray: es5.isArray,
    asArray: asArray,
    notEnumerableProp: notEnumerableProp,
    isPrimitive: isPrimitive,
    isObject: isObject,
    isError: isError,
    canEvaluate: canEvaluate,
    errorObj: errorObj,
    tryCatch: tryCatch,
    inherits: inherits,
    withAppended: withAppended,
    maybeWrapAsError: maybeWrapAsError,
    toFastProperties: toFastProperties,
    filledRange: filledRange,
    toString: safeToString,
    canAttachTrace: canAttachTrace,
    ensureErrorObject: ensureErrorObject,
    originatesFromRejection: originatesFromRejection,
    markAsOriginatingFromRejection: markAsOriginatingFromRejection,
    classString: classString,
    copyDescriptors: copyDescriptors,
    hasDevTools: typeof chrome !== "undefined" && chrome &&
                 typeof chrome.loadTimes === "function",
    isNode: isNode,
    env: env,
    global: globalObject,
    getNativePromise: getNativePromise,
    domainBind: domainBind
};
ret.isRecentNode = ret.isNode && (function() {
    var version = process.versions.node.split(".").map(Number);
    return (version[0] === 0 && version[1] > 10) || (version[0] > 0);
})();

if (ret.isNode) ret.toFastProperties(process);

try {throw new Error(); } catch (e) {ret.lastLineError = e;}
module.exports = ret;
<commit_msg>Fixes #1217<commit_after>"use strict";
var ASSERT = require("./assert");
var es5 = require("./es5");
// Assume CSP if browser
var canEvaluate = typeof navigator == "undefined";

//Try catch is not supported in optimizing
//compiler, so it is isolated
var errorObj = {e: {}};
var tryCatchTarget;
var globalObject = typeof self !== "undefined" ? self :
    typeof window !== "undefined" ? window :
    typeof global !== "undefined" ? global :
    this !== undefined ? this : null;

function tryCatcher() {
    try {
        var target = tryCatchTarget;
        tryCatchTarget = null;
        return target.apply(this, arguments);
    } catch (e) {
        errorObj.e = e;
        return errorObj;
    }
}
function tryCatch(fn) {
    ASSERT(typeof fn === "function");
    tryCatchTarget = fn;
    return tryCatcher;
}

//Un-magical enough that using this doesn't prevent
//extending classes from outside using any convention
var inherits = function(Child, Parent) {
    var hasProp = {}.hasOwnProperty;

    function T() {
        this.constructor = Child;
        this.constructor$ = Parent;
        for (var propertyName in Parent.prototype) {
            if (hasProp.call(Parent.prototype, propertyName) &&
                propertyName.charAt(propertyName.length-1) !== "$"
           ) {
                this[propertyName + "$"] = Parent.prototype[propertyName];
            }
        }
    }
    T.prototype = Parent.prototype;
    Child.prototype = new T();
    return Child.prototype;
};

function isPrimitive(val) {
    return val == null || val === true || val === false ||
        typeof val === "string" || typeof val === "number";

}

function isObject(value) {
    return typeof value === "function" ||
           typeof value === "object" && value !== null;
}

function maybeWrapAsError(maybeError) {
    if (!isPrimitive(maybeError)) return maybeError;

    return new Error(safeToString(maybeError));
}

function withAppended(target, appendee) {
    var len = target.length;
    var ret = new Array(len + 1);
    var i;
    for (i = 0; i < len; ++i) {
        ret[i] = target[i];
    }
    ret[i] = appendee;
    return ret;
}

function getDataPropertyOrDefault(obj, key, defaultValue) {
    if (es5.isES5) {
        var desc = Object.getOwnPropertyDescriptor(obj, key);

        if (desc != null) {
            return desc.get == null && desc.set == null
                    ? desc.value
                    : defaultValue;
        }
    } else {
        return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined;
    }
}

function notEnumerableProp(obj, name, value) {
    if (isPrimitive(obj)) return obj;
    var descriptor = {
        value: value,
        configurable: true,
        enumerable: false,
        writable: true
    };
    es5.defineProperty(obj, name, descriptor);
    return obj;
}

function thrower(r) {
    throw r;
}

var inheritedDataKeys = (function() {
    var excludedPrototypes = [
        Array.prototype,
        Object.prototype,
        Function.prototype
    ];

    var isExcludedProto = function(val) {
        for (var i = 0; i < excludedPrototypes.length; ++i) {
            if (excludedPrototypes[i] === val) {
                return true;
            }
        }
        return false;
    };

    if (es5.isES5) {
        var getKeys = Object.getOwnPropertyNames;
        return function(obj) {
            var ret = [];
            var visitedKeys = Object.create(null);
            while (obj != null && !isExcludedProto(obj)) {
                var keys;
                try {
                    keys = getKeys(obj);
                } catch (e) {
                    return ret;
                }
                for (var i = 0; i < keys.length; ++i) {
                    var key = keys[i];
                    if (visitedKeys[key]) continue;
                    visitedKeys[key] = true;
                    var desc = Object.getOwnPropertyDescriptor(obj, key);
                    if (desc != null && desc.get == null && desc.set == null) {
                        ret.push(key);
                    }
                }
                obj = es5.getPrototypeOf(obj);
            }
            return ret;
        };
    } else {
        var hasProp = {}.hasOwnProperty;
        return function(obj) {
            if (isExcludedProto(obj)) return [];
            var ret = [];

            /*jshint forin:false */
            enumeration: for (var key in obj) {
                if (hasProp.call(obj, key)) {
                    ret.push(key);
                } else {
                    for (var i = 0; i < excludedPrototypes.length; ++i) {
                        if (hasProp.call(excludedPrototypes[i], key)) {
                            continue enumeration;
                        }
                    }
                    ret.push(key);
                }
            }
            return ret;
        };
    }

})();

var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/;
function isClass(fn) {
    try {
        if (typeof fn === "function") {
            var keys = es5.names(fn.prototype);

            var hasMethods = es5.isES5 && keys.length > 1;
            var hasMethodsOtherThanConstructor = keys.length > 0 &&
                !(keys.length === 1 && keys[0] === "constructor");
            var hasThisAssignmentAndStaticMethods =
                thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0;

            if (hasMethods || hasMethodsOtherThanConstructor ||
                hasThisAssignmentAndStaticMethods) {
                return true;
            }
        }
        return false;
    } catch (e) {
        return false;
    }
}

function toFastProperties(obj) {
    /*jshint -W027,-W055,-W031*/
    function FakeConstructor() {}
    FakeConstructor.prototype = obj;
    var l = 8;
    while (l--) new FakeConstructor();
    ASSERT("%HasFastProperties", true, obj);
    return obj;
    // Prevent the function from being optimized through dead code elimination
    // or further optimizations. This code is never reached but even using eval
    // in unreachable code causes v8 to not optimize functions.
    eval(obj);
}

var rident = /^[a-z$_][a-z$_0-9]*$/i;
function isIdentifier(str) {
    return rident.test(str);
}

function filledRange(count, prefix, suffix) {
    var ret = new Array(count);
    for(var i = 0; i < count; ++i) {
        ret[i] = prefix + i + suffix;
    }
    return ret;
}

function safeToString(obj) {
    try {
        return obj + "";
    } catch (e) {
        return "[no string representation]";
    }
}

function isError(obj) {
    return obj !== null &&
           typeof obj === "object" &&
           typeof obj.message === "string" &&
           typeof obj.name === "string";
}

function markAsOriginatingFromRejection(e) {
    try {
        notEnumerableProp(e, OPERATIONAL_ERROR_KEY, true);
    }
    catch(ignore) {}
}

function originatesFromRejection(e) {
    if (e == null) return false;
    return ((e instanceof Error[BLUEBIRD_ERRORS].OperationalError) ||
        e[OPERATIONAL_ERROR_KEY] === true);
}

function canAttachTrace(obj) {
    return isError(obj) && es5.propertyIsWritable(obj, "stack");
}

var ensureErrorObject = (function() {
    if (!("stack" in new Error())) {
        return function(value) {
            if (canAttachTrace(value)) return value;
            try {throw new Error(safeToString(value));}
            catch(err) {return err;}
        };
    } else {
        return function(value) {
            if (canAttachTrace(value)) return value;
            return new Error(safeToString(value));
        };
    }
})();

function classString(obj) {
    return {}.toString.call(obj);
}

function copyDescriptors(from, to, filter) {
    var keys = es5.names(from);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        if (filter(key)) {
            try {
                es5.defineProperty(to, key, es5.getDescriptor(from, key));
            } catch (ignore) {}
        }
    }
}

var asArray = function(v) {
    if (es5.isArray(v)) {
        return v;
    }
    return null;
};

if (typeof Symbol !== "undefined" && Symbol.iterator) {
    var ArrayFrom = typeof Array.from === "function" ? function(v) {
        return Array.from(v);
    } : function(v) {
        var ret = [];
        var it = v[Symbol.iterator]();
        var itResult;
        while (!((itResult = it.next()).done)) {
            ret.push(itResult.value);
        }
        return ret;
    };

    asArray = function(v) {
        if (es5.isArray(v)) {
            return v;
        } else if (v != null && typeof v[Symbol.iterator] === "function") {
            return ArrayFrom(v);
        }
        return null;
    };
}

var isNode = typeof process !== "undefined" &&
        classString(process).toLowerCase() === "[object process]";

function env(key, def) {
    return isNode ? process.env[key] : def;
}

function getNativePromise() {
    if (typeof Promise === "function") {
        try {
            var promise = new Promise(function(){});
            if ({}.toString.call(promise) === "[object Promise]") {
                return Promise;
            }
        } catch (e) {}
    }
}

function domainBind(self, cb) {
    return self.bind(cb);
}

var ret = {
    isClass: isClass,
    isIdentifier: isIdentifier,
    inheritedDataKeys: inheritedDataKeys,
    getDataPropertyOrDefault: getDataPropertyOrDefault,
    thrower: thrower,
    isArray: es5.isArray,
    asArray: asArray,
    notEnumerableProp: notEnumerableProp,
    isPrimitive: isPrimitive,
    isObject: isObject,
    isError: isError,
    canEvaluate: canEvaluate,
    errorObj: errorObj,
    tryCatch: tryCatch,
    inherits: inherits,
    withAppended: withAppended,
    maybeWrapAsError: maybeWrapAsError,
    toFastProperties: toFastProperties,
    filledRange: filledRange,
    toString: safeToString,
    canAttachTrace: canAttachTrace,
    ensureErrorObject: ensureErrorObject,
    originatesFromRejection: originatesFromRejection,
    markAsOriginatingFromRejection: markAsOriginatingFromRejection,
    classString: classString,
    copyDescriptors: copyDescriptors,
    hasDevTools: typeof chrome !== "undefined" && chrome &&
                 typeof chrome.loadTimes === "function",
    isNode: isNode,
    env: env,
    global: globalObject,
    getNativePromise: getNativePromise,
    domainBind: domainBind
};
ret.isRecentNode = ret.isNode && (function() {
    var version = process.versions.node.split(".").map(Number);
    return (version[0] === 0 && version[1] > 10) || (version[0] > 0);
})();

if (ret.isNode) ret.toFastProperties(process);

try {throw new Error(); } catch (e) {ret.lastLineError = e;}
module.exports = ret;
<|endoftext|>