<commit_before>define([
        '../Core/buildModuleUrl',
        '../Core/Check',
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/destroyObject'
    ], function(
        buildModuleUrl,
        Check,
        Credit,
        defaultValue,
        defined,
        destroyObject) {
    'use strict';

    var mobileWidth = 576;
    var lightboxHeight = 100;
    var textColor = '#ffffff';
    var highlightColor = '#48b';

    function contains(credits, credit) {
        var len = credits.length;
        for (var i = 0; i < len; i++) {
            var existingCredit = credits[i];
            if (Credit.equals(existingCredit, credit)) {
                return true;
            }
        }
        return false;
    }

    function swapCesiumCredit(creditDisplay) {
        // We don't want to clutter the screen with the Cesium logo and the Cesium ion
        // logo at the same time. Since the ion logo is required, we just replace the
        // Cesium logo or add the logo if the Cesium one was removed.
        var previousCredit = creditDisplay._previousCesiumCredit;
        var currentCredit = creditDisplay._currentCesiumCredit;
        if (Credit.equals(currentCredit, previousCredit)) {
            return;
        }

        if (defined(previousCredit)) {
            creditDisplay._cesiumCreditContainer.removeChild(previousCredit.element);
        }
        if (defined(currentCredit)) {
            creditDisplay._cesiumCreditContainer.appendChild(currentCredit.element);
        }

        creditDisplay._previousCesiumCredit = currentCredit;
    }

    function displayCredits(creditDisplay, credits) {
        var i;
        var index;
        var credit;
        var displayedCredits = creditDisplay._displayedCredits.screenCredits;
        var container = creditDisplay._screenContainer;
        for (i = 0; i < credits.length; i++) {
            credit = credits[i];
            if (defined(credit)) {
                index = displayedCredits.indexOf(credit);
                if (index === -1) {
                    var element = credit.element;
                    if (container.hasChildNodes()) {
                        var del = document.createElement('span');
                        del.textContent = creditDisplay._delimiter;
                        del.className = 'cesium-credit-delimiter';
                        container.appendChild(del);
                    }
                    container.appendChild(element);
                } else {
                    displayedCredits.splice(index, 1);
                }
            }
        }
    }

    function displayLightboxCredits(creditDisplay, lighboxCredits) {
        var i;
        var index;
        var credit;
        var displayedCredits = creditDisplay._displayedCredits.lightboxCredits;
        var container = creditDisplay._creditList;
        for (i = 0; i < lighboxCredits.length; i++) {
            credit = lighboxCredits[i];
            if (defined(credit)) {
                index = displayedCredits.indexOf(credit);
                if (index === -1) {
                    var li = document.createElement('li');
                    var element = credit.element;
                    li.appendChild(element);
                    container.appendChild(li);
                } else {
                    displayedCredits.splice(index, 1);
                }
            }
        }
    }

    function removeCreditDomElement(credit) {
        var element = credit.element;

        var container = credit.showOnScreen ? element.parentNode : element.parentNode.parentNode;

        if (!credit.showOnScreen) {
            container.removeChild(element.parentNode);
            return;
        }

        var delimiter = element.previousSibling;
        if (delimiter === null) {
            delimiter = element.nextSibling;
        }
        if (delimiter !== null) {
            container.removeChild(delimiter);
        }
        container.removeChild(element);
    }

    function removeUnusedCredits(creditDisplay) {
        var i;
        var credit;
        var displayedTextCredits = creditDisplay._displayedCredits.screenCredits;
        for (i = 0; i < displayedTextCredits.length; i++) {
            credit = displayedTextCredits[i];
            if (defined(credit)) {
                removeCreditDomElement(credit);
            }
        }
    }

    function removeUnusedLightboxCredits(creditDisplay) {
        var i;
        var credit;
        var displayedLightboxCredits = creditDisplay._displayedCredits.lightboxCredits;
        for (i = 0; i < displayedLightboxCredits.length; i++) {
            credit = displayedLightboxCredits[i];
            if (defined(credit)) {
                removeCreditDomElement(credit);
            }
        }
    }

    function styleLightboxContainer(that) {
        var lightboxCredits = that._lightboxCredits;
        var width = that.viewport.clientWidth;
        var height = that.viewport.clientHeight;
        if (width !== that._lastViewportWidth) {
            if (width < mobileWidth) {
                lightboxCredits.className = 'cesium-credit-lightbox cesium-credit-lightbox-mobile';
                lightboxCredits.style.marginTop = '0';
            } else {
                lightboxCredits.className = 'cesium-credit-lightbox cesium-credit-lightbox-expanded';
                lightboxCredits.style.marginTop = Math.floor((height - lightboxCredits.clientHeight) * 0.5) + 'px';
            }
            that._lastViewportWidth = width;
        }

        if (width >= mobileWidth && height !== that._lastViewportHeight) {
            lightboxCredits.style.marginTop = Math.floor((height - lightboxCredits.clientHeight) * 0.5) + 'px';
            that._lastViewportHeight = height;
        }
    }

    function addStyle(selector, styles) {
        var style = selector + ' {';
        for (var attribute in styles) {
            if (styles.hasOwnProperty(attribute)) {
                style += attribute + ': ' + styles[attribute] + '; ';
            }
        }
        style += ' }\n';
        return style;
    }

    function appendCss() {
        var head = document.head;
        var css = document.createElement('style');
        var style = '';
        style += addStyle('.cesium-credit-lightbox-overlay', {
            display : 'none',
            'z-index' : '1', //must be at least 1 to draw over top other Cesium widgets
            position : 'absolute',
            top : '0',
            left : '0',
            width : '100%',
            height : '100%',
            'background-color' : 'rgba(80, 80, 80, 0.8)'
        });

        style += addStyle('.cesium-credit-lightbox', {
            'background-color' : '#303336',
            color : textColor,
            position : 'relative',
            'min-height' : lightboxHeight + 'px',
            margin : 'auto'
        });

        style += addStyle('.cesium-credit-lightbox > ul > li a, .cesium-credit-lightbox > ul > li a:visited', {
            color: textColor
        });

        style += addStyle('.cesium-credit-lightbox > ul > li a:hover', {
            color: highlightColor
        });

        style += addStyle('.cesium-credit-lightbox.cesium-credit-lightbox-expanded', {
            border : '1px solid #444',
            'border-radius' : '5px',
            'max-width' : '370px'
        });

        style += addStyle('.cesium-credit-lightbox.cesium-credit-lightbox-mobile', {
            height : '100%',
            width : '100%'
        });

        style += addStyle('.cesium-credit-lightbox-title', {
            padding : '20px 20px 0 20px'
        });

        style += addStyle('.cesium-credit-lightbox-close', {
            'font-size' : '18pt',
            cursor : 'pointer',
            position : 'absolute',
            top : '0',
            right : '6px',
            color : textColor
        });

        style += addStyle('.cesium-credit-lightbox-close:hover', {
            color : highlightColor
        });

        style += addStyle('.cesium-credit-lightbox > ul', {
            margin : '0',
            padding : '12px 20px 12px 40px',
            'font-size' : '13px'
        });

        style += addStyle('.cesium-credit-lightbox > ul > li', {
            'padding-bottom' : '6px'
        });

        style += addStyle('.cesium-credit-expand-link', {
            'padding-left' : '5px',
            cursor : 'pointer',
            'text-decoration' : 'underline',
            color: textColor
        });
        style += addStyle('.cesium-credit-expand-link:hover', {
            'color' : highlightColor
        });

        style += addStyle('.cesium-credit-text', {
            color: textColor
        });

        css.innerHTML = style;

        head.insertBefore(css, head.firstChild);
    }

    var cesiumLogo = buildModuleUrl('Assets/Images/cesium_credit.png');
    var cesiumCredit = new Credit('', true);

    /**
     * The credit display is responsible for displaying credits on screen.
     *
     * @param {HTMLElement} container The HTML element where credits will be displayed
     * @param {String} [delimiter= ' • '] The string to separate text credits
     * @param {HTMLElement} [viewport=document.body] The HTML element that will contain the credits popup
     *
     * @alias CreditDisplay
     * @constructor
     *
     * @example
     * var creditDisplay = new Cesium.CreditDisplay(creditContainer);
     */
    function CreditDisplay(container, delimiter, viewport) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('container', container);
        //>>includeEnd('debug');
        var that = this;

        viewport = defaultValue(viewport, document.body);

        var lightbox = document.createElement('div');
        lightbox.className = 'cesium-credit-lightbox-overlay';
        viewport.appendChild(lightbox);

        var lightboxCredits = document.createElement('div');
        lightboxCredits.className = 'cesium-credit-lightbox';
        lightbox.appendChild(lightboxCredits);

        function hideLightbox(event) {
            if (lightboxCredits.contains(event.target)) {
                return;
            }
            that.hideLightbox();
        }
        lightbox.addEventListener('click', hideLightbox, false);

        var title = document.createElement('div');
        title.className = 'cesium-credit-lightbox-title';
        title.textContent = 'Data provided by:';
        lightboxCredits.appendChild(title);

        var closeButton = document.createElement('a');
        closeButton.onclick = this.hideLightbox.bind(this);
        closeButton.innerHTML = '×';
        closeButton.className = 'cesium-credit-lightbox-close';
        lightboxCredits.appendChild(closeButton);

        var creditList = document.createElement('ul');
        lightboxCredits.appendChild(creditList);

        var cesiumCreditContainer = document.createElement('span');
        container.appendChild(cesiumCreditContainer);

        var screenContainer = document.createElement('span');
        screenContainer.className = 'cesium-credit-textContainer';
        container.appendChild(screenContainer);

        var expandLink = document.createElement('a');
        expandLink.className = 'cesium-credit-expand-link';
        expandLink.onclick = this.showLightbox.bind(this);
        expandLink.textContent = 'Data attribution';
        container.appendChild(expandLink);

        appendCss();

        this._delimiter = defaultValue(delimiter, ' • ');
        this._screenContainer = screenContainer;
        this._cesiumCreditContainer = cesiumCreditContainer;
        this._lastViewportHeight = undefined;
        this._lastViewportWidth = undefined;
        this._lightboxCredits = lightboxCredits;
        this._creditList = creditList;
        this._lightbox = lightbox;
        this._hideLightbox = hideLightbox;
        this._expandLink = expandLink;
        this._expanded = false;
        this._defaultCredits = [];
        this._previousCesiumCredit = undefined;
        this._currentCesiumCredit = CreditDisplay.cesiumCredit;

        this._displayedCredits = {
            screenCredits : [],
            lightboxCredits : []
        };
        this._currentFrameCredits = {
            screenCredits : [],
            lightboxCredits : []
        };

        this.viewport = viewport;

        /**
         * The HTML element where credits will be displayed.
         * @type {HTMLElement}
         */
        this.container = container;
    }

    /**
     * Adds a credit to the list of current credits to be displayed in the credit container
     *
     * @param {Credit} credit The credit to display
     */
    CreditDisplay.prototype.addCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var screenCredits = this._currentFrameCredits.screenCredits;

        if (credit._isIon) {
            this._currentCesiumCredit = credit;
        } else if (!credit.showOnScreen) {
            this._currentFrameCredits.lightboxCredits[credit.id] = credit;
        } else {
            screenCredits[credit.id] = credit;
        }
    };

    /**
     * Adds credits that will persist until they are removed
     *
     * @param {Credit} credit The credit to added to defaults
     */
    CreditDisplay.prototype.addDefaultCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var credits = this._defaultCredits;
        if (!contains(credits, credit)) {
            credits.push(credit);
        }
    };

    /**
     * Removes a default credit
     *
     * @param {Credit} credit The credit to be removed from defaults
     */
    CreditDisplay.prototype.removeDefaultCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var index = this._defaultCredits.indexOf(credit);
        if (index !== -1) {
            this._defaultCredits.splice(index, 1);
        }
    };

    CreditDisplay.prototype.showLightbox = function() {
        this._lightbox.style.display = 'block';
        this._expanded = true;
    };

    CreditDisplay.prototype.hideLightbox = function() {
        this._lightbox.style.display = 'none';
        this._expanded = false;
    };

    /**
     * Updates the credit display before a new frame is rendered.
     */
    CreditDisplay.prototype.update = function() {
        var displayedLightboxCredits = [];

        if (this._expanded && defined(this._creditsToUpdate)) {
            styleLightboxContainer(this);
            displayLightboxCredits(this, this._creditsToUpdate);
            displayedLightboxCredits = this._creditsToUpdate.slice();
        }

        removeUnusedLightboxCredits(this);

        this._displayedCredits.lightboxCredits = displayedLightboxCredits;
    };

    /**
     * Resets the credit display to a beginning of frame state, clearing out current credits.
     */
    CreditDisplay.prototype.beginFrame = function() {
        this._currentFrameCredits.screenCredits.length = 0;
        this._currentFrameCredits.lightboxCredits.length = 0;
        this._currentCesiumCredit = CreditDisplay.cesiumCredit;
    };

    /**
     * Sets the credit display to the end of frame state, displaying credits from the last frame in the credit container.
     */
    CreditDisplay.prototype.endFrame = function() {
        displayCredits(this, this._defaultCredits);
        displayCredits(this, this._currentFrameCredits.screenCredits);

        var displayedScreenCredits = this._defaultCredits.concat(this._currentFrameCredits.screenCredits);

        var showLightboxLink = this._currentFrameCredits.lightboxCredits.length > 0;
        this._expandLink.style.display = showLightboxLink ? 'inline' : 'none';

        removeUnusedCredits(this);
        swapCesiumCredit(this);

        this._displayedCredits.screenCredits = displayedScreenCredits;

        this._creditsToUpdate = this._currentFrameCredits.lightboxCredits.slice();
    };

    /**
     * Destroys the resources held by this object.  Destroying an object allows for deterministic
     * release of resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     */
    CreditDisplay.prototype.destroy = function() {
        this._lightbox.removeEventListener('click', this._hideLightbox, false);

        this.container.removeChild(this._cesiumCreditContainer);
        this.container.removeChild(this._screenContainer);
        this.container.removeChild(this._expandLink);
        this.viewport.removeChild(this._lightbox);

        return destroyObject(this);
    };

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     *
     * @returns {Boolean} true if this object was destroyed; otherwise, false.
     */
    CreditDisplay.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Gets or sets the Cesium logo credit.
     * @type {Credit}
     */
    CreditDisplay.cesiumCredit = cesiumCredit;

    return CreditDisplay;
});
<commit_msg>fix styling<commit_after>define([
        '../Core/buildModuleUrl',
        '../Core/Check',
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/destroyObject'
    ], function(
        buildModuleUrl,
        Check,
        Credit,
        defaultValue,
        defined,
        destroyObject) {
    'use strict';

    var mobileWidth = 576;
    var lightboxHeight = 100;
    var textColor = '#ffffff';
    var highlightColor = '#48b';

    function contains(credits, credit) {
        var len = credits.length;
        for (var i = 0; i < len; i++) {
            var existingCredit = credits[i];
            if (Credit.equals(existingCredit, credit)) {
                return true;
            }
        }
        return false;
    }

    function swapCesiumCredit(creditDisplay) {
        // We don't want to clutter the screen with the Cesium logo and the Cesium ion
        // logo at the same time. Since the ion logo is required, we just replace the
        // Cesium logo or add the logo if the Cesium one was removed.
        var previousCredit = creditDisplay._previousCesiumCredit;
        var currentCredit = creditDisplay._currentCesiumCredit;
        if (Credit.equals(currentCredit, previousCredit)) {
            return;
        }

        if (defined(previousCredit)) {
            creditDisplay._cesiumCreditContainer.removeChild(previousCredit.element);
        }
        if (defined(currentCredit)) {
            creditDisplay._cesiumCreditContainer.appendChild(currentCredit.element);
        }

        creditDisplay._previousCesiumCredit = currentCredit;
    }

    function displayCredits(creditDisplay, credits) {
        var i;
        var index;
        var credit;
        var displayedCredits = creditDisplay._displayedCredits.screenCredits;
        var container = creditDisplay._screenContainer;
        for (i = 0; i < credits.length; i++) {
            credit = credits[i];
            if (defined(credit)) {
                index = displayedCredits.indexOf(credit);
                if (index === -1) {
                    var element = credit.element;
                    if (container.hasChildNodes()) {
                        var del = document.createElement('span');
                        del.textContent = creditDisplay._delimiter;
                        del.className = 'cesium-credit-delimiter';
                        container.appendChild(del);
                    }
                    container.appendChild(element);
                } else {
                    displayedCredits.splice(index, 1);
                }
            }
        }
    }

    function displayLightboxCredits(creditDisplay, lighboxCredits) {
        var i;
        var index;
        var credit;
        var displayedCredits = creditDisplay._displayedCredits.lightboxCredits;
        var container = creditDisplay._creditList;
        for (i = 0; i < lighboxCredits.length; i++) {
            credit = lighboxCredits[i];
            if (defined(credit)) {
                index = displayedCredits.indexOf(credit);
                if (index === -1) {
                    var li = document.createElement('li');
                    var element = credit.element;
                    li.appendChild(element);
                    container.appendChild(li);
                } else {
                    displayedCredits.splice(index, 1);
                }
            }
        }
    }

    function removeCreditDomElement(credit) {
        var element = credit.element;

        var container = credit.showOnScreen ? element.parentNode : element.parentNode.parentNode;

        if (!credit.showOnScreen) {
            container.removeChild(element.parentNode);
            return;
        }

        var delimiter = element.previousSibling;
        if (delimiter === null) {
            delimiter = element.nextSibling;
        }
        if (delimiter !== null) {
            container.removeChild(delimiter);
        }
        container.removeChild(element);
    }

    function removeUnusedCredits(creditDisplay) {
        var i;
        var credit;
        var displayedTextCredits = creditDisplay._displayedCredits.screenCredits;
        for (i = 0; i < displayedTextCredits.length; i++) {
            credit = displayedTextCredits[i];
            if (defined(credit)) {
                removeCreditDomElement(credit);
            }
        }
    }

    function removeUnusedLightboxCredits(creditDisplay) {
        var i;
        var credit;
        var displayedLightboxCredits = creditDisplay._displayedCredits.lightboxCredits;
        for (i = 0; i < displayedLightboxCredits.length; i++) {
            credit = displayedLightboxCredits[i];
            if (defined(credit)) {
                removeCreditDomElement(credit);
            }
        }
    }

    function styleLightboxContainer(that) {
        var lightboxCredits = that._lightboxCredits;
        var width = that.viewport.clientWidth;
        var height = that.viewport.clientHeight;
        if (width !== that._lastViewportWidth) {
            if (width < mobileWidth) {
                lightboxCredits.className = 'cesium-credit-lightbox cesium-credit-lightbox-mobile';
                lightboxCredits.style.marginTop = '0';
            } else {
                lightboxCredits.className = 'cesium-credit-lightbox cesium-credit-lightbox-expanded';
                lightboxCredits.style.marginTop = Math.floor((height - lightboxCredits.clientHeight) * 0.5) + 'px';
            }
            that._lastViewportWidth = width;
        }

        if (width >= mobileWidth && height !== that._lastViewportHeight) {
            lightboxCredits.style.marginTop = Math.floor((height - lightboxCredits.clientHeight) * 0.5) + 'px';
            that._lastViewportHeight = height;
        }
    }

    function addStyle(selector, styles) {
        var style = selector + ' {';
        for (var attribute in styles) {
            if (styles.hasOwnProperty(attribute)) {
                style += attribute + ': ' + styles[attribute] + '; ';
            }
        }
        style += ' }\n';
        return style;
    }

    function appendCss() {
        var head = document.head;
        var css = document.createElement('style');
        var style = '';
        style += addStyle('.cesium-credit-lightbox-overlay', {
            display : 'none',
            'z-index' : '1', //must be at least 1 to draw over top other Cesium widgets
            position : 'absolute',
            top : '0',
            left : '0',
            width : '100%',
            height : '100%',
            'background-color' : 'rgba(80, 80, 80, 0.8)'
        });

        style += addStyle('.cesium-credit-lightbox', {
            'background-color' : '#303336',
            color : textColor,
            position : 'relative',
            'min-height' : lightboxHeight + 'px',
            margin : 'auto'
        });

        style += addStyle('.cesium-credit-lightbox > ul > li a, .cesium-credit-lightbox > ul > li a:visited', {
            color: textColor
        });

        style += addStyle('.cesium-credit-lightbox > ul > li a:hover', {
            color: highlightColor
        });

        style += addStyle('.cesium-credit-lightbox.cesium-credit-lightbox-expanded', {
            border : '1px solid #444',
            'border-radius' : '5px',
            'max-width' : '370px'
        });

        style += addStyle('.cesium-credit-lightbox.cesium-credit-lightbox-mobile', {
            height : '100%',
            width : '100%'
        });

        style += addStyle('.cesium-credit-lightbox-title', {
            padding : '20px 20px 0 20px'
        });

        style += addStyle('.cesium-credit-lightbox-close', {
            'font-size' : '18pt',
            cursor : 'pointer',
            position : 'absolute',
            top : '0',
            right : '6px',
            color : textColor
        });

        style += addStyle('.cesium-credit-lightbox-close:hover', {
            color : highlightColor
        });

        style += addStyle('.cesium-credit-lightbox > ul', {
            margin : '0',
            padding : '12px 20px 12px 40px',
            'font-size' : '13px'
        });

        style += addStyle('.cesium-credit-lightbox > ul > li', {
            'padding-bottom' : '6px'
        });

        style += addStyle('.cesium-credit-lightbox > ul > li *', {
            padding : '0',
            margin : '0'
        });

        style += addStyle('.cesium-credit-expand-link', {
            'padding-left' : '5px',
            cursor : 'pointer',
            'text-decoration' : 'underline',
            color: textColor
        });
        style += addStyle('.cesium-credit-expand-link:hover', {
            'color' : highlightColor
        });

        style += addStyle('.cesium-credit-text', {
            color: textColor
        });

        style += addStyle('.cesium-credit-textContainer *, .cesium-credit-logoContainer *', {
            display: 'inline'
        });

        css.innerHTML = style;

        head.insertBefore(css, head.firstChild);
    }

    var cesiumLogo = buildModuleUrl('Assets/Images/cesium_credit.png');
    var cesiumCredit = new Credit('', true);

    /**
     * The credit display is responsible for displaying credits on screen.
     *
     * @param {HTMLElement} container The HTML element where credits will be displayed
     * @param {String} [delimiter= ' • '] The string to separate text credits
     * @param {HTMLElement} [viewport=document.body] The HTML element that will contain the credits popup
     *
     * @alias CreditDisplay
     * @constructor
     *
     * @example
     * var creditDisplay = new Cesium.CreditDisplay(creditContainer);
     */
    function CreditDisplay(container, delimiter, viewport) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('container', container);
        //>>includeEnd('debug');
        var that = this;

        viewport = defaultValue(viewport, document.body);

        var lightbox = document.createElement('div');
        lightbox.className = 'cesium-credit-lightbox-overlay';
        viewport.appendChild(lightbox);

        var lightboxCredits = document.createElement('div');
        lightboxCredits.className = 'cesium-credit-lightbox';
        lightbox.appendChild(lightboxCredits);

        function hideLightbox(event) {
            if (lightboxCredits.contains(event.target)) {
                return;
            }
            that.hideLightbox();
        }
        lightbox.addEventListener('click', hideLightbox, false);

        var title = document.createElement('div');
        title.className = 'cesium-credit-lightbox-title';
        title.textContent = 'Data provided by:';
        lightboxCredits.appendChild(title);

        var closeButton = document.createElement('a');
        closeButton.onclick = this.hideLightbox.bind(this);
        closeButton.innerHTML = '×';
        closeButton.className = 'cesium-credit-lightbox-close';
        lightboxCredits.appendChild(closeButton);

        var creditList = document.createElement('ul');
        lightboxCredits.appendChild(creditList);

        var cesiumCreditContainer = document.createElement('div');
        cesiumCreditContainer.className = 'cesium-credit-logoContainer';
        cesiumCreditContainer.style.display = 'inline';
        container.appendChild(cesiumCreditContainer);

        var screenContainer = document.createElement('div');
        screenContainer.className = 'cesium-credit-textContainer';
        screenContainer.style.display = 'inline';
        container.appendChild(screenContainer);

        var expandLink = document.createElement('a');
        expandLink.className = 'cesium-credit-expand-link';
        expandLink.onclick = this.showLightbox.bind(this);
        expandLink.textContent = 'Data attribution';
        container.appendChild(expandLink);

        appendCss();

        this._delimiter = defaultValue(delimiter, ' • ');
        this._screenContainer = screenContainer;
        this._cesiumCreditContainer = cesiumCreditContainer;
        this._lastViewportHeight = undefined;
        this._lastViewportWidth = undefined;
        this._lightboxCredits = lightboxCredits;
        this._creditList = creditList;
        this._lightbox = lightbox;
        this._hideLightbox = hideLightbox;
        this._expandLink = expandLink;
        this._expanded = false;
        this._defaultCredits = [];
        this._previousCesiumCredit = undefined;
        this._currentCesiumCredit = CreditDisplay.cesiumCredit;

        this._displayedCredits = {
            screenCredits : [],
            lightboxCredits : []
        };
        this._currentFrameCredits = {
            screenCredits : [],
            lightboxCredits : []
        };

        this.viewport = viewport;

        /**
         * The HTML element where credits will be displayed.
         * @type {HTMLElement}
         */
        this.container = container;
    }

    /**
     * Adds a credit to the list of current credits to be displayed in the credit container
     *
     * @param {Credit} credit The credit to display
     */
    CreditDisplay.prototype.addCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var screenCredits = this._currentFrameCredits.screenCredits;

        if (credit._isIon) {
            this._currentCesiumCredit = credit;
        } else if (!credit.showOnScreen) {
            this._currentFrameCredits.lightboxCredits[credit.id] = credit;
        } else {
            screenCredits[credit.id] = credit;
        }
    };

    /**
     * Adds credits that will persist until they are removed
     *
     * @param {Credit} credit The credit to added to defaults
     */
    CreditDisplay.prototype.addDefaultCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var credits = this._defaultCredits;
        if (!contains(credits, credit)) {
            credits.push(credit);
        }
    };

    /**
     * Removes a default credit
     *
     * @param {Credit} credit The credit to be removed from defaults
     */
    CreditDisplay.prototype.removeDefaultCredit = function(credit) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('credit', credit);
        //>>includeEnd('debug');

        var index = this._defaultCredits.indexOf(credit);
        if (index !== -1) {
            this._defaultCredits.splice(index, 1);
        }
    };

    CreditDisplay.prototype.showLightbox = function() {
        this._lightbox.style.display = 'block';
        this._expanded = true;
    };

    CreditDisplay.prototype.hideLightbox = function() {
        this._lightbox.style.display = 'none';
        this._expanded = false;
    };

    /**
     * Updates the credit display before a new frame is rendered.
     */
    CreditDisplay.prototype.update = function() {
        var displayedLightboxCredits = [];

        if (this._expanded && defined(this._creditsToUpdate)) {
            styleLightboxContainer(this);
            displayLightboxCredits(this, this._creditsToUpdate);
            displayedLightboxCredits = this._creditsToUpdate.slice();
        }

        removeUnusedLightboxCredits(this);

        this._displayedCredits.lightboxCredits = displayedLightboxCredits;
    };

    /**
     * Resets the credit display to a beginning of frame state, clearing out current credits.
     */
    CreditDisplay.prototype.beginFrame = function() {
        this._currentFrameCredits.screenCredits.length = 0;
        this._currentFrameCredits.lightboxCredits.length = 0;
        this._currentCesiumCredit = CreditDisplay.cesiumCredit;
    };

    /**
     * Sets the credit display to the end of frame state, displaying credits from the last frame in the credit container.
     */
    CreditDisplay.prototype.endFrame = function() {
        displayCredits(this, this._defaultCredits);
        displayCredits(this, this._currentFrameCredits.screenCredits);

        var displayedScreenCredits = this._defaultCredits.concat(this._currentFrameCredits.screenCredits);

        var showLightboxLink = this._currentFrameCredits.lightboxCredits.length > 0;
        this._expandLink.style.display = showLightboxLink ? 'inline' : 'none';

        removeUnusedCredits(this);
        swapCesiumCredit(this);

        this._displayedCredits.screenCredits = displayedScreenCredits;

        this._creditsToUpdate = this._currentFrameCredits.lightboxCredits.slice();
    };

    /**
     * Destroys the resources held by this object.  Destroying an object allows for deterministic
     * release of resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     */
    CreditDisplay.prototype.destroy = function() {
        this._lightbox.removeEventListener('click', this._hideLightbox, false);

        this.container.removeChild(this._cesiumCreditContainer);
        this.container.removeChild(this._screenContainer);
        this.container.removeChild(this._expandLink);
        this.viewport.removeChild(this._lightbox);

        return destroyObject(this);
    };

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     *
     * @returns {Boolean} true if this object was destroyed; otherwise, false.
     */
    CreditDisplay.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Gets or sets the Cesium logo credit.
     * @type {Credit}
     */
    CreditDisplay.cesiumCredit = cesiumCredit;

    return CreditDisplay;
});
<|endoftext|>


<commit_before>import Cartesian3 from "../Core/Cartesian3.js";
import Cartesian4 from "../Core/Cartesian4.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";
import GeometryPipeline from "../Core/GeometryPipeline.js";
import CesiumMath from "../Core/Math.js";
import Matrix3 from "../Core/Matrix3.js";
import Matrix4 from "../Core/Matrix4.js";
import VertexFormat from "../Core/VertexFormat.js";
import BufferUsage from "../Renderer/BufferUsage.js";
import DrawCommand from "../Renderer/DrawCommand.js";
import RenderState from "../Renderer/RenderState.js";
import ShaderProgram from "../Renderer/ShaderProgram.js";
import ShaderSource from "../Renderer/ShaderSource.js";
import VertexArray from "../Renderer/VertexArray.js";
import SkyAtmosphereCommon from "../Shaders/SkyAtmosphereCommon.js";
import SkyAtmosphereFS from "../Shaders/SkyAtmosphereFS.js";
import SkyAtmosphereVS from "../Shaders/SkyAtmosphereVS.js";
import Axis from "./Axis.js";
import BlendingState from "./BlendingState.js";
import CullFace from "./CullFace.js";
import SceneMode from "./SceneMode.js";

/**
 * An atmosphere drawn around the limb of the provided ellipsoid.  Based on
 * {@link https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering}
 * in GPU Gems 2.
 *

 * This is only supported in 3D. Atmosphere is faded out when morphing to 2D or Columbus view.
 *

 *
 * @alias SkyAtmosphere
 * @constructor
 *
 * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around.
 *
 * @example
 * scene.skyAtmosphere = new Cesium.SkyAtmosphere();
 *
 * @demo {@link https://sandcastle.cesium.com/index.html?src=Sky%20Atmosphere.html|Sky atmosphere demo in Sandcastle}
 *
 * @see Scene.skyAtmosphere
 */
function SkyAtmosphere(ellipsoid) {
  ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

  /**
   * Determines if the atmosphere is shown.
   *
   * @type {Boolean}
   * @default true
   */
  this.show = true;

  /**
   * Compute atmosphere per-fragment instead of per-vertex.
   * This produces better looking atmosphere with a slight performance penalty.
   *
   * @type {Boolean}
   * @default false
   */
  this.perFragmentAtmosphere = false;

  this._ellipsoid = ellipsoid;

  var scaleVector = Cartesian3.multiplyByScalar(
    ellipsoid.radii,
    1.025,
    new Cartesian3()
  );
  this._scaleMatrix = Matrix4.fromScale(scaleVector);
  this._modelMatrix = new Matrix4();

  this._command = new DrawCommand({
    owner: this,
    modelMatrix: this._modelMatrix,
  });
  this._spSkyFromSpace = undefined;
  this._spSkyFromAtmosphere = undefined;

  this._flags = undefined;

  /**
   * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A hue shift of 1.0 indicates a complete rotation of the hues available.
   * @type {Number}
   * @default 0.0
   */
  this.hueShift = 0.0;

  /**
   * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A saturation shift of -1.0 is monochrome.
   * @type {Number}
   * @default 0.0
   */
  this.saturationShift = 0.0;

  /**
   * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A brightness shift of -1.0 is complete darkness, which will let space show through.
   * @type {Number}
   * @default 0.0
   */
  this.brightnessShift = 0.0;

  this._hueSaturationBrightness = new Cartesian3();

  // outer radius, inner radius, dynamic atmosphere color flag, inverse scale
  var radiiAndDynamicAtmosphereColorAndInverseScale = new Cartesian4();

  radiiAndDynamicAtmosphereColorAndInverseScale.x =
    ellipsoid.maximumRadius * 1.025;
  radiiAndDynamicAtmosphereColorAndInverseScale.y = ellipsoid.maximumRadius;

  // Toggles whether the sun position is used. 0 treats the sun as always directly overhead.
  radiiAndDynamicAtmosphereColorAndInverseScale.z = 0;

  // Controls the distance below the horizon at which atmosphere transitions from its brightest to a more neutral blue color
  // Higher values push the transition point further below the horizon
  radiiAndDynamicAtmosphereColorAndInverseScale.w = 1.003;

  this._radiiAndDynamicAtmosphereColorAndInverseScale = radiiAndDynamicAtmosphereColorAndInverseScale;

  var that = this;

  this._command.uniformMap = {
    u_radiiAndDynamicAtmosphereColorAndInverseScale: function () {
      return that._radiiAndDynamicAtmosphereColorAndInverseScale;
    },
    u_hsbShift: function () {
      that._hueSaturationBrightness.x = that.hueShift;
      that._hueSaturationBrightness.y = that.saturationShift;
      that._hueSaturationBrightness.z = that.brightnessShift;
      return that._hueSaturationBrightness;
    },
  };
}

Object.defineProperties(SkyAtmosphere.prototype, {
  /**
   * Gets the ellipsoid the atmosphere is drawn around.
   * @memberof SkyAtmosphere.prototype
   *
   * @type {Ellipsoid}
   * @readonly
   */
  ellipsoid: {
    get: function () {
      return this._ellipsoid;
    },
  },
});

/**
 * @private
 */
SkyAtmosphere.prototype.setDynamicAtmosphereColor = function (
  enableLighting,
  useSunDirection
) {
  var lightEnum = enableLighting ? (useSunDirection ? 2.0 : 1.0) : 0.0;
  this._radiiAndDynamicAtmosphereColorAndInverseScale.z = lightEnum;
};

var scratchRotationMatrix = new Matrix3();
var scratchModelMatrix = new Matrix4();

/**
 * @private
 */
SkyAtmosphere.prototype.update = function (frameState) {
  if (!this.show) {
    return undefined;
  }

  var mode = frameState.mode;
  if (mode !== SceneMode.SCENE3D && mode !== SceneMode.MORPHING) {
    return undefined;
  }

  // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc.
  if (!frameState.passes.render) {
    return undefined;
  }

  // Align the ellipsoid geometry so it always faces the same direction as the
  // camera to reduce artifacts when rendering atmosphere per-vertex
  var view = frameState.context.uniformState.viewRotation;
  var inverseView = Matrix3.inverse(view, scratchRotationMatrix);
  var rotationMatrix = Matrix4.fromRotationTranslation(
    inverseView,
    Cartesian3.ZERO,
    scratchModelMatrix
  );
  var rotationOffsetMatrix = Matrix4.multiplyTransformation(
    rotationMatrix,
    Axis.Y_UP_TO_Z_UP,
    scratchModelMatrix
  );
  var modelMatrix = Matrix4.multiply(
    this._scaleMatrix,
    rotationOffsetMatrix,
    scratchModelMatrix
  );
  Matrix4.clone(modelMatrix, this._modelMatrix);

  var context = frameState.context;

  var colorCorrect = hasColorCorrection(this);
  var perFragmentAtmosphere = this.perFragmentAtmosphere;

  var command = this._command;

  if (!defined(command.vertexArray)) {
    var geometry = EllipsoidGeometry.createGeometry(
      new EllipsoidGeometry({
        radii: new Cartesian3(1.0, 1.0, 1.0),
        slicePartitions: 256,
        stackPartitions: 256,
        vertexFormat: VertexFormat.POSITION_ONLY,
      })
    );
    command.vertexArray = VertexArray.fromGeometry({
      context: context,
      geometry: geometry,
      attributeLocations: GeometryPipeline.createAttributeLocations(geometry),
      bufferUsage: BufferUsage.STATIC_DRAW,
    });
    command.renderState = RenderState.fromCache({
      cull: {
        enabled: true,
        face: CullFace.FRONT,
      },
      blending: BlendingState.ALPHA_BLEND,
      depthMask: false,
    });
  }

  var flags = colorCorrect | (perFragmentAtmosphere << 2);

  if (flags !== this._flags) {
    this._flags = flags;

    var defines = [];

    if (colorCorrect) {
      defines.push("COLOR_CORRECT");
    }

    if (perFragmentAtmosphere) {
      defines.push("PER_FRAGMENT_ATMOSPHERE");
    }

    var vs = new ShaderSource({
      defines: defines.concat("SKY_FROM_SPACE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
    });

    var fs = new ShaderSource({
      defines: defines.concat("SKY_FROM_SPACE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
    });

    this._spSkyFromSpace = ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: vs,
      fragmentShaderSource: fs,
    });

    vs = new ShaderSource({
      defines: defines.concat("SKY_FROM_ATMOSPHERE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
    });

    fs = new ShaderSource({
      defines: defines.concat("SKY_FROM_ATMOSPHERE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
    });

    this._spSkyFromAtmosphere = ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: vs,
      fragmentShaderSource: fs,
    });
  }

  var cameraPosition = frameState.camera.positionWC;
  var cameraHeight = Cartesian3.magnitude(cameraPosition);

  if (cameraHeight > this._radiiAndDynamicAtmosphereColorAndInverseScale.x) {
    // Camera in space
    command.shaderProgram = this._spSkyFromSpace;
  } else {
    // Camera in atmosphere
    command.shaderProgram = this._spSkyFromAtmosphere;
  }

  return command;
};

function hasColorCorrection(skyAtmosphere) {
  return !(
    CesiumMath.equalsEpsilon(
      skyAtmosphere.hueShift,
      0.0,
      CesiumMath.EPSILON7
    ) &&
    CesiumMath.equalsEpsilon(
      skyAtmosphere.saturationShift,
      0.0,
      CesiumMath.EPSILON7
    ) &&
    CesiumMath.equalsEpsilon(
      skyAtmosphere.brightnessShift,
      0.0,
      CesiumMath.EPSILON7
    )
  );
}

/**
 * Returns true if this object was destroyed; otherwise, false.
 *

 * If this object was destroyed, it should not be used; calling any function other than
 * isDestroyed will result in a {@link DeveloperError} exception.
 *
 * @returns {Boolean} true if this object was destroyed; otherwise, false.
 *
 * @see SkyAtmosphere#destroy
 */
SkyAtmosphere.prototype.isDestroyed = function () {
  return false;
};

/**
 * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
 * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
 *

 * Once an object is destroyed, it should not be used; calling any function other than
 * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
 * assign the return value (undefined) to the object as done in the example.
 *
 * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
 *
 *
 * @example
 * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy();
 *
 * @see SkyAtmosphere#isDestroyed
 */
SkyAtmosphere.prototype.destroy = function () {
  var command = this._command;
  command.vertexArray = command.vertexArray && command.vertexArray.destroy();
  this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
  this._spSkyFromAtmosphere =
    this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
  return destroyObject(this);
};
export default SkyAtmosphere;
<commit_msg>Updates from review<commit_after>import Cartesian3 from "../Core/Cartesian3.js";
import Cartesian4 from "../Core/Cartesian4.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";
import GeometryPipeline from "../Core/GeometryPipeline.js";
import CesiumMath from "../Core/Math.js";
import Matrix3 from "../Core/Matrix3.js";
import Matrix4 from "../Core/Matrix4.js";
import VertexFormat from "../Core/VertexFormat.js";
import BufferUsage from "../Renderer/BufferUsage.js";
import DrawCommand from "../Renderer/DrawCommand.js";
import RenderState from "../Renderer/RenderState.js";
import ShaderProgram from "../Renderer/ShaderProgram.js";
import ShaderSource from "../Renderer/ShaderSource.js";
import VertexArray from "../Renderer/VertexArray.js";
import SkyAtmosphereCommon from "../Shaders/SkyAtmosphereCommon.js";
import SkyAtmosphereFS from "../Shaders/SkyAtmosphereFS.js";
import SkyAtmosphereVS from "../Shaders/SkyAtmosphereVS.js";
import Axis from "./Axis.js";
import BlendingState from "./BlendingState.js";
import CullFace from "./CullFace.js";
import SceneMode from "./SceneMode.js";

/**
 * An atmosphere drawn around the limb of the provided ellipsoid.  Based on
 * {@link https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering}
 * in GPU Gems 2.
 *

 * This is only supported in 3D. Atmosphere is faded out when morphing to 2D or Columbus view.
 *

 *
 * @alias SkyAtmosphere
 * @constructor
 *
 * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around.
 *
 * @example
 * scene.skyAtmosphere = new Cesium.SkyAtmosphere();
 *
 * @demo {@link https://sandcastle.cesium.com/index.html?src=Sky%20Atmosphere.html|Sky atmosphere demo in Sandcastle}
 *
 * @see Scene.skyAtmosphere
 */
function SkyAtmosphere(ellipsoid) {
  ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

  /**
   * Determines if the atmosphere is shown.
   *
   * @type {Boolean}
   * @default true
   */
  this.show = true;

  /**
   * Compute atmosphere per-fragment instead of per-vertex.
   * This produces better looking atmosphere with a slight performance penalty.
   *
   * @type {Boolean}
   * @default false
   */
  this.perFragmentAtmosphere = false;

  this._ellipsoid = ellipsoid;

  var scaleVector = Cartesian3.multiplyByScalar(
    ellipsoid.radii,
    1.025,
    new Cartesian3()
  );
  this._scaleMatrix = Matrix4.fromScale(scaleVector);
  this._modelMatrix = new Matrix4();

  this._command = new DrawCommand({
    owner: this,
    modelMatrix: this._modelMatrix,
  });
  this._spSkyFromSpace = undefined;
  this._spSkyFromAtmosphere = undefined;

  this._flags = undefined;

  /**
   * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A hue shift of 1.0 indicates a complete rotation of the hues available.
   * @type {Number}
   * @default 0.0
   */
  this.hueShift = 0.0;

  /**
   * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A saturation shift of -1.0 is monochrome.
   * @type {Number}
   * @default 0.0
   */
  this.saturationShift = 0.0;

  /**
   * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift).
   * A brightness shift of -1.0 is complete darkness, which will let space show through.
   * @type {Number}
   * @default 0.0
   */
  this.brightnessShift = 0.0;

  this._hueSaturationBrightness = new Cartesian3();

  // outer radius, inner radius, dynamic atmosphere color flag, inverse scale
  var radiiAndDynamicAtmosphereColorAndInverseScale = new Cartesian4();

  radiiAndDynamicAtmosphereColorAndInverseScale.x =
    ellipsoid.maximumRadius * 1.025;
  radiiAndDynamicAtmosphereColorAndInverseScale.y = ellipsoid.maximumRadius;

  // Toggles whether the sun position is used. 0 treats the sun as always directly overhead.
  radiiAndDynamicAtmosphereColorAndInverseScale.z = 0;

  // Controls the distance below the horizon at which atmosphere transitions from its brightest to a more neutral blue color
  // Higher values push the transition point further below the horizon
  radiiAndDynamicAtmosphereColorAndInverseScale.w = 1.003;

  this._radiiAndDynamicAtmosphereColorAndInverseScale = radiiAndDynamicAtmosphereColorAndInverseScale;

  var that = this;

  this._command.uniformMap = {
    u_radiiAndDynamicAtmosphereColorAndInverseScale: function () {
      return that._radiiAndDynamicAtmosphereColorAndInverseScale;
    },
    u_hsbShift: function () {
      that._hueSaturationBrightness.x = that.hueShift;
      that._hueSaturationBrightness.y = that.saturationShift;
      that._hueSaturationBrightness.z = that.brightnessShift;
      return that._hueSaturationBrightness;
    },
  };
}

Object.defineProperties(SkyAtmosphere.prototype, {
  /**
   * Gets the ellipsoid the atmosphere is drawn around.
   * @memberof SkyAtmosphere.prototype
   *
   * @type {Ellipsoid}
   * @readonly
   */
  ellipsoid: {
    get: function () {
      return this._ellipsoid;
    },
  },
});

/**
 * @private
 */
SkyAtmosphere.prototype.setDynamicAtmosphereColor = function (
  enableLighting,
  useSunDirection
) {
  var lightEnum = enableLighting ? (useSunDirection ? 2.0 : 1.0) : 0.0;
  this._radiiAndDynamicAtmosphereColorAndInverseScale.z = lightEnum;
};

var scratchModelMatrix = new Matrix4();

/**
 * @private
 */
SkyAtmosphere.prototype.update = function (frameState) {
  if (!this.show) {
    return undefined;
  }

  var mode = frameState.mode;
  if (mode !== SceneMode.SCENE3D && mode !== SceneMode.MORPHING) {
    return undefined;
  }

  // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc.
  if (!frameState.passes.render) {
    return undefined;
  }

  // Align the ellipsoid geometry so it always faces the same direction as the
  // camera to reduce artifacts when rendering atmosphere per-vertex
  var rotationMatrix = Matrix4.fromRotationTranslation(
    frameState.context.uniformState.inverseViewRotation,
    Cartesian3.ZERO,
    scratchModelMatrix
  );
  var rotationOffsetMatrix = Matrix4.multiplyTransformation(
    rotationMatrix,
    Axis.Y_UP_TO_Z_UP,
    scratchModelMatrix
  );
  var modelMatrix = Matrix4.multiply(
    this._scaleMatrix,
    rotationOffsetMatrix,
    scratchModelMatrix
  );
  Matrix4.clone(modelMatrix, this._modelMatrix);

  var context = frameState.context;

  var colorCorrect = hasColorCorrection(this);
  var perFragmentAtmosphere = this.perFragmentAtmosphere;

  var command = this._command;

  if (!defined(command.vertexArray)) {
    var geometry = EllipsoidGeometry.createGeometry(
      new EllipsoidGeometry({
        radii: new Cartesian3(1.0, 1.0, 1.0),
        slicePartitions: 256,
        stackPartitions: 256,
        vertexFormat: VertexFormat.POSITION_ONLY,
      })
    );
    command.vertexArray = VertexArray.fromGeometry({
      context: context,
      geometry: geometry,
      attributeLocations: GeometryPipeline.createAttributeLocations(geometry),
      bufferUsage: BufferUsage.STATIC_DRAW,
    });
    command.renderState = RenderState.fromCache({
      cull: {
        enabled: true,
        face: CullFace.FRONT,
      },
      blending: BlendingState.ALPHA_BLEND,
      depthMask: false,
    });
  }

  var flags = colorCorrect | (perFragmentAtmosphere << 2);

  if (flags !== this._flags) {
    this._flags = flags;

    var defines = [];

    if (colorCorrect) {
      defines.push("COLOR_CORRECT");
    }

    if (perFragmentAtmosphere) {
      defines.push("PER_FRAGMENT_ATMOSPHERE");
    }

    var vs = new ShaderSource({
      defines: defines.concat("SKY_FROM_SPACE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
    });

    var fs = new ShaderSource({
      defines: defines.concat("SKY_FROM_SPACE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
    });

    this._spSkyFromSpace = ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: vs,
      fragmentShaderSource: fs,
    });

    vs = new ShaderSource({
      defines: defines.concat("SKY_FROM_ATMOSPHERE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
    });

    fs = new ShaderSource({
      defines: defines.concat("SKY_FROM_ATMOSPHERE"),
      sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
    });

    this._spSkyFromAtmosphere = ShaderProgram.fromCache({
      context: context,
      vertexShaderSource: vs,
      fragmentShaderSource: fs,
    });
  }

  var cameraPosition = frameState.camera.positionWC;
  var cameraHeight = Cartesian3.magnitude(cameraPosition);

  if (cameraHeight > this._radiiAndDynamicAtmosphereColorAndInverseScale.x) {
    // Camera in space
    command.shaderProgram = this._spSkyFromSpace;
  } else {
    // Camera in atmosphere
    command.shaderProgram = this._spSkyFromAtmosphere;
  }

  return command;
};

function hasColorCorrection(skyAtmosphere) {
  return !(
    CesiumMath.equalsEpsilon(
      skyAtmosphere.hueShift,
      0.0,
      CesiumMath.EPSILON7
    ) &&
    CesiumMath.equalsEpsilon(
      skyAtmosphere.saturationShift,
      0.0,
      CesiumMath.EPSILON7
    ) &&
    CesiumMath.equalsEpsilon(
      skyAtmosphere.brightnessShift,
      0.0,
      CesiumMath.EPSILON7
    )
  );
}

/**
 * Returns true if this object was destroyed; otherwise, false.
 *

 * If this object was destroyed, it should not be used; calling any function other than
 * isDestroyed will result in a {@link DeveloperError} exception.
 *
 * @returns {Boolean} true if this object was destroyed; otherwise, false.
 *
 * @see SkyAtmosphere#destroy
 */
SkyAtmosphere.prototype.isDestroyed = function () {
  return false;
};

/**
 * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
 * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
 *

 * Once an object is destroyed, it should not be used; calling any function other than
 * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
 * assign the return value (undefined) to the object as done in the example.
 *
 * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
 *
 *
 * @example
 * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy();
 *
 * @see SkyAtmosphere#isDestroyed
 */
SkyAtmosphere.prototype.destroy = function () {
  var command = this._command;
  command.vertexArray = command.vertexArray && command.vertexArray.destroy();
  this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
  this._spSkyFromAtmosphere =
    this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
  return destroyObject(this);
};
export default SkyAtmosphere;
<|endoftext|>


<commit_before>var request = require('request');
var config = require('./config');
var skins = require('./skins');

var session_url = "https://sessionserver.mojang.com/session/minecraft/profile/";

var exp = {};

// download the Mojang profile for +uuid+
// callback contains error, profile object
exp.get_profile = function(uuid, callback) {
  if (uuid.length <= 16) {
    callback(null, null);
    return;
  }
  request.get({
    url: session_url + uuid,
    timeout: config.http_timeout // ms
  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // profile downloaded successfully
      console.log(uuid + " profile downloaded");
      callback(null, JSON.parse(body));
    } else if (error) {
      callback(error, null);
    } else if (response.statusCode == 204 || response.statusCode == 404) {
      // we get 204 No Content when UUID doesn't exist (including 404 in case they change that)
      console.log(uuid + " uuid does not exist");
      callback(0, null);
    } else if (response.statusCode == 429) {
      // Too Many Requests
      console.warn(uuid + " Too many requests");
      console.warn(body);
      callback(null, null);
    } else {
      console.error(uuid + " Unknown error:");
      console.error(response);
      console.error(body);
      callback(null, null);
    }
  });
};

// downloads skin file from +url+
// stores face image as +facename+
// stores helm image as +helmname+
// callback is forwarded from skins/extract_face or skins/extract_helm
exp.skin_file = function(url, facename, helmname, callback) {
  request.get({
    url: url,
    encoding: null, // encoding must be null so we get a buffer
    timeout: config.http_timeout // ms
  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // skin downloaded successfully
      console.log(url + " skin downloaded");
      skins.extract_face(body, facename, function(err) {
        if (err) {
          callback(err);
        } else {
          console.log(facename + " face extracted");
          skins.extract_helm(facename, body, helmname, function(err) {
            console.log(helmname + " helm extracted.");
            callback(err);
          });
        }
      });
    } else {
      if (error) {
        console.error("Error downloading '" + url + "': " + error);
      } else if (response.statusCode == 404) {
        console.warn(url + " texture not found");
        error = "texture not found" // Setting error
      } else if (response.statusCode == 429) {
        // Too Many Requests
        // Never got this, seems like textures aren't limited
        error = "too many requests" // Error needs to be set, otherwise null in callback
        console.warn(url + " too many requests");
        console.warn(body);
      } else {
        console.error(url + " unknown error:");
        console.error(response);
        console.error(body);
        error = "unknown error" // Setting error
      }
      callback(error);
    }
  });
};

module.exports = exp;<commit_msg>removing some errors in networking.skin_file callback 404 shouldn't return an error, null is fine. Setting the error causes that non-existing skins aren't cached. Thus we'd always make a new request to mojang, which will result in hitting the (sessionserver's) rate limit Removing the error for Too Many Requests for the same reason.<commit_after>var request = require('request');
var config = require('./config');
var skins = require('./skins');

var session_url = "https://sessionserver.mojang.com/session/minecraft/profile/";

var exp = {};

// download the Mojang profile for +uuid+
// callback contains error, profile object
exp.get_profile = function(uuid, callback) {
  if (uuid.length <= 16) {
    callback(null, null);
    return;
  }
  request.get({
    url: session_url + uuid,
    timeout: config.http_timeout // ms
  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // profile downloaded successfully
      console.log(uuid + " profile downloaded");
      callback(null, JSON.parse(body));
    } else if (error) {
      callback(error, null);
    } else if (response.statusCode == 204 || response.statusCode == 404) {
      // we get 204 No Content when UUID doesn't exist (including 404 in case they change that)
      console.log(uuid + " uuid does not exist");
      callback(0, null);
    } else if (response.statusCode == 429) {
      // Too Many Requests
      console.warn(uuid + " Too many requests");
      console.warn(body);
      callback(null, null);
    } else {
      console.error(uuid + " Unknown error:");
      console.error(response);
      console.error(body);
      callback(null, null);
    }
  });
};

// downloads skin file from +url+
// stores face image as +facename+
// stores helm image as +helmname+
// callback is forwarded from skins/extract_face or skins/extract_helm
exp.skin_file = function(url, facename, helmname, callback) {
  request.get({
    url: url,
    encoding: null, // encoding must be null so we get a buffer
    timeout: config.http_timeout // ms
  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // skin downloaded successfully
      console.log(url + " skin downloaded");
      skins.extract_face(body, facename, function(err) {
        if (err) {
          callback(err);
        } else {
          console.log(facename + " face extracted");
          skins.extract_helm(facename, body, helmname, function(err) {
            console.log(helmname + " helm extracted.");
            callback(err);
          });
        }
      });
    } else {
      if (error) {
        console.error("Error downloading '" + url + "': " + error);
      } else if (response.statusCode == 404) {
        console.warn(url + " texture not found");
      } else if (response.statusCode == 429) {
        // Too Many Requests
        // Never got this, seems like textures aren't limited
        console.warn(url + " too many requests");
        console.warn(body);
      } else {
        console.error(url + " unknown error:");
        console.error(response);
        console.error(body);
        error = "unknown error"; // Error needs to be set, otherwise null in callback
      }
      callback(error);
    }
  });
};

module.exports = exp;<|endoftext|>


<commit_before>module.exports = ElastoCss

function ElastoCss (localName) {
  this.localName = localName
  this.css = null
  this.rawRules = []
  this.styleElement = null
}

ElastoCss.map = {}

ElastoCss.getInstance = function (localName, css) {
  var map = ElastoCss.map

  if (!map[localName]) {
    map[localName] = new ElastoCss(localName)
  }
  if (css) {
    map[localName].inject(css)
  }
  return map[localName]
}

ElastoCss.transform = function (src, localName, rawRules) {
  rawRules = rawRules || []

  // Ignore comments
  src = src.replace(/\/\*(.|\n)*?\*\//g, '')

  src = src.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, function (match, rule, rest) {
    if (/^@/.test(rule)) {
      return rule + ' ' + rest
    }
    rule = rule.trim()
    rawRules.push(rule)
    rule = ElastoCss.scopeRule(rule, localName)
    return rule + ' ' + rest
  })

  return src
}

ElastoCss.scopeRule = function (rule, localName) {

  var hasHost = /^:host/.test(rule)
  var hostOnly = /^:host(?:\([^\)]+\))?$/.test(rule)

  if (hasHost && (rule === ':host')) {
    return localName
  }

  if (hasHost) {
    rule = rule.replace(/^:host(?:\(([^\)]+)\))?/, localName + '$1').trim()
  }

  rule = rule.replace(/(\/deep\/|::shadow)/g, ' ')
  rule = rule.replace(/::content/g, 'content')

  // Add element scope (if not a :host only rull)
  if (!hostOnly) {
    var splitted = rule.split(/(^|[\s>+~]+)([^\s>+~]+)/g).filter(function (s) { return Boolean(s) })
    var last = splitted[splitted.length - 1]
    var injected = last.split(/(:?[^\s\:\[]+)([\:\[].+)?/).filter(function (s) { return Boolean(s) })
    injected[0] = injected[0] + '.' + localName + '-scope'
    splitted[splitted.length - 1] = injected.join('')
    rule = splitted.join('')
  }

  rule = (hasHost ? '' : localName + ' ') + rule
  return rule
}

ElastoCss.prototype.inject = function (src) {
  if (this.css === src) {
    // No changes. Ignore
    return
  }
  this.css = src
  this.rawRules = []
  src = ElastoCss.transform(src, this.localName, this.rawRules)

  var style = this._getStyleElement()

  if (style.styleSheet) {
    style.styleSheet.cssText = src
  } else {
    style.textContent = src
  }
}

ElastoCss.prototype.getSelectors = function () {
  return this.rawRules.map(function (rule) {
    rule = rule.replace(/:host(\([^\)]+\))?\s*/g, '') // :host(...) too
    // Remove some pseudo-class
    rule = rule.replace(/:(link|visited|hover|active)$/, '')
    // Remove native shadow dom rules
    rule = rule.replace(/(\/deep\/|::shadow)/g, ' ')
    rule = rule.replace(/::content/g, 'content')
    return rule.trim()
  })
  .filter(function (rule) {
    return Boolean(rule)
  })
}

ElastoCss.prototype._getStyleElement = function () {
  if (this.styleElement) {
    return this.styleElement
  }

  var style = document.querySelector('head style[elasto-scope="' + this.localName + '"]')

  if (style) {
    this.styleElement = style
    return this.styleElement
  }

  var ref = document.head.querySelector('style, link[rel=stylesheet]')

  style = document.createElement('style')
  style.setAttribute('type', 'text/css')
  style.setAttribute('elasto-scope', this.localName)

  if (ref) {
    document.head.insertBefore(style, ref)
  } else {
    document.head.appendChild(style)
  }

  this.styleElement = style

  return this.styleElement
}
<commit_msg>fix: Ignore keyframe rules<commit_after>module.exports = ElastoCss

function ElastoCss (localName) {
  this.localName = localName
  this.css = null
  this.rawRules = []
  this.styleElement = null
}

ElastoCss.map = {}

ElastoCss.getInstance = function (localName, css) {
  var map = ElastoCss.map

  if (!map[localName]) {
    map[localName] = new ElastoCss(localName)
  }
  if (css) {
    map[localName].inject(css)
  }
  return map[localName]
}

ElastoCss.transform = function (src, localName, rawRules) {
  rawRules = rawRules || []

  // Ignore comments
  src = src.replace(/\/\*(.|\n)*?\*\//g, '')

  src = src.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, function (match, rule, rest) {
    if (/^@/.test(rule)) {
      return rule + ' ' + rest
    }
    if (/%/.test(rule)) {
      return rule + ' ' + rest
    }
    rule = rule.trim()
    rawRules.push(rule)
    rule = ElastoCss.scopeRule(rule, localName)
    return rule + ' ' + rest
  })

  return src
}

ElastoCss.scopeRule = function (rule, localName) {

  var hasHost = /^:host/.test(rule)
  var hostOnly = /^:host(?:\([^\)]+\))?$/.test(rule)

  if (hasHost && (rule === ':host')) {
    return localName
  }

  if (hasHost) {
    rule = rule.replace(/^:host(?:\(([^\)]+)\))?/, localName + '$1').trim()
  }

  rule = rule.replace(/(\/deep\/|::shadow)/g, ' ')
  rule = rule.replace(/::content/g, 'content')

  // Add element scope (if not a :host only rull)
  if (!hostOnly) {
    var splitted = rule.split(/(^|[\s>+~]+)([^\s>+~]+)/g).filter(function (s) { return Boolean(s) })
    var last = splitted[splitted.length - 1]
    var injected = last.split(/(:?[^\s\:\[]+)([\:\[].+)?/).filter(function (s) { return Boolean(s) })
    injected[0] = injected[0] + '.' + localName + '-scope'
    splitted[splitted.length - 1] = injected.join('')
    rule = splitted.join('')
  }

  rule = (hasHost ? '' : localName + ' ') + rule
  return rule
}

ElastoCss.prototype.inject = function (src) {
  if (this.css === src) {
    // No changes. Ignore
    return
  }
  this.css = src
  this.rawRules = []
  src = ElastoCss.transform(src, this.localName, this.rawRules)

  var style = this._getStyleElement()

  if (style.styleSheet) {
    style.styleSheet.cssText = src
  } else {
    style.textContent = src
  }
}

ElastoCss.prototype.getSelectors = function () {
  return this.rawRules.map(function (rule) {
    rule = rule.replace(/:host(\([^\)]+\))?\s*/g, '') // :host(...) too
    // Remove some pseudo-class
    rule = rule.replace(/:(link|visited|hover|active)$/, '')
    // Remove native shadow dom rules
    rule = rule.replace(/(\/deep\/|::shadow)/g, ' ')
    rule = rule.replace(/::content/g, 'content')
    return rule.trim()
  })
  .filter(function (rule) {
    return Boolean(rule)
  })
}

ElastoCss.prototype._getStyleElement = function () {
  if (this.styleElement) {
    return this.styleElement
  }

  var style = document.querySelector('head style[elasto-scope="' + this.localName + '"]')

  if (style) {
    this.styleElement = style
    return this.styleElement
  }

  var ref = document.head.querySelector('style, link[rel=stylesheet]')

  style = document.createElement('style')
  style.setAttribute('type', 'text/css')
  style.setAttribute('elasto-scope', this.localName)

  if (ref) {
    document.head.insertBefore(style, ref)
  } else {
    document.head.appendChild(style)
  }

  this.styleElement = style

  return this.styleElement
}
<|endoftext|>


<commit_before>'use strict'

var Emitter = require('vigour-js/lib/emitter')
exports.inject = require('./')

var map = {
  // left
  37: 'arrowleft',
  4: 'arrowleft', // samsung

  // right
  39: 'arrowright',
  5: 'right', // samsung

  // up
  38: 'arrowup',
  29460: 'arrowup', // samsung

  // down
  40: 'arrowdown',
  29461: 'arrowdown', // samsung

  // back
  8: 'back',
  88: 'back', // samsung
  1537: 'back', // lg web os
  10009: 'back', // tizen os

  // menu / escape
  27: 'menu',
  75: 'menu',

  // enter
  13: 'enter',
  29443: 'enter',

  // rewind
  227: 'rewind',

  // play
  179: 'playbtn',

  // forward
  228: 'forward',

  // space
  32: 'space'
}

var keyEmitter = new Emitter({
  define: {
    generateConstructor: function () {
      return function DerivedEmitter (val, ev, parent, key) {
        if (parent) {
          let set = {}
          set[key] = function (e, event) {
            if (key === map[e.keyCode]) {
              e.preventDefault()
              this.emit(key, e, event)
            }
          }
          parent.setKey('keydown', set, ev)
        }
        return Emitter.apply(this, arguments)
      }
    }
  }
})

var properties = {}
for (var i in map) {
  var type = map[i]
  if (!properties[type]) {
    properties[type] = keyEmitter
  }
}

exports.on = {
  properties: properties
}
<commit_msg>remove prevent<commit_after>'use strict'

var Emitter = require('vigour-js/lib/emitter')
exports.inject = require('./')

var map = {
  // left
  37: 'arrowleft',
  4: 'arrowleft', // samsung

  // right
  39: 'arrowright',
  5: 'right', // samsung

  // up
  38: 'arrowup',
  29460: 'arrowup', // samsung

  // down
  40: 'arrowdown',
  29461: 'arrowdown', // samsung

  // back
  8: 'back',
  88: 'back', // samsung
  1537: 'back', // lg web os
  10009: 'back', // tizen os

  // menu / escape
  27: 'menu',
  75: 'menu',

  // enter
  13: 'enter',
  29443: 'enter',

  // rewind
  227: 'rewind',

  // play
  179: 'playbtn',

  // forward
  228: 'forward',

  // space
  32: 'space'
}

var keyEmitter = new Emitter({
  define: {
    generateConstructor: function () {
      return function DerivedEmitter (val, ev, parent, key) {
        if (parent) {
          let set = {}
          set[key] = function (e, event) {
            if (key === map[e.keyCode]) {
              this.emit(key, e, event)
            }
          }
          parent.setKey('keydown', set, ev)
        }
        return Emitter.apply(this, arguments)
      }
    }
  }
})

var properties = {}
for (var i in map) {
  var type = map[i]
  if (!properties[type]) {
    properties[type] = keyEmitter
  }
}

exports.on = {
  properties: properties
}
<|endoftext|>


<commit_before>/**
 * +--------------------------------------------------------------------+
 * | This HTML_CodeSniffer file is Copyright (c)                        |
 * | Squiz Pty Ltd (ABN 77 084 670 600)                                 |
 * +--------------------------------------------------------------------+
 * | IMPORTANT: Your use of this Software is subject to the terms of    |
 * | the Licence provided in the file licence.txt. If you cannot find   |
 * | this file please contact Squiz (www.squiz.com.au) so we may        |
 * | provide you a copy.                                                |
 * +--------------------------------------------------------------------+
 *
 */

window.HTMLCS_WCAG2AAA = {
    name: 'WCAG2AAA',
    description: 'Web Content Accessibility Guidelines (WCAG) 2.0 AAA',
    sniffs: [
        'Principle1.Guideline1_1.1_1_1',
        'Principle1.Guideline1_2.1_2_1',
        'Principle1.Guideline1_2.1_2_2',
        'Principle1.Guideline1_2.1_2_4',
        'Principle1.Guideline1_2.1_2_5',
        'Principle1.Guideline1_2.1_2_6',
        'Principle1.Guideline1_2.1_2_7',
        'Principle1.Guideline1_2.1_2_8',
        'Principle1.Guideline1_2.1_2_9',
        'Principle1.Guideline1_3.1_3_1',
        'Principle1.Guideline1_3.1_3_1_AAA',
        'Principle1.Guideline1_3.1_3_2',
        'Principle1.Guideline1_3.1_3_3',
        'Principle1.Guideline1_4.1_4_1',
        'Principle1.Guideline1_4.1_4_2',
        'Principle1.Guideline1_4.1_4_3_F24',
        'Principle1.Guideline1_4.1_4_3_Contrast',
        'Principle1.Guideline1_4.1_4_6',
        'Principle1.Guideline1_4.1_4_7',
        'Principle1.Guideline1_4.1_4_8',
        'Principle1.Guideline1_4.1_4_9',
        'Principle2.Guideline2_1.2_1_1',
        'Principle2.Guideline2_1.2_1_2',
        'Principle2.Guideline2_2.2_2_2',
        'Principle2.Guideline2_2.2_2_3',
        'Principle2.Guideline2_2.2_2_4',
        'Principle2.Guideline2_2.2_2_5',
        'Principle2.Guideline2_3.2_3_2',
        'Principle2.Guideline2_4.2_4_1',
        'Principle2.Guideline2_4.2_4_2',
        'Principle2.Guideline2_4.2_4_3',
        'Principle2.Guideline2_4.2_4_5',
        'Principle2.Guideline2_4.2_4_6',
        'Principle2.Guideline2_4.2_4_7',
        'Principle2.Guideline2_4.2_4_8',
        'Principle2.Guideline2_4.2_4_9',
        'Principle3.Guideline3_1.3_1_1',
        'Principle3.Guideline3_1.3_1_2',
        'Principle3.Guideline3_1.3_1_3',
        'Principle3.Guideline3_1.3_1_4',
        'Principle3.Guideline3_1.3_1_5',
        'Principle3.Guideline3_1.3_1_6',
        'Principle3.Guideline3_2.3_2_1',
        'Principle3.Guideline3_2.3_2_2',
        'Principle3.Guideline3_2.3_2_3',
        'Principle3.Guideline3_2.3_2_4',
        'Principle3.Guideline3_2.3_2_5',
        'Principle3.Guideline3_3.3_3_1',
        'Principle3.Guideline3_3.3_3_2',
        'Principle3.Guideline3_3.3_3_3',
        'Principle3.Guideline3_3.3_3_5',
        'Principle3.Guideline3_3.3_3_6',
        'Principle4.Guideline4_1.4_1_1',
        'Principle4.Guideline4_1.4_1_2'
    ],
    getMsgInfo: function(code) {
        var principles = {
            'Principle1': {
                name: 'Perceivable',
                link: 'http://www.w3.org/TR/WCAG20/#perceivable'
               },
            'Principle2': {
                name: 'Operable',
                link: 'http://www.w3.org/TR/WCAG20/#operable'
               },
            'Principle3': {
                name: 'Understandable',
                link: 'http://www.w3.org/TR/WCAG20/#understandable'
               },
            'Principle4': {
                name: 'Robust',
                link: 'http://www.w3.org/TR/WCAG20/#robust'
               }
        }

        var msgCodeParts  = code.split('.', 5);
        var principle     = msgCodeParts[1];
        var techniques    = msgCodeParts[4].split(',');
        var techniquesStr = [];

        for (var i = 0; i < techniques.length; i++) {
            techniques[i]  = techniques[i].split('.');
            techniquesStr.push('' + techniques[i][0] + '');
        }

        var principleStr = ['', principles[principle].name, ''].join('');
        var retval = [
            ['Principle', principleStr],
            ['Techniques', techniquesStr.join(' ')]
        ];

        return retval;
    }
};
<commit_msg>日本語訳版へのリンク追加<commit_after>/**
 * +--------------------------------------------------------------------+
 * | This HTML_CodeSniffer file is Copyright (c)                        |
 * | Squiz Pty Ltd (ABN 77 084 670 600)                                 |
 * +--------------------------------------------------------------------+
 * | IMPORTANT: Your use of this Software is subject to the terms of    |
 * | the Licence provided in the file licence.txt. If you cannot find   |
 * | this file please contact Squiz (www.squiz.com.au) so we may        |
 * | provide you a copy.                                                |
 * +--------------------------------------------------------------------+
 *
 */

window.HTMLCS_WCAG2AAA = {
    name: 'WCAG2AAA',
    description: 'Web Content Accessibility Guidelines (WCAG) 2.0 AAA',
    sniffs: [
        'Principle1.Guideline1_1.1_1_1',
        'Principle1.Guideline1_2.1_2_1',
        'Principle1.Guideline1_2.1_2_2',
        'Principle1.Guideline1_2.1_2_4',
        'Principle1.Guideline1_2.1_2_5',
        'Principle1.Guideline1_2.1_2_6',
        'Principle1.Guideline1_2.1_2_7',
        'Principle1.Guideline1_2.1_2_8',
        'Principle1.Guideline1_2.1_2_9',
        'Principle1.Guideline1_3.1_3_1',
        'Principle1.Guideline1_3.1_3_1_AAA',
        'Principle1.Guideline1_3.1_3_2',
        'Principle1.Guideline1_3.1_3_3',
        'Principle1.Guideline1_4.1_4_1',
        'Principle1.Guideline1_4.1_4_2',
        'Principle1.Guideline1_4.1_4_3_F24',
        'Principle1.Guideline1_4.1_4_3_Contrast',
        'Principle1.Guideline1_4.1_4_6',
        'Principle1.Guideline1_4.1_4_7',
        'Principle1.Guideline1_4.1_4_8',
        'Principle1.Guideline1_4.1_4_9',
        'Principle2.Guideline2_1.2_1_1',
        'Principle2.Guideline2_1.2_1_2',
        'Principle2.Guideline2_2.2_2_2',
        'Principle2.Guideline2_2.2_2_3',
        'Principle2.Guideline2_2.2_2_4',
        'Principle2.Guideline2_2.2_2_5',
        'Principle2.Guideline2_3.2_3_2',
        'Principle2.Guideline2_4.2_4_1',
        'Principle2.Guideline2_4.2_4_2',
        'Principle2.Guideline2_4.2_4_3',
        'Principle2.Guideline2_4.2_4_5',
        'Principle2.Guideline2_4.2_4_6',
        'Principle2.Guideline2_4.2_4_7',
        'Principle2.Guideline2_4.2_4_8',
        'Principle2.Guideline2_4.2_4_9',
        'Principle3.Guideline3_1.3_1_1',
        'Principle3.Guideline3_1.3_1_2',
        'Principle3.Guideline3_1.3_1_3',
        'Principle3.Guideline3_1.3_1_4',
        'Principle3.Guideline3_1.3_1_5',
        'Principle3.Guideline3_1.3_1_6',
        'Principle3.Guideline3_2.3_2_1',
        'Principle3.Guideline3_2.3_2_2',
        'Principle3.Guideline3_2.3_2_3',
        'Principle3.Guideline3_2.3_2_4',
        'Principle3.Guideline3_2.3_2_5',
        'Principle3.Guideline3_3.3_3_1',
        'Principle3.Guideline3_3.3_3_2',
        'Principle3.Guideline3_3.3_3_3',
        'Principle3.Guideline3_3.3_3_5',
        'Principle3.Guideline3_3.3_3_6',
        'Principle4.Guideline4_1.4_1_1',
        'Principle4.Guideline4_1.4_1_2'
    ],
    getMsgInfo: function(code) {
        var principles = {
            'Principle1': {
                name: 'Perceivable',
                link: 'http://www.w3.org/TR/WCAG20/#perceivable'
               },
            'Principle2': {
                name: 'Operable',
                link: 'http://www.w3.org/TR/WCAG20/#operable'
               },
            'Principle3': {
                name: 'Understandable',
                link: 'http://www.w3.org/TR/WCAG20/#understandable'
               },
            'Principle4': {
                name: 'Robust',
                link: 'http://www.w3.org/TR/WCAG20/#robust'
               }
        }

        var msgCodeParts  = code.split('.', 5);
        var principle     = msgCodeParts[1];
        var techniques    = msgCodeParts[4].split(',');
        var techniquesStr = [];

        for (var i = 0; i < techniques.length; i++) {
            techniques[i]  = techniques[i].split('.');
            techniquesStr.push('' + techniques[i][0] + ' (日本語訳)');
        }

        var principleStr = ['', principles[principle].name, ''].join('');
        var retval = [
            ['Principle', principleStr],
            ['Techniques', techniquesStr.join(' ')]
        ];

        return retval;
    }
};
<|endoftext|>


<commit_before>API.Page = new Class({

    Implements: Options,

    options: {
        filename: '',
        path: ''
    },

    initialize: function(options) {
        this.setOptions(options);

        if (!this.options.path) this.options.path = this.options.filename;
    },

    getID: function() {
        return 'Page-' + this.options.filename.replace(/\//g, '-');
    }

});

FlightDeck = Class.refactor(FlightDeck, {

    options: {
        file_selected_class: 'UI_File_Selected',
        file_listing_class: 'tree',
        file_normal_class: 'UI_File_Normal'
    },

    initialize: function(options) {
        this.previous(options);

        var actions = { add: false, edit: false, remove: false },
			that = this;

        API.Tree = new FileTree('PackTree', {
            checkDrag: Function.from(false),
            editable: false,
            actions: actions
        });

		API.Tree.collapse = new FileTree.Collapse('PackTree', {});
		var top_branch = API.Tree.addBranch({
			'rel': 'directory',
			'title': 'Docs',
			'id': 'lib_branch',
			'class': 'top_branch nodrag'
		}, null, { actions: actions, collapsed: false });
		API.Tree.collapse.prepare();

        doc_list.forEach(function(page) {
            var p = API.pages[page.filename] = new API.Page(page);
            var el = API.Tree.addPath(p, Object.merge({
               target: top_branch
            }, actions));
            API.Tree.collapse.prepare();
            el.store('page', p);
            if (p.options.selected) {

			    this.setSelectedFile(el);
            }

        }, this);

        $('PackTree').addEvent('click:relay(li:not(top_branch) > .holder > .label)', function(e, label) {
            var page = label.getParent('li').retrieve('page');
            if(page) {
                that.setSelectedFile(label.getParent('li'));
				window.location.href = page.options.get_url;
            }
        });
    },

    setSelectedFile: function(el) {
        var options = this.options;

        $$('.'+options.file_listing_class+' li')
			.removeClass(options.file_selected_class)
			.addClass(options.file_normal_class);

		el.removeClass(options.file_normal_class)
			.addClass(options.file_selected_class);

		//also be sure to expand all parent folders
		var tree = API.Tree;
			node = el;

		if (node.getElement('li')) {
			tree.collapse.expand(node);
		}

		while (node = node.getParent('li')) {
			tree.collapse.expand(node);
		}
    }

});
<commit_msg>fixes Bug 656619 - Tree in docs page is broken, docs cannot be viewed<commit_after>API.Page = new Class({

    Implements: Options,

    options: {
        filename: '',
        path: ''
    },

    initialize: function(options) {
        this.setOptions(options);

        if (!this.options.path) this.options.path = this.options.filename;
    },

    getID: function() {
        return 'Page-' + this.options.filename.replace(/\//g, '-');
    },

	getShortName: function() {
		return this.getFullName().split('/').pop();
	},

	getFullName: function() {
		return this.options.filename;
	}

});

FlightDeck = Class.refactor(FlightDeck, {

    options: {
        file_selected_class: 'UI_File_Selected',
        file_listing_class: 'tree',
        file_normal_class: 'UI_File_Normal'
    },

    initialize: function(options) {
        this.previous(options);

        var actions = { add: false, edit: false, remove: false },
			that = this;

        API.Tree = new FileTree('PackTree', {
            checkDrag: Function.from(false),
            editable: false,
            actions: actions
        });

		API.Tree.collapse = new FileTree.Collapse('PackTree', {});
		var top_branch = API.Tree.addBranch({
			'rel': 'directory',
			'title': 'Docs',
			'id': 'lib_branch',
			'class': 'top_branch nodrag'
		}, null, { actions: actions, collapsed: false });
		API.Tree.collapse.prepare();

        doc_list.forEach(function(page) {
            var p = API.pages[page.filename] = new API.Page(page);
            var el = API.Tree.addPath(p, Object.merge({
               target: top_branch
            }, actions));
            API.Tree.collapse.prepare();
            el.store('page', p);
            if (p.options.selected) {

			    this.setSelectedFile(el);
            }

        }, this);

        $('PackTree').addEvent('click:relay(li:not(top_branch) > .holder > .label)', function(e, label) {
            var page = label.getParent('li').retrieve('page');
            if(page) {
                that.setSelectedFile(label.getParent('li'));
				window.location.href = page.options.get_url;
            }
        });
    },

    setSelectedFile: function(el) {
        var options = this.options;

        $$('.'+options.file_listing_class+' li')
			.removeClass(options.file_selected_class)
			.addClass(options.file_normal_class);

		el.removeClass(options.file_normal_class)
			.addClass(options.file_selected_class);

		//also be sure to expand all parent folders
		var tree = API.Tree;
			node = el;

		if (node.getElement('li')) {
			tree.collapse.expand(node);
		}

		while (node = node.getParent('li')) {
			tree.collapse.expand(node);
		}
    }

});
<|endoftext|>