text:
/**
 * @file Orchestrator class. Part of the "Age of Space" project.
 * @author github.com/azziliz
 * @author github.com/thyshimrod
 * {@link https://github.com/The-game-craftmen/age-of-space/ Project page}
 * @license MIT
 */

'use strict';
var aos = aos || {};
//debugger;

/**
 * The orchestrator is responsible for initial instanciations and time management.
 * It also maintains an instance reference.
 *
 * @class
 */
aos.Orchestrator = function () {
    this.galaxy = {};
    this.selectedStar = null;
    this.gameSpeedMultiplier = 0; // can be 0 (pause), 1, or 5. Set by the controls in the bottom right corner of the screen
    this.gameTime = 0; // elapsed milliseconds since the start of the game. Grows faster if the speed is 5x
    this.lastGameplayTick = 0; // dispatches an update event every x milliseconds in game time (x = 1000?)
    this.lastAnimationFrame = 0; // time interval counter

    this.mousePosition = { x: 0, y: 0 };
    this.isDragging = false;
    this.dragStart = null;
    this.dragEnd = null;

    this.pies = [];
    this.shipResourceBars = [];
    this.planetResourceBars = [];
    this.buildingButtons = [];

    this.transits = [];
};

aos.Orchestrator.prototype = {

    start: function () {
        this.buildPlanetUi();
        this.galaxy = new aos.Galaxy();
        this.galaxy.generate();
        document.getElementById('starSystemBlock').style.display = 'none';
        document.getElementById('shipBlock').style.display = 'none';
        document.getElementById('contextualBlock').style.display = 'none';
        document.getElementById('contextualTxt').innerHTML = '';

        this.setupEvents();
        this.animationTick(0);
        this.setGameSpeed(1);
    },

    //#region Planet UI
    buildPlanetUi: function () {
        this.renderPie(document.getElementById('airPie'), 'Air', 'air');
        this.renderPie(document.getElementById('liquidPie'), 'Ocean', 'liquid');
        this.renderPie(document.getElementById('groundPie'), 'Soil', 'ground');

        aos.resources.forEach(function (resource, i) {
            this.renderBar(document.getElementById('res' + i + 'Storage'), resource, i, true);
            this.renderBar(document.getElementById('res' + i + 'Ship'), resource, i, false);
        }, this);

        Object.keys(aos.buildingTemplates).forEach(function (key, i) {
            this.renderBuildingButton(document.getElementById('building' + i + 'Build'), key);
            const fullSvgCode = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">'
                + '<path fill="{color}" d="'.replace('{color}', 'hsl(0, 0%, 80%)')
                + aos.buildingTemplates[key].svgCode
                + '"></path>'
                + '</svg>';
            const image = document.getElementById("resourceImg" + i);
            image.src = 'data:image/svg+xml,' + encodeURIComponent(fullSvgCode);
            const fullSvgCodeDisabled = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">'
                + '<path fill="{color}" d="'.replace('{color}', 'hsl(0, 80%, 50%)')
                + aos.buildingTemplates[key].svgCode
                + '"></path>'
                + '</svg>';
            const imageDisabled = document.getElementById("resourceDisabled" + i);
            imageDisabled.src = 'data:image/svg+xml,' + encodeURIComponent(fullSvgCodeDisabled);
        }, this);

    },

    renderPie: function (elem, txt, category) {
        const chart = new aos.PieChart();
        chart.htmlElement = elem;
        chart.innerText = txt;
        chart.content = [];
        aos.resources.forEach(function (resource, i) {
            if (resource.category === category) {
                chart.content.push({ label: resource.name, value: i + 1, color: resource.color });
            }
        }, this);
        chart.render();
        this.pies.push(chart);
        elem.addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = '' + txt + ' composition' + '
 ';
            chart.setWantContextual(true);
        }.bind(this), false);
        elem.addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            chart.setWantContextual(false);
        }.bind(this), false);
    },

    renderBar: function (elem, res, idx, isStorage) {
        const bar = new aos.Resource();
        bar.htmlElement = elem;
        bar.name = res.name;
        bar.svgCode = res.svgCode;
        bar.color = res.color;
        bar.type = res.category;
        bar.contextualTip = res.contextualTip;
        bar.index = idx;
        bar.render(isStorage);
        if (isStorage) {
            this.planetResourceBars.push(bar);
            elem.firstChild.childNodes[0].addEventListener('click', function (e) {
                e.preventDefault();
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null && this.selectedStar.hasShip) {
                    if (this.selectedStar.selectedPlanet.storedResources[bar.index].quantity > 0) {
                        const transferAmount = Math.min(10000, this.selectedStar.selectedPlanet.storedResources[bar.index].quantity, this.selectedStar.ship.availableSpace());
                        this.selectedStar.selectedPlanet.storedResources[bar.index].quantity -= transferAmount;
                        this.selectedStar.ship.storedResources[bar.index].quantity += transferAmount;
                        this.emitEvent('requestUiSlowRefresh', {});
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[0].addEventListener('mouseover', function (e) {
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null && this.selectedStar.hasShip) {
                    if (this.selectedStar.selectedPlanet.storedResources[bar.index].quantity > 0) {
                        bar.setTooltipFlag(true, false, false);
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[0].addEventListener('mouseout', function (e) {
                bar.setTooltipFlag(false, false, false);
            }.bind(this), false);

            elem.firstChild.childNodes[3].addEventListener('click', function (e) {
                e.preventDefault();
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null && this.selectedStar.hasShip) {
                    if (this.selectedStar.ship.storedResources[bar.index].quantity > 0) {
                        const transferAmount = Math.min(10000, this.selectedStar.ship.storedResources[bar.index].quantity);
                        this.selectedStar.selectedPlanet.storedResources[bar.index].quantity += transferAmount;
                        this.selectedStar.ship.storedResources[bar.index].quantity -= transferAmount;
                        this.emitEvent('requestUiSlowRefresh', {});
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[3].addEventListener('mouseover', function (e) {
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null && this.selectedStar.hasShip) {
                    if (this.selectedStar.ship.storedResources[bar.index].quantity > 0) {
                        bar.setTooltipFlag(false, true, false);
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[3].addEventListener('mouseout', function (e) {
                bar.setTooltipFlag(false, false, false);
            }.bind(this), false);

            elem.firstChild.childNodes[7].addEventListener('click', function (e) {
                e.preventDefault();
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null) {
                    if (this.selectedStar.selectedPlanet.storedResources[bar.index].quantity > 0) {
                        const transferAmount = Math.min(10000, this.selectedStar.selectedPlanet.storedResources[bar.index].quantity);
                        this.selectedStar.selectedPlanet.storedResources[bar.index].quantity -= transferAmount;
                        this.selectedStar.selectedPlanet.resources[bar.index].quantity += transferAmount;
                        this.emitEvent('requestUiSlowRefresh', {});
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[7].addEventListener('mouseover', function (e) {
                if (this.selectedStar !== null && this.selectedStar.selectedPlanet !== null) {
                    if (this.selectedStar.selectedPlanet.storedResources[bar.index].quantity > 0) {
                        bar.setTooltipFlag(false, false, true);
                    }
                }
            }.bind(this), false);
            elem.firstChild.childNodes[7].addEventListener('mouseout', function (e) {
                bar.setTooltipFlag(false, false, false);
            }.bind(this), false);
        } else {
            this.shipResourceBars.push(bar);
        }
        elem.addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            bar.setWantContextual(true);
        }.bind(this), false);
        elem.addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            bar.setWantContextual(false);
        }.bind(this), false);
    },

    renderBuildingButton: function (elem, templateName) {
        const button = new aos.BuildingButton();
        button.buildingTemplate = templateName;
        button.htmlElement = elem;
        button.render();
        this.buildingButtons.push(button);
        elem.addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            button.setWantContextual(true);
        }.bind(this), false);
        elem.addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            button.setWantContextual(false);
        }.bind(this), false);
        elem.addEventListener('click', function (e) {
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.onBuildingButtonClicked(button.buildingTemplate);
            }
        }.bind(this), false);
    },
    //#endregion

    setGameSpeed: function (newSpeed) { // expects newSpeed = 0, 1 or 2
        this.gameSpeedMultiplier = newSpeed === 2 ? 5 : newSpeed;
        document.getElementById('speed0').style.border = '';
        document.getElementById('speed1').style.border = '';
        document.getElementById('speed2').style.border = '';
        document.getElementById('speed' + newSpeed).style.border = '4px solid #f00';
    },

    setSelectedStar: function (star) {
        this.selectedStar = star;
        if (star === null) {
            document.getElementById('galaxyBlock').style.display = 'block';
            document.getElementById('starSystemBlock').style.display = 'none';
            document.getElementById('shipBlock').style.display = 'none';
            document.getElementById('contextualBlock').style.display = 'none';
        } else {
            document.getElementById('galaxyBlock').style.display = 'none';
            document.getElementById('starSystemBlock').style.display = 'block';
            document.getElementById('shipBlock').style.display = 'none';
            document.getElementById('contextualBlock').style.display = 'none';
            star.buildUi();
        }
    },

    refreshGalaxyOverlay: function () {
        const galaxyCoordX = this.mousePosition.x;
        const galaxyCoordY = this.mousePosition.y;

        document.getElementById('galaxyOverlayCanvas').style.cursor = 'default';
        document.getElementById('contextualBlock').style.display = 'none';

        const canvas = document.getElementById('galaxyOverlayCanvas');
        const ctx = canvas.getContext('2d');
        ctx.clearRect(0, 0, 1200, 900);
        const constellationId = this.galaxy.getConstellationId(galaxyCoordX, galaxyCoordY);
        this.galaxy.constellations.forEach(function (c, i) {
            c.render(i === constellationId);
        });
        this.dragEnd = null;

        // Transit render
        this.transits.forEach(function (transit) {
            const lerpRatio = (this.gameTime - transit.startTick) / (transit.endTick - transit.startTick);
            const shipX = transit.from.x + lerpRatio * (transit.to.x - transit.from.x);
            const shipY = transit.from.y + lerpRatio * (transit.to.y - transit.from.y);

            ctx.beginPath();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#360';
            ctx.arc(600 + shipX, 450 + shipY, 5, 0, 2 * Math.PI);
            ctx.stroke();

            ctx.setLineDash([2, 5]);
            ctx.moveTo(600 + transit.from.x, 450 + transit.from.y);
            ctx.lineTo(600 + transit.to.x, 450 + transit.to.y);
            ctx.stroke();
            ctx.setLineDash([]);
        }, this);

        // End of transit operations (adding ship to target star)
        const endOfTransit = this.transits.filter(function (transit) {
            return transit.endTick <= this.gameTime;
        }, this);
        endOfTransit.forEach(function (transit) {
            transit.to.hasShip = true;
            transit.to.ship = transit;
            transit.from = null;
            transit.to = null;
        }, this);
        this.transits = this.transits.filter(function (transit) {
            return transit.endTick > this.gameTime;
        }, this);

        if (this.isDragging) {
            this.galaxy.stars.forEach(function (star) {
                if (this.dragStart === star) {
                    const deltaX = star.x - galaxyCoordX;
                    const deltaY = star.y - galaxyCoordY;
                    const dist = deltaX * deltaX + deltaY * deltaY;
                    const radius = star.isNotable ? 225.0 : 100.0; // 15² , 10²
                    if (dist > radius) {
                        ctx.beginPath();
                        ctx.lineWidth = 2;
                        ctx.moveTo(600 + star.x, 450 + star.y);
                        let lineDrawn = false;
                        this.galaxy.stars.forEach(function (target) {
                            const deltaX1 = target.x - galaxyCoordX;
                            const deltaY1 = target.y - galaxyCoordY;
                            const dist1 = deltaX1 * deltaX1 + deltaY1 * deltaY1;
                            const radius1 = target.isNotable ? 225.0 : 100.0; // 15² , 10²
                            if (dist1 < radius1) {
                                ctx.strokeStyle = '#066';
                                ctx.lineTo(600 + target.x, 450 + target.y);
                                lineDrawn = true;
                                this.dragEnd = target;
                            }
                        }, this);
                        if (!lineDrawn) {
                            ctx.strokeStyle = '#600';
                            ctx.lineTo(600 + galaxyCoordX, 450 + galaxyCoordY);
                        }
                        ctx.stroke();
                    }
                }
            }, this);
        }
        if (constellationId === 0) {
            //ctx.beginPath();
            //ctx.strokeStyle = '#600';
            //ctx.lineWidth = 2;
            //ctx.arc(600, 450, 100, 0, 2 * Math.PI);
            //ctx.stroke();
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = 'Galactic Core' +
                '
 ';
            document.getElementById('contextualTxt').innerHTML = '';
            document.getElementById('contextualTxt').innerHTML +=
                '
DANGER

Black hole

Don\'t come close !
';
        }
        else {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = '' + this.galaxy.constellations[constellationId].reference.name +
                '
Constellation';
            document.getElementById('contextualTxt').innerHTML = '';
            {
                let radical = this.galaxy.constellations[constellationId].loreStarCount;
                let power = 8;
                while (radical > 10.0) {
                    radical /= 10.0;
                    power++;
                }
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Stars (total)' + '

' + radical.toFixed(1) + ' × 10' + power + '

';
            }
            const constellationStars = this.galaxy.constellations[constellationId].stars;
            document.getElementById('contextualTxt').innerHTML +=
                '

' + 'Notable stars' + '

' + constellationStars.length + '

';
            document.getElementById('contextualTxt').innerHTML +=
                '

' + 'Stars with at least' + '

' + '

';
            document.getElementById('contextualTxt').innerHTML +=
                '

' + 'one planet in the' + '

' + constellationStars.filter(function (star) {
                    return star.isNotable;
                }).length + '

';
            document.getElementById('contextualTxt').innerHTML +=
                '

' + 'habitable zone' + '

' + '

';
        }

        //document.getElementById('debug').innerHTML = '' + constellationId + '/' + '
';

        this.galaxy.constellations[constellationId].stars.forEach(function (star) {
            const deltaX = star.x - galaxyCoordX;
            const deltaY = star.y - galaxyCoordY;
            const dist = deltaX * deltaX + deltaY * deltaY;
            const radius = star.isNotable ? 225.0 : 100.0; // 15² , 10²
            const label = star.isNotable ? 'Star' : 'Star';
            if (dist < radius) { // sqrt(dist) < 20.0
                document.getElementById('galaxyOverlayCanvas').style.cursor = 'pointer';
                document.getElementById('contextualBlock').style.display = 'block';
                document.getElementById('contextualTitle').innerHTML = '' +
                    star.greekLetter.name.charAt(0).toUpperCase() + star.greekLetter.name.slice(1) + ' ' +
                    this.galaxy.constellations[constellationId].reference.gen +
                '
' + label + '';
                document.getElementById('contextualTxt').innerHTML = '';
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Proper name' + '

' + star.properName.name + '

';
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Type' + '

' +
                    (star.spectralClass === 'M' ? 'Red dwarf' :
                    star.spectralClass === 'K' ? 'Orange dwarf' :
                    star.spectralClass === 'G' ? 'Yellow dwarf' :
                    star.spectralClass === 'F' ? 'Yellow-white dwarf' :
                    star.spectralClass === 'A' ? 'White main sequence' :
                    star.spectralClass === 'B' ? 'Blue subgiant' : 'Blue giant') + '

';
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Spectral class' + '

' + star.spectralClass + star.subSpectral + '

';
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Luminosity class' + '

' + star.luminosityClass + '

';
                document.getElementById('contextualTxt').innerHTML +=
                    '

' + 'Surface temperature' + '

' + 100 * Math.floor(star.temperature / 100) + ' K

';
                {
                    let radical = star.mass;
                    let power = 29;
                    while (radical > 10.0) {
                        radical /= 10.0;
                        power++;
                    }
                    document.getElementById('contextualTxt').innerHTML +=
                        '

' + 'Mass' + '

' + radical.toFixed(1) + ' × 10' + power + ' kg

';
                }
                {
                    let radical = star.radius;
                    let power = 8;
                    while (radical > 10.0) {
                        radical /= 10.0;
                        power++;
                    }
                    document.getElementById('contextualTxt').innerHTML +=
                        '

' + 'Radius' + '

' + radical.toFixed(1) + ' × 10' + power + ' m

';
                }
                {
                    let radical = star.bolometricLuminosity;
                    let power = 22;
                    while (radical > 10.0) {
                        radical /= 10.0;
                        power++;
                    }
                    document.getElementById('contextualTxt').innerHTML +=
                        '

' + 'Bolometric luminosity' + '

' + radical.toFixed(1) + ' × 10' + power + ' W

';
                }
                {
                    const mbol = -2.5 * Math.log(star.bolometricLuminosity / 4000.0) * Math.LOG10E + 5;
                    document.getElementById('contextualTxt').innerHTML +=
                        '

' + 'Absolute magnitude' + '

' + mbol.toFixed(1) + '

';
                }
            }
            //document.getElementById('debug').innerHTML += dist + '
';
        }, this);
    },

    setupEvents: function () {
        document.getElementById('galaxyOverlayCanvas').addEventListener('mousemove', function (e) {
            e.preventDefault(); // usually, keeping the left mouse button down triggers a text selection or a drag & drop.
            const galaxyCoordX = e.offsetX * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 600;
            const galaxyCoordY = e.offsetY * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 450;
            //document.getElementById('debug').innerHTML = '' + galaxyCoordX + '/' + galaxyCoordY + '/' + '
';
            this.mousePosition.x = galaxyCoordX;
            this.mousePosition.y = galaxyCoordY;

        }.bind(this), false);

        document.getElementById('galaxyOverlayCanvas').addEventListener('mousedown', function (e) {
            e.preventDefault(); // usually, keeping the left mouse button down triggers a text selection or a drag & drop.
            const galaxyCoordX = e.offsetX * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 600;
            const galaxyCoordY = e.offsetY * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 450;

            this.setSelectedStar(null);
            this.galaxy.stars.forEach(function (star) {
                const deltaX = star.x - galaxyCoordX;
                const deltaY = star.y - galaxyCoordY;
                const dist = deltaX * deltaX + deltaY * deltaY;
                const radius = star.isNotable ? 225.0 : 100.0; // 15² , 10²
                if (dist < radius) {
                    this.dragStart = star;
                    if (star.hasShip) {
                        this.isDragging = true;
                    }
                }
            }, this);
        }.bind(this), false);

        document.getElementById('galaxyOverlayCanvas').addEventListener('mouseup', function (e) {
            e.preventDefault(); // usually, keeping the left mouse button down triggers a text selection or a drag & drop.
            const galaxyCoordX = e.offsetX * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 600;
            const galaxyCoordY = e.offsetY * 1200 / document.getElementById('galaxyOverlayCanvas').offsetWidth - 450;

            this.setSelectedStar(null);
            this.galaxy.stars.forEach(function (star) {
                const deltaX = star.x - galaxyCoordX;
                const deltaY = star.y - galaxyCoordY;
                const dist = deltaX * deltaX + deltaY * deltaY;
                const radius = star.isNotable ? 225.0 : 100.0; // 15² , 10²
                if (dist < radius && this.dragStart === star) {
                    this.setSelectedStar(star);
                    this.isDragging = false;
                } else if (this.isDragging && this.dragEnd !== null && this.dragStart.hasShip) {
                    //document.getElementById('galaxyBlock').style.display = 'none';
                    //document.getElementById('shipBlock').style.display = 'block';
                    const shipInTransit = this.dragStart.ship;
                    shipInTransit.from = this.dragStart;
                    shipInTransit.to = this.dragEnd;
                    shipInTransit.startTick = this.gameTime;
                    const transitDistanceX = shipInTransit.from.x - shipInTransit.to.x;
                    const transitDistanceY = shipInTransit.from.y - shipInTransit.to.y;
                    const transitDistance = Math.sqrt(transitDistanceX * transitDistanceX + transitDistanceY * transitDistanceY);
                    shipInTransit.endTick = this.gameTime + transitDistance * 20;
                    this.transits.push(shipInTransit);
                    this.dragStart.hasShip = false;
                    this.dragStart.ship = null;
                }
            }, this);
            this.isDragging = false;
        }.bind(this), false);

        document.getElementById('galaxyOverlayCanvas').addEventListener('mouseleave', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            document.getElementById('contextualTxt').innerHTML = '';
            this.isDragging = false;
        }.bind(this), false);

        document.getElementById('closeStarSystem').addEventListener('click', function (e) {
            e.preventDefault();
            this.setSelectedStar(null);
        }.bind(this), false);
        document.getElementById('closeShip').addEventListener('click', function (e) {
            e.preventDefault();
            this.setSelectedStar(null);
        }.bind(this), false);
        document.getElementById('speed0').addEventListener('click', function (e) {
            e.preventDefault();
            this.setGameSpeed(0);
        }.bind(this), false);
        document.getElementById('speed1').addEventListener('click', function (e) {
            e.preventDefault();
            this.setGameSpeed(1);
        }.bind(this), false);
        document.getElementById('speed2').addEventListener('click', function (e) {
            e.preventDefault();
            this.setGameSpeed(2);
        }.bind(this), false);

        //#region Speed buttons help
        document.getElementById('speed0').addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = 'Speed control' + '
Pause';
            document.getElementById('contextualTxt').innerHTML = '
Pauses the game
';
        }.bind(this), false);
        document.getElementById('speed0').addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            document.getElementById('contextualTxt').innerHTML = '';
        }.bind(this), false);
        document.getElementById('speed1').addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = 'Speed control' + '
Normal speed';
            document.getElementById('contextualTxt').innerHTML = '
Runs the game at normal speed

1 second in real life = 1 tick in game
';
        }.bind(this), false);
        document.getElementById('speed1').addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            document.getElementById('contextualTxt').innerHTML = '';
        }.bind(this), false);
        document.getElementById('speed2').addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = 'Speed control' + '
Fast speed';
            document.getElementById('contextualTxt').innerHTML = '
Runs the game at fast speed
(5 times the normal speed)

1 second in real life = 5 ticks in game
';
        }.bind(this), false);
        document.getElementById('speed2').addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
            document.getElementById('contextualTxt').innerHTML = '';
        }.bind(this), false);
        //#endregion

        document.getElementById('miniatureTabs').addEventListener('click', function (e) {
            e.preventDefault(); // usually, keeping the left mouse button down triggers a text selection or a drag & drop.
            let clickedElem = e.target;
            while (clickedElem.tagName.toUpperCase() !== 'LI' && clickedElem.tagName.toUpperCase() !== 'BODY') {
                clickedElem = clickedElem.parentElement;
            }
            if (clickedElem.tagName.toUpperCase() === 'LI') {
                this.selectedStar.setSelectedPlanetIndex(+clickedElem.dataset.index);
            }
        }.bind(this), false);

        document.getElementById('planetModelCanvas').addEventListener('mouseover', function (e) {
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.renderModel.rotates = false;
                document.getElementById('contextualBlock').style.display = 'block';
                this.selectedStar.selectedPlanet.setWantPolyhedronContextual(true);
            }
        }.bind(this), false);
        document.getElementById('planetModelCanvas').addEventListener('mouseout', function (e) {
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.renderModel.rotates = true;
                document.getElementById('contextualBlock').style.display = 'none';
                this.selectedStar.selectedPlanet.setWantPolyhedronContextual(false);
            }
        }.bind(this), false);
        document.getElementById('planetModelCanvas').addEventListener('mousemove', function (e) {
            e.preventDefault();
            const x = e.offsetX * 500 / document.getElementById('planetModelCanvas').offsetWidth;
            const y = e.offsetY * 500 / document.getElementById('planetModelCanvas').offsetWidth;
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.renderModel.mousePosition = [x, y];
            }
        }.bind(this), false);
        document.getElementById('planetModelCanvas').addEventListener('click', function (e) {
            e.preventDefault();
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.renderModel.wantSelectedTile = true;
            }
        }.bind(this), false);

        document.getElementById('removeBuilding').addEventListener('mouseover', function (e) {
            document.getElementById('contextualBlock').style.display = 'block';
            document.getElementById('contextualTitle').innerHTML = 'Destroy building' + '
' + ' ' + '';
            document.getElementById('contextualTxt').innerHTML = '';
        }.bind(this), false);
        document.getElementById('removeBuilding').addEventListener('mouseout', function (e) {
            document.getElementById('contextualBlock').style.display = 'none';
        }.bind(this), false);
        document.getElementById('removeBuilding').addEventListener('click', function (e) {
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.onRemoveButtonClicked();
            }
        }.bind(this), false);

        window.setInterval(function () {
            this.emitEvent('requestUiFastRefresh', {});
        }.bind(this), 130);
        window.setInterval(function () {
            this.emitEvent('requestUiSlowRefresh', {});
        }.bind(this), 1100);

        window.addEventListener('requestUiFastRefresh', function (e) {
            document.getElementById('gameTime').textContent = (this.gameTime / 1000.0).toFixed(1);
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.showStatsFast();
            }
        }.bind(this), false);
        window.addEventListener('requestUiSlowRefresh', function (e) {
            if (this.selectedStar !== null) {
                this.selectedStar.selectedPlanet.showStats();
                this.selectedStar.showShip();
            }
        }.bind(this), false);
        window.addEventListener('animationTick', function (e) {
            if (this.selectedStar !== null) {
                const wantRefresh = this.selectedStar.selectedPlanet.renderModel.wantSelectedTile;
                this.selectedStar.animateLargeStar();
                this.selectedStar.selectedPlanet.animateModel();
                //this.selectedStar.animateShip();
                if (wantRefresh) {
                    this.emitEvent('requestUiSlowRefresh', {});
                }
            } else {
                this.refreshGalaxyOverlay();
            }
        }.bind(this), false);

    },

    emitEvent: function (type, payload) {
        const event = document.createEvent('CustomEvent');
        event.initCustomEvent(type, false, false, payload);
        window.dispatchEvent(event);
    },

    animationTick: function (timestamp) {
        this.emitEvent('animationTick', { ts: timestamp, speed: this.gameSpeedMultiplier });
        this.gameTime += (timestamp - this.lastAnimationFrame) * this.gameSpeedMultiplier;
        this.lastAnimationFrame = timestamp;
        if (this.gameTime / 1000.0 > this.lastGameplayTick) {
            this.lastGameplayTick += 1;
            this.emitEvent('gameplayTick', { tick: this.lastGameplayTick });
        }
        window.requestAnimationFrame(this.animationTick.bind(this));
    },

};

aos.game = new aos.Orchestrator();
window.onload = function () {
    aos.game.start();
};


text:
An iOS 8 notification center widget for shortening URLs from the clipboard.

## Requirements
- XCode 6 or newer with Swift
- Bitly Access Token (retrievable [here](https://bitly.com/a/oauth_apps))

## Setup
1. Clone
2. Replace _your-access-token_ with your API token
3. Build and run

## That's all?
Yea, why? I think the bitly website sucks and I don't like the app, so why fucking not?
Oh there's a python version, too for those that stick to the command line (like me on my Mac ;))

redpajama_set_name: RedPajamaGithub


text:
All configurations must define a **routers** key, the value of which
must be an array of router configurations. Routers also include **servers**,
which define their entry points, **client**, which configures how clients are
built, and **service**, which configures service level policy.

## Router Parameters

<aside class="notice">
These parameters are available to the router regardless of protocol. Routers may also have protocol-specific parameters.
</aside>

```yaml
routers:
- protocol: http
  servers: ...
  service: ...
  client: ...
  announcers: ...
  bindingCache: ...
  label: myPackIce
  dstPrefix: /walruses/http
  dtab: |
    /host                => /#/io.l5d.fs;
    /walruses/http => /host;
  originator: true
  bindingTimeoutMs: 5000
```

Key | Default Value | Description
--- | ------------- | -----------
protocol | _required_ | Either [`http`](#http-1-1-protocol), [`h2`](#http-2-protocol), [`thrift`](#thrift-protocol), or [`mux`](#mux-protocol-experimental).
servers | _required_ | A list of [server objects](#servers).
announcers | an empty list | A list of service discovery [announcers](#announcers) that servers can announce to.
dtab | an empty dtab | Sets the base delegation table. See [dtabs](https://linkerd.io/doc/dtabs/) for more.
bindingTimeoutMs | 10 seconds | The maximum amount of time in milliseconds to spend binding a path.
bindingCache | see [binding cache](#binding-cache) | Binding cache size configuration.
client | an empty object | A [client configuration](#client-configuration) object.
dstPrefix | protocol dependent | A path prefix to be used on request destinations.
originator | `false` | If `true`, indicates that this router is the first hop for linker-to-linker requests, and reflects that in the router's stats. Useful for deduping linker-to-linker stats.
interpreter | default interpreter | An [interpreter object](#interpreter) determining what module will be used to process destinations.
label | the value of *protocol* | The name of the router (in stats and the admin ui)

### Binding Cache

```yaml
- protocol: http
  servers:
  - port: 9000
  bindingCache:
    paths: 100
    trees: 100
    bounds: 100
    clients: 10
    idleTtlSecs: 3600
```

Key | Default Value | Description
-------------- | -------------- | --------------
paths | `1000` | Max number of paths in the path cache.
trees | `1000` | Max number of trees in the tree cache.
bounds | `1000` | Max number of bounds in the bounds cache.
clients | `1000` | Max number of clients in the clients cache.
idleTtlSecs | 10 minutes | The amount of time, in seconds, to cache idle services and clients before expiring them.

## Server Parameters

<aside class="notice">
These parameters are available to the server regardless of protocol. Servers may also have protocol-specific parameters.
</aside>

```yaml
servers:
- port: 8080
  ip: 0.0.0.0
  tls:
    certPath: /foo/cert.pem
    keyPath: /foo/key.pem
  maxConcurrentRequests: 1000
  announce:
    - /#/io.l5d.serversets/discovery/prod/web
```

Key | Default Value | Description
--- | ------------- | -----------
port | protocol dependent | The TCP port number. Protocols may provide default values. If no default is provided, the port parameter is required.
ip | loopback address | The local IP address. A value like 0.0.0.0 configures the server to listen on all local IPv4 interfaces.
tls | no tls | The server will serve over TLS if this parameter is provided. see [TLS](#server-tls).
maxConcurrentRequests | unlimited | The maximum number of concurrent requests the server will accept.
announce | an empty list | A list of concrete names to announce using the router's [announcers](#announcers).
clearContext | `false` | If `true`, all headers that set linkerd contexts are removed from inbound requests. Useful for servers exposed on untrusted networks.

## Service Configuration

This section defines the policy that linkerd will use when talking to services.
The structure of this section depends on its `kind`.

Key  | Default Value    | Description
---- | ---------------- | --------------
kind | `io.l5d.global` | Either [io.l5d.global](#global-service-config) or [io.l5d.static](#static-service-config)

### Global Service Config

```yaml
- protocol: http
  service:
    kind: io.l5d.global
    totalTimeoutMs: 500
    retries:
      budget:
        minRetriesPerSec: 5
        percentCanRetry: 0.5
        ttlSecs: 15
      backoff:
        kind: jittered
        minMs: 10
        maxMs: 10000
```

This service configuration allows you to specify [service parameters](#service-parameters)
which will be applied to all services.

### Static Service Config

```yaml
- protocol: http
  service:
    kind: io.l5d.static
    configs:
    - prefix: /svc
      retries:
        budget:
          minRetriesPerSec: 5
          percentCanRetry: 0.5
          ttlSecs: 15
        backoff:
          kind: jittered
          minMs: 10
          maxMs: 10000
    - prefix: /svc/foo
      totalTimeoutMs: 500
    - prefix: /svc/bar
      totalTimeoutMs: 200

```

This service configuration allows you to specify [service parameters](#service-parameters)
which will be applied to all services that match a specified prefix.  The service
configuration must contain a property called `configs` which contains a list
of config objects.  Each config object must specify a prefix and the
[service parameters](#service-parameters) to apply to services that match that prefix.
If a service matches more than one prefix, all parameters from the matching
configs will be applied, with parameters defined later in the configuration file
taking precedence over those defined earlier.

### Service Parameters

<aside class="notice">
These parameters are available to the service regardless of protocol. Services may also have protocol-specific parameters.
</aside>

Key                 | Default Value                 | Description
------------------- | ----------------------------- | -----------
retries             | see [retries](#retries)       | A [retry policy](#retries) for application-level retries.
totalTimeoutMs      | no timeout                    | The timeout for an entire request, including all retries, in milliseconds.
responseClassifier  | `io.l5d.http.nonRetryable5XX` | A (sometimes protocol-specific) [response classifier](#http-response-classifiers) that determines which responses should be considered failures and, of those, which should be considered [retryable](#retries).

## Client Configuration

This section defines how the clients that linkerd creates will be configured.  The structure of this section depends on
its `kind`.

Key  | Default Value    | Description
---- | ---------------- | --------------
kind | `io.l5d.global` | Either [io.l5d.global](#global-client-config) or [io.l5d.static](#static-client-config)

### Global Client Config

```yaml
- protocol: http
  client:
    kind: io.l5d.global
    loadBalancer:
      kind: ewma
    failureAccrual:
      kind: io.l5d.consecutiveFailures
      failures: 10
```

This client configuration allows you to specify [client parameters](#client-parameters)
which will be applied to all clients.

### Static Client Config

```yaml
- protocol: http
  client:
    kind: io.l5d.static
    configs:
    - prefix: /#/io.l5d.fs
      loadBalancer:
        kind: ewma
    - prefix: /#/io.l5d.fs/{service}
      tls:
        commonName: "{service}.linkerd.io"
    - prefix: /$/inet/*/80
      failureAccrual:
        kind: io.l5d.consecutiveFailures
        failures: 10
```

This client configuration allows you to specify [client parameters](#client-parameters)
which will be applied to all clients that match a specified prefix.  The client
configuration must contain a property called `configs` which contains a list
of config objects.  Each config object must specify a prefix and the
[client parameters](#client-parameters) to apply to clients that match that prefix.
A prefix may contain wildcards (`*`) and capture variables (`{foo}`) which can
be referenced in some client parameters.
If a client matches more than one config's prefix, all parameters from the
matching configs will be applied, with parameters defined later in the
configuration file taking precedence over those defined earlier.

### Client Parameters

<aside class="notice">
These parameters are available to the client regardless of protocol. Clients may also have protocol-specific parameters.
</aside>

```yaml
client:
  tls:
    kind: io.l5d.noValidation
    commonName: foo
    caCertPath: /foo/caCert.pem
  requestAttemptTimeoutMs: 100
  loadBalancer:
    kind: ewma
    enableProbation: false
  requeueBudget:
    percentCanRetry: 0.25
  failureAccrual:
    kind: io.l5d.consecutiveFailures
    failures: 10
```

Key | Default Value | Description
--- | ------------- | -----------
hostConnectionPool | An empty object | see [hostConnectionPool](#host-connection-pool).
tls | no tls | The router will make requests using TLS if this parameter is provided.  It must be a [client TLS](#client-tls) object.
loadBalancer | [p2c](#power-of-two-choices-least-loaded) | A [load balancer](#load-balancer) object.
failFast | `false` | If `true`, connection failures are punished more aggressively. Should not be used with small destination pools.
requeueBudget | see [retry budget](#retry-budget-parameters) | A [requeue budget](#retry-budget-parameters) for connection-level retries.
failureAccrual | 5 consecutive failures | a [failure accrual policy](#failure-accrual) for all clients created by this router.
requestAttemptTimeoutMs | no timeout | The timeout, in milliseconds, for each attempt (original or retry) of the request made by this client.

#### Host Connection Pool

```yaml
client:
  hostConnectionPool:
    minSize: 0
    maxSize: 1000
    idleTimeMs: 10000
    maxWaiters: 5000
```

Key | Default Value | Description
--- | ------------- | -----------
minSize | `0` | The minimum number of connections to maintain to each host.
maxSize | Int.MaxValue | The maximum number of connections to maintain to each host.
idleTimeMs | forever | The amount of idle time for which a connection is cached in milliseconds.
maxWaiters | Int.MaxValue | The maximum number of connection requests that are queued when the connection concurrency exceeds maxSize.


text:
<?php

namespace Buki\Router;

class RouterCommand
{
    /**
     * @var RouterCommand|null Class instance variable
     */
    protected static $instance = null;

    /**
     * Get class instance
     *
     * @return RouterCommand
     */
    public static function getInstance()
    {
        if (null === self::$instance) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    /**
     * Throw new Exception for Router Error
     *
     * @param $message
     *
     * @return RouterException
     * @throws
     */
    public function exception($message = '')
    {
        return new RouterException($message);
    }

    /**
     * Run Route Middlewares
     *
     * @param $command
     * @param $path
     * @param $namespace
     *
     * @return mixed|void
     * @throws
     */
    public function beforeAfter($command, $path = '', $namespace = '')
    {
        if (! is_null($command)) {
            if (is_array($command)) {
                foreach ($command as $key => $value) {
                    $this->beforeAfter($value, $path, $namespace);
                }
            } elseif (is_string($command)) {
                $controller = $this->resolveClass($command, $path, $namespace);
                if (method_exists($controller, 'handle')) {
                    return call_user_func([$controller, 'handle']);
                }

                return $this->exception('handle() method is not found in <b>'.$command.'</b> class.');
            }
        }

        return;
    }

    /**
     * Run Route Command; Controller or Closure
     *
     * @param $command
     * @param $params
     * @param $path
     * @param $namespace
     *
     * @return void
     * @throws
     */
    public function runRoute($command, $params = null, $path = '', $namespace = '')
    {
        if (! is_object($command)) {
			$segments = explode('@', $command);
			$controllerClass = str_replace([$namespace, '\\', '.'], ['', '/', '/'], $segments[0]);
			$controllerMethod = $segments[1];

            $controller = $this->resolveClass($controllerClass, $path, $namespace);
            if (method_exists($controller, $controllerMethod)) {
                echo call_user_func_array(
                    [$controller, $controllerMethod],
                    (!is_null($params) ? $params : [])
                );
                return;
            }

            return $this->exception($controllerMethod . ' method is not found in '.$controllerClass.' class.');
        } else {
            if (! is_null($params)) {
                echo call_user_func_array($command, $params);
                return;
            }

            echo call_user_func($command);
        }
    }

    /**
     * Resolve Controller or Middleware class.
     *
     * @param $class
     * @param $path
     * @param $namespace
     *
     * @return object
     * @throws
     */
    protected function resolveClass($class, $path, $namespace)
    {
        $file = realpath(rtrim($path, '/') . '/' . $class . '.php');
        if (! file_exists($file)) {
            return $this->exception($class . ' class is not found. Please, check file.');
        }

        require_once($file);
        $class = $namespace . str_replace('/', '\\', $class);

        return new $class();
    }
}


text:
package org.psidnell.omnifocus.visitor;

import java.util.HashSet;
import java.util.Set;

import org.psidnell.omnifocus.model.Context;
import org.psidnell.omnifocus.model.Folder;
import org.psidnell.omnifocus.model.Project;
import org.psidnell.omnifocus.model.Task;

/**
 * @author psidnell
 *
 *         Visits a tree collecting all the enclosed nodes by type
 */
public class CollectingVisitor implements Visitor {

    private final VisitorDescriptor what;

    private HashSet<Project> projects = new HashSet<>();
    private HashSet<Task> tasks = new HashSet<>();
    private HashSet<Folder> folders = new HashSet<>();
    private HashSet<Context> contexts = new HashSet<>();

    public CollectingVisitor(VisitorDescriptor what) {
        this.what = what;
    }

    @Override
    public VisitorDescriptor getWhat() {
        return what;
    }

    @Override
    public void enter(Context node) throws Exception {
        contexts.add(node);
    }

    @Override
    public void enter(Folder node) throws Exception {
        folders.add(node);
    }

    @Override
    public void enter(Project node) throws Exception {
        projects.add(node);
    }

    @Override
    public void enter(Task node) throws Exception {
        tasks.add(node);
    }

    public Set<Folder> getFolders() {
        return folders;
    }

    public Set<Project> getProjects() {
        return projects;
    }

    public Set<Task> getTasks() {
        return tasks;
    }

    public Set<Context> getContexts() {
        return contexts;
    }

    @Override
    public String toString() {
        return this.getClass().getSimpleName();
    }
}


text:
google.load("earth", "1");
google.setOnLoadCallback(function () {
    $(document).ready(function () {
        $('div.report').each(
            function (index, element) {
                var thelink, thekml, theoverlay;
                thelink = $('a.maplink', element);
                thekml = thelink.attr('href');
                theoverlay = $('div.overlay', element);

                $(thelink).overlay({
                    top: 'center',
                    target: $(theoverlay),
                    onLoad: function (event) {
                        var initCB, failureCB, themap;
                        initCB = function (instance) {
                            var ge, link, href, networkLink;
                            ge = instance;
                            ge.getWindow().setVisibility(true);
                            ge.getNavigationControl().setVisibility(
                                ge.VISIBILITY_AUTO);
                            ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS,
                                                              true);
                            ge.getOptions().setStatusBarVisibility(true);
                            ge.getOptions().setScaleLegendVisibility(true);

                            link = ge.createLink('');
                            href = thekml;
                            link.setHref(href);

                            networkLink = ge.createNetworkLink('');
                            networkLink.set(link, true, true);

                            ge.getFeatures().appendChild(networkLink);
                        };

                        failureCB = function (errorCode) {
                            console.log(errorCode);
                        };

                        themap = $('div.map', theoverlay)[0];

                        google.earth.createInstance(themap, initCB, failureCB);
	                },

                    onClose: function (event) {
                        //Clear out the overlay so the plugin goes away.
                        $('div.map', theoverlay)[0].innerHTML = '';
                    }
                });
            }
        );
    });
});


text:
import { AngularClientPage } from './app.po';

describe('angular-client App', () => {
  let page: AngularClientPage;

  beforeEach(() => {
    page = new AngularClientPage();
  });

  it('should display message saying app works', () => {
    page.navigateTo();
    expect(page.getParagraphText()).toEqual('app works!');
  });
});


text:
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Step = exports.Step = function () {
  function Step(params) {
    _classCallCheck(this, Step);

    this.parent = params.parent || null;
    this.name = params.name;
    this.next = params.next;
    this.methods = params.methods || {};
    this.template = params.template || '';
    this.ignore_progress = params.ignore_progress || false;
    this.hide_progress = params.hide_progress || false;
    this.from = null;
    this.required = params.required || false;
    this._data = params.data || {};
    params.interceptors = params.interceptors || {};
    this.interceptors = {
      isSkip: params.interceptors.isSkip || this.methods.isSkip || function () {
        return false;
      },
      beforeRender: params.interceptors.beforeRender || this.methods.beforeRender || function () {
        return { status: true };
      },
      beforeNext: params.interceptors.beforeNext || this.methods.beforeNext || function () {
        return { status: true };
      },
      beforeBack: params.interceptors.beforeBack || this.methods.beforeBack || function () {
        return { status: true };
      }
    };
  }

  /* LINKS */

  _createClass(Step, [{
    key: 'call',
    value: function call(method) {
      var fnc = this.methods[method] || this.interceptors[method];
      if (fnc) {
        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        return fnc.apply(this, args);
      }
    }
  }, {
    key: 'goNext',
    get: function get() {
      return this.parent.goNext;
    }
  }, {
    key: 'goBack',
    get: function get() {
      return this.parent.goBack;
    }
  }, {
    key: 'goToStep',
    get: function get() {
      return this.parent.goToStep;
    }
  }, {
    key: 'data',
    get: function get() {
      return this._data;
    }
  }, {
    key: 'container',
    get: function get() {
      return this.parent.container.find(this.parent._step_container);
    }
  }]);

  return Step;
}();

},{}],2:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * StepSystem v1.0.1
 * Last update: 25.05.2017
 *
 * Dependencies: jQuery
 *
 * @author kaskar2008
 */

var StepSystem = exports.StepSystem = function () {
  /**
   * @param  {jQuery element} container
   */
  function StepSystem(params) {
    _classCallCheck(this, StepSystem);

    this._steps = {};
    this._current_step = null;
    this._container = params.container || $('.step-system');
    this._step_container = params.step_class || '.step';
    this._next_timeout = null;
    this.steps_past = [];
    this.progress = 0;
    this.commonHandlers = function () {};
    this.onFinish = function () {};
    this.onProgress = function () {};
    this.onStepRender = function () {};

    this._global_interceptors = {
      isSkipGlobal: function isSkipGlobal(step) {
        return step.interceptors.isSkip(step);
      },
      beforeNext: function beforeNext(step) {
        return new Promise(function (resolve) {
          resolve();
        });
      },
      beforeBack: function beforeBack(step) {
        return new Promise(function (resolve) {
          resolve();
        });
      }
    };
  }

  /**
   * Add new step
   * @param {Step} step
   */

  _createClass(StepSystem, [{
    key: 'addStep',
    value: function addStep(step) {
      step.parent = this;
      this._steps[step.name] = step;
      return this;
    }
  }, {
    key: 'setGlobalInterceptors',
    value: function setGlobalInterceptors(interceptors) {
      this._global_interceptors = Object.assign(this._global_interceptors, interceptors);
      return this;
    }
  }, {
    key: 'setHandlers',
    value: function setHandlers(cb) {
      this.commonHandlers = cb;
      return this;
    }
  }, {
    key: 'step',
    value: function step(name) {
      return this._steps[name];
    }
  }, {
    key: 'render',
    value: function render(step) {
      var _br = step.call('beforeRender', step);
      if (!_br.status) {
        if (_br.onError) _br.onError.apply(step);
        return this;
      }
      this.container.find(this._step_container).html(step.template || this._container.find('#' + step.name).html());
      this.container.find(this._step_container).attr('data-name', step.name);
      this.onStepRender(step);
      step.call('onRender', step);
    }
  }, {
    key: 'updateProgress',
    value: function updateProgress() {
      var future_steps = 0;
      var iteration_step = this.current_step;
      var iteration_next_step = iteration_step.next;
      while (iteration_next_step) {
        if (!iteration_step.ignore_progress) {
          future_steps++;
        }
        iteration_step = this.step(iteration_next_step);
        iteration_next_step = iteration_step.next;
      }
      this.progress = this.steps_past.length * 100 / (this.steps_past.length + future_steps);
      this.onProgress(this.progress);
    }
  }, {
    key: 'goNextTimeout',
    value: function goNextTimeout() {
      var timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 300;

      var $this = this;
      clearTimeout(this._next_timeout);
      this._next_timeout = setTimeout(function () {
        $this.goNext();
      }, timeout);
    }
  }, {
    key: 'goNext',
    value: function goNext() {
      var _this = this;

      var curr_step = this.current_step || {};
      this.global_interceptors.beforeNext(curr_step).then(function () {
        var _bn = curr_step.call('beforeNext', curr_step);
        if (!_bn.status) {
          if (_bn.onError) {
            _bn.onError.apply(curr_step);
          }
          return;
        }
        var next_step = curr_step.next || null;
        if (next_step) {
          _this.goToStep(_this.step(next_step), { from: curr_step.name });
        } else {
          if (_this.onFinish) {
            _this.onFinish();
          }
        }
      }).catch(function () {});
      return this;
    }
  }, {
    key: 'goBack',
    value: function goBack() {
      var _this2 = this;

      var curr_step = this.current_step || {};
      this.global_interceptors.beforeBack(curr_step).then(function () {
        var prev_step = curr_step.from || null;
        var _bb = curr_step.call('beforeBack', curr_step) || { status: false };
        if (!_bb.status) {
          if (_bb.onError) _bb.onError.apply(curr_step);
          return;
        }
        if (prev_step) {
          if (_bb.status) {
            _this2.steps_past.pop();
          }
          _this2.goToStep(_this2.step(prev_step), { is_back: true });
        }
      }).catch(function () {});
      return this;
    }
  }, {
    key: 'goToStep',
    value: function goToStep(step) {
      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

      var is_skip = this.global_interceptors.isSkipGlobal(step) || step.call('isSkip', step);
      if (is_skip) {
        step = this.step(step.next);
      }
      var from = params.from || null;
      var is_back = params.is_back || false;
      if (from) {
        step.from = from;
      }
      this.render(step);
      this._current_step = step.name;
      if (this.steps_past.indexOf(step.name) < 0) {
        this.steps_past.push(step.name);
      }
      this.updateProgress();
      return this;
    }
  }, {
    key: 'collectData',
    value: function collectData() {
      var data = {};
      for (var step in this.steps) {
        if (this.step(step).data) {
          data[step] = this.step(step).data;
        }
      }
      return data;
    }
  }, {
    key: 'init',
    value: function init(first_step) {
      this.first_step = first_step;
      this.commonHandlers();
      this._current_step = this.first_step;
      this.goToStep(this.step(this._current_step));
    }
  }, {
    key: 'global_interceptors',
    get: function get() {
      return this._global_interceptors;
    }
  }, {
    key: 'current_step',
    get: function get() {
      return this.step(this._current_step) || null;
    }
  }, {
    key: 'container',
    get: function get() {
      return this._container;
    }
  }, {
    key: 'steps',
    get: function get() {
      return this._steps;
    }
  }, {
    key: 'all_data',
    get: function get() {
      return this.collectData();
    }
  }]);

  return StepSystem;
}();

},{}],3:[function(require,module,exports){
'use strict';

var _Step = require('../classes/Step');

var _StepSystem = require('../classes/StepSystem');

window.app = new _StepSystem.StepSystem({
  container: $('.container'),
  step_class: '.step'
});

(function (app) {
  var _this = this;

  var first_step = 'first-step';

  app
  /**
   * COMMON HANDLERS
   */
  .setHandlers(function () {
    console.log('handlers init');
  })

  /**
   * FIRST STEP
   */
  .addStep(new _Step.Step({
    name: 'first-step',
    next: 'second-step',
    methods: {
      beforeRender: function beforeRender(step) {
        console.log('first-step beforeRender');
        return { status: true };
      },
      beforeNext: function beforeNext(step) {
        console.log('first-step beforeNext', _this);
        step.data.lol = 'lol';
        return { status: true };
      },
      onRender: function onRender(step) {
        app.container.find('.step').css({ 'color': 'green' });
      }
    }
  }))

  /**
   * SECOND STEP
   */
  .addStep(new _Step.Step({
    name: 'second-step',
    next: 'third-step',
    methods: {
      isSkip: function isSkip(step) {
        return app.step('first-step').data.lol == 'lol';
      },
      beforeRender: function beforeRender(step) {
        console.log('second-step beforeRender');
        return { status: true };
      },
      beforeNext: function beforeNext(step) {
        console.log('second-step beforeNext');
        step.data.azaza = 'azaza';
        return { status: true };
      },
      onRender: function onRender(step) {
        app.container.find('.step').css({ 'color': 'red' });
      }
    }
  }))

  /**
   * THIRD STEP
   */
  .addStep(new _Step.Step({
    name: 'third-step',
    methods: {
      beforeRender: function beforeRender(step) {
        console.log('third-step beforeRender');
        return { status: true };
      },
      beforeNext: function beforeNext(step) {
        console.log('third-step beforeNext');
        step.data.kek = 'kek';
        return { status: true };
      },
      onRender: function onRender(step) {
        app.container.find('.step').css({ 'color': 'blue' });
      }
    }
  }))

  /**
   * FINISH
   */
  .addStep(new _Step.Step({
    name: 'finish',
    hide_progress: true,
    ignore_progress: true,
    methods: {
      beforeRender: function beforeRender(step) {
        console.log('finish beforeRender');
        return { status: true };
      },
      beforeNext: function beforeNext(step) {
        console.log('finish beforeNext');
        step.data.kek = 'kek';
        return { status: true };
      },
      onRender: function onRender(step) {
        step.call('anyOfInternalMethods');
      },
      anyOfInternalMethods: function anyOfInternalMethods() {
        alert('Hey there');
      }
    }
  }));

  /**
   * GLOBAL
   */

  app.onFinish = function () {
    app.goToStep(app.step('finish'));
    console.log(app.collectData());
  };

  app.onProgress = function (progress) {
    app.container.find('.progress').html(Math.floor(progress) + '%');
  };

  app.onStepRender = function (step) {
    app.container.find('.step .next').click(function () {
      app.goNext();
    });
    app.container.find('.step .back').click(function () {
      app.goBack();
    });

    console.log(step);

    if (step.hide_progress) {
      app.container.find('.progress').hide();
    } else {
      app.container.find('.progress').show();
    }
  };

  app.init(first_step);
})(window.app);

},{"../classes/Step":1,"../classes/StepSystem":2}]},{},[3])

//# sourceMappingURL=app.js.map


text:
from nova import objects

def fake_diagnostics_obj(**updates):
    diag = objects.Diagnostics()
    cpu_details = updates.pop('cpu_details', [])
    nic_details = updates.pop('nic_details', [])
    disk_details = updates.pop('disk_details', [])
    memory_details = updates.pop('memory_details', {})

    for field in objects.Diagnostics.fields:
        if field in updates:
            setattr(diag, field, updates[field])

    for cpu in cpu_details:
        diag.add_cpu(**cpu)

    for nic in nic_details:
        diag.add_nic(**nic)

    for disk in disk_details:
        diag.add_disk(**disk)

    for k, v in memory_details.items():
        setattr(diag.memory_details, k, v)

    return diag


text:
@interface MCKMockingContextTest : XCTestCase @end
@implementation MCKMockingContextTest {
    MCKMockingContext *context;
}

#pragma mark - Setup

- (void)setUp
{
    context = [[MCKMockingContext alloc] initWithTestCase:self];
    context.invocationRecorder = MKTMock([MCKInvocationRecorder class]);
    context.invocationStubber = MKTMock([MCKInvocationStubber class]);
    context.invocationVerifier = MKTMock([MCKInvocationVerifier class]);
    context.argumentMatcherRecorder = MKTMock([MCKArgumentMatcherRecorder class]);
    context.failureHandler = MKTMock([MCKFailureHandler class]);
}

#pragma mark - Test Handling Invocations Preparations

- (void)testThatHandlingInvocationRetainsInvocationArguments
{
    // given
    NSInvocation *invocation = MKTMock([NSInvocation class]);

    // when
    [context handleInvocation:invocation];

    // then
    [MKTVerify(invocation) retainArguments];
}

- (void)testThatHandlingInvocationValidatesArgumentMatchers
{
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];

    // when
    [context handleInvocation:invocation];

    // then
    [MKTVerify(context.argumentMatcherRecorder) validateForMethodSignature:invocation.methodSignature];
}

- (void)testThatHandlingInvocationClearsArgumentMatchers
{
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];

    // when
    [context handleInvocation:invocation];

    // then
    [MKTVerify(context.argumentMatcherRecorder) collectAndReset];
}

KNMParametersFor(testThatHandlingInvocationSucceedsIfArgumentMatchersAreGivenInMode, @[
    @(MCKContextModeStubbing), @(MCKContextModeVerifying)
])
- (void)testThatHandlingInvocationSucceedsIfArgumentMatchersAreGivenInMode:(MCKContextMode)mode
{
    // given
    [context updateContextMode:mode];

    NSArray *matchers = @[ [[MCKBlockArgumentMatcher alloc] init] ];
    [MKTGiven([context.argumentMatcherRecorder argumentMatchers]) willReturn:matchers];

    // then
    expect(^{
        [context handleInvocation:[NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)]];
    }).toNot.raiseAny();
}

- (void)testThatHandlingInvocationFailsIfArgumentMatchersAreGivenInRecordingMode
{
    // given
    [context updateContextMode:MCKContextModeRecording];

    NSArray *matchers = @[ [[MCKBlockArgumentMatcher alloc] init] ];
    [MKTGiven([context.argumentMatcherRecorder argumentMatchers]) willReturn:matchers];

    // then
    expect(^{
        [context handleInvocation:[NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)]];
    }).to.raise(MCKAPIMisuseException);
}

#pragma mark - Test Handling Invocations Dispatching

- (void)testThatHandlingInvocationInRecordingModeDispatchesToInvocationRecorder {
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];
    MCKInvocationPrototype *prototype = [[MCKInvocationPrototype alloc] initWithInvocation:invocation];

    // when
    [context updateContextMode:MCKContextModeRecording];
    [context handleInvocation:invocation];

    // then
    [MKTVerify(context.invocationRecorder) recordInvocationFromPrototype:prototype];

    [MKTVerifyCount(context.invocationStubber, MKTNever()) recordStubPrototype:HC_anything()];
    [MKTVerifyCount(context.invocationVerifier, MKTNever()) verifyInvocationsForPrototype:HC_anything()];
}

- (void)testThatHandlingInvocationInStubbingModeDispatchesToInvocationStubber {
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];
    MCKInvocationPrototype *prototype = [[MCKInvocationPrototype alloc] initWithInvocation:invocation];

    // when
    [context updateContextMode:MCKContextModeStubbing];
    [context handleInvocation:invocation];

    // then
    [MKTVerify(context.invocationStubber) recordStubPrototype:prototype];

    [MKTVerifyCount(context.invocationRecorder, MKTNever()) recordInvocationFromPrototype:HC_anything()];
    [MKTVerifyCount(context.invocationVerifier, MKTNever()) verifyInvocationsForPrototype:HC_anything()];
}

- (void)testThatHandlingInvocationInVerificationModeDispatchesToInvocationVerifier {
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];

    // when
    [context updateContextMode:MCKContextModeVerifying];
    [context handleInvocation:invocation];

    // then
    [MKTVerify(context.invocationVerifier) verifyInvocationsForPrototype:[[MCKInvocationPrototype alloc] initWithInvocation:invocation]];

    [MKTVerifyCount(context.invocationRecorder, MKTNever()) recordInvocationFromPrototype:HC_anything()];
    [MKTVerifyCount(context.invocationStubber, MKTNever()) recordStubPrototype:HC_anything()];
}

KNMParametersFor(testThatHandlingInvocationDoesNotChangeContextMode, @[
    @(MCKContextModeRecording), @(MCKContextModeStubbing), @(MCKContextModeVerifying)
]);
- (void)testThatHandlingInvocationDoesNotChangeContextMode:(MCKContextMode)mode
{
    // given
    NSInvocation *invocation = [NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)];

    // when
    [context updateContextMode:mode];
    [context handleInvocation:invocation];

    // then
    expect(context.mode).to.equal(mode);
}

#pragma mark - Test Error Messages

- (void)testThatFailWithReasonCallsFailureHandlerWithFormattedReason {
    // when
    [context failWithReason:@"Hello, %@!", @"World"];

    // then
    [MKTVerify(context.failureHandler) handleFailureAtLocation:context.currentLocation withReason:@"Hello, World!"];
}

#pragma mark - LEGACY TESTS: TO BE MOVED

#pragma mark - Test Invocation Stubbing

- (void)testThatContextIsInRecordingModeAfterStubbing {
    // when
    [context stubCalls:^{
        [context handleInvocation:[NSInvocation invocationForTarget:self selectorAndArguments:@selector(setUp)]];
    }];

    // then
    expect(context.mode).to.equal(MCKContextModeRecording);
}

@end


text:
#include "base/string_utilities.h"
#include "base/file_utilities.h"
#include "base/file_functions.h"

#include <stdexcept>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <errno.h>
#include <fcntl.h>
#include <sys/file.h>
#endif
#include <algorithm>

namespace base {

  std::string format_file_error(const std::string &text, int err)
  {
#ifdef _WIN32
    return strfmt("%s: error code %i", text.c_str(), err);
#else
    return strfmt("%s: %s", text.c_str(), strerror(err));
#endif
  }

  file_error::file_error(const std::string &text, int err)
  : std::runtime_error(format_file_error(text, err)), sys_error_code(err)
  {
  }

  error_code file_error::code()
  {
#ifdef _WIN32
    switch (sys_error_code)
    {
      case 0:
        return success;
      case ERROR_FILE_NOT_FOUND:
      case ERROR_PATH_NOT_FOUND:
        return file_not_found;
      case ERROR_ALREADY_EXISTS:
        return already_exists;
      case ERROR_ACCESS_DENIED:
        return access_denied;
      default:
        return other_error;
    }
#else
    switch (sys_error_code)
    {
      case 0:
        return success;
      case ENOENT:
        return file_not_found;
      case EEXIST:
        return already_exists;
      case EACCES:
        return access_denied;
      default:
        return other_error;
    }
#endif
  }

//--------------------------------------------------------------------------------------------------

  std::list<std::string> scan_for_files_matching(const std::string &pattern, bool recursive)
  {
    std::list<std::string> matches;

    std::string path = dirname(pattern);
    if (!g_file_test(path.c_str(), G_FILE_TEST_EXISTS))
    {
      return matches;
    }

    std::string pure_pattern = pattern.substr(path.size() + 1);

    std::string bname = basename(pattern);
    GPatternSpec *pat = g_pattern_spec_new(bname.c_str());
    GDir *dir;
    {
      GError *err = NULL;
      dir = g_dir_open(path.empty() ? "." : path.c_str(), 0, &err);
      if (!dir)
      {
        std::string msg = strfmt("can't open %s: %s", !path.empty() ? path.c_str() : ".", err->message);
        g_error_free(err);
        g_pattern_spec_free(pat);
        throw std::runtime_error(msg);
      }
    }
    const gchar *filename;
    while ((filename = g_dir_read_name(dir)))
    {
      std::string full_path = strfmt("%s%s%s", path.c_str(), G_DIR_SEPARATOR_S, filename);
      if (g_pattern_match_string(pat, filename))
        matches.push_back(full_path);

      if (recursive && g_file_test(full_path.c_str(), G_FILE_TEST_IS_DIR))
      {
        std::string subpattern = strfmt("%s%s%s", full_path.c_str(), G_DIR_SEPARATOR_S, pure_pattern.c_str());
        std::list<std::string> submatches = scan_for_files_matching(subpattern, true);
        if (submatches.size() > 0)
          matches.insert(matches.end(), submatches.begin(), submatches.end());
      }
    }
    g_dir_close(dir);
    g_pattern_spec_free(pat);
    return matches;
  }

//--------------------------------------------------------------------------------------------------

#ifdef _WIN32
  LockFile::LockFile(const std::string &path) throw (std::invalid_argument, std::runtime_error, file_locked_error)
    : path(path), handle(0)
  {
    std::wstring wpath(string_to_wstring(path));
    if (path.empty()) throw std::invalid_argument("invalid path");

    handle = CreateFileW(wpath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL,
      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (handle == INVALID_HANDLE_VALUE)
    {
      if (GetLastError() == ERROR_SHARING_VIOLATION)
        throw file_locked_error("File already locked");
      throw std::runtime_error(strfmt("Error creating lock file (%i)", GetLastError()));
    }

    char buffer[32];
    sprintf_s(buffer, "%i", GetCurrentProcessId());
    DWORD bytes_written;

    if (!WriteFile(handle, buffer, (DWORD)strlen(buffer), &bytes_written, NULL) || bytes_written != strlen(buffer))
    {
      CloseHandle(handle);
      DeleteFileW(wpath.c_str());
      throw std::runtime_error("Could not write to lock file");
    }
  }

  LockFile::~LockFile()
  {
    if (handle)
      CloseHandle(handle);
    DeleteFileW(string_to_wstring(path).c_str());
  }

  LockFile::Status LockFile::check(const std::string &path)
  {
    // Can we open the file in exclusive mode?
    std::wstring wpath = string_to_wstring(path);
    HANDLE h = CreateFile(wpath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (h != INVALID_HANDLE_VALUE)
    {
      CloseHandle(h);
      return NotLocked;
    }

    switch (GetLastError())
    {
    case ERROR_SHARING_VIOLATION:
      // If file cannot be opened for writing it's open somewhere else.
      // Try to open it and read the first bytes to see if that corresponds to our process id.
      h = CreateFileW(wpath.c_str(),
            GENERIC_READ,
            FILE_SHARE_WRITE | FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (h != INVALID_HANDLE_VALUE)
      {
        char buffer[32];
        DWORD bytes_read;
        if (ReadFile(h, buffer, sizeof(buffer), &bytes_read, NULL))
        {
          CloseHandle(h);
          buffer[bytes_read] = 0;
          if (base::atoi<int>(buffer, -1) != GetCurrentProcessId())
            return LockedOther; // TODO: this unreliable. Any non-lock file would qualify here (which is wrong).
          return LockedSelf;
        }
        CloseHandle(h);
        return LockedOther;
      }

      // If the file cannot be read assume its locked by another process.
      return LockedOther;

    case ERROR_FILE_NOT_FOUND:
      return NotLocked;

    case ERROR_PATH_NOT_FOUND:
      throw std::invalid_argument("Invalid path");

    default:
      throw std::runtime_error(strfmt("Unknown error while checking file %s for locks (%i)", path.c_str(), GetLastError()));
    }
  }
#else
  LockFile::LockFile(const std::string &apath) throw (std::invalid_argument, std::runtime_error, file_locked_error)
  : path(apath)
  {
    if (path.empty()) throw std::invalid_argument("invalid path");

    fd = open(path.c_str(), O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
    if (fd < 0)
    {
      // this could mean lock exists, that it's a dangling file or that it's currently being locked by some other process/thread
      // we just go on and try to lock the file if the file already exists
      if (errno == ENOENT || errno == ENOTDIR)
        throw std::invalid_argument("invalid path");

      throw std::runtime_error(strfmt("%s creating lock file", g_strerror(errno)));
    }
    if (flock(fd, LOCK_EX|LOCK_NB) < 0)
    {
      close(fd);
      fd = -1;
      if (errno == EWOULDBLOCK)
        throw file_locked_error("file already locked");

      throw std::runtime_error(strfmt("%s while locking file", g_strerror(errno)));
    }

    ftruncate(fd, 0);

    char pid[32];
    snprintf(pid, sizeof(pid), "%i", getpid());
    if (write(fd, pid, strlen(pid)+1) < 0)
    {
      close(fd);
      throw std::runtime_error(strfmt("%s while locking file", g_strerror(errno)));
    }
  }

  LockFile::~LockFile()
  {
    if (fd >= 0)
      close(fd);
    unlink(path.c_str());
  }

  LockFile::Status LockFile::check(const std::string &path)
  {
    int fd = open(path.c_str(), O_RDONLY);
    if (fd < 0)
      return NotLocked;

    if (flock(fd, LOCK_EX|LOCK_NB) < 0)
    {
      char pid[32];
      // couldn't lock file, check if we own it ourselves
      int c = read(fd, pid, sizeof(pid)-1);
      close(fd);
      if (c < 0)
        return LockedOther;
      pid[c] = 0;
      if (base::atoi<int>(pid, -1) != getpid())
        return LockedOther;
      return LockedSelf;
    }
    else // nobody holds a lock on the file, so this is a leftover
    {
      flock(fd, LOCK_UN);
      close(fd);
      return NotLocked;
    }
  }
#endif

  bool create_directory(const std::string &path, int mode, bool with_parents)
  {
#ifdef _WIN32
    SetLastError(0);
    if (!CreateDirectoryW(path_from_utf8(path).c_str(), NULL))
    {
      DWORD error = GetLastError();
      if (error == ERROR_ALREADY_EXISTS)
        return false;

      if (with_parents)
      {
        if (error == ERROR_PATH_NOT_FOUND)
        {
          // create parents too
          std::string tmp = path;
          std::list<std::string> stack;
          while (!tmp.empty() && !file_exists(tmp))
          {
            stack.push_back(tmp);
            tmp = dirname(tmp);
          }
          if (tmp.empty()) // path is invalid
            throw file_error(strfmt("Could not create directory %s",
                              path.c_str()), ERROR_PATH_NOT_FOUND);

          while (!stack.empty())
          {
            if (!CreateDirectoryW(path_from_utf8(stack.back()).c_str(), NULL))
              throw file_error(strfmt("Could not create directory %s",
                                      path.c_str()), GetLastError());
            stack.pop_back();
          }
          return true;
        }
      }

      throw file_error(strfmt("Could not create directory %s", path.c_str()), GetLastError());
    }
#else
    if (with_parents)
    {
      if (g_mkdir_with_parents(path_from_utf8(path).c_str(), mode) < 0)
        throw file_error(strfmt("Could not create directory %s",
                                path.c_str()), errno);
    }
    else
    {
      // do not use g_mkdir_with_parents here, as we rely on the specific behaviour of g_mkdir (g_mkdir_with_parents doesnt fail if dir exists)
      if (g_mkdir(path_from_utf8(path).c_str(), mode) < 0)
      {
        if (errno == EEXIST)
          return false;
        throw file_error(strfmt("Could not create directory %s",
                                path.c_str()), errno);
      }
    }
#endif
    return true;
  }

  void rename(const std::string &from, const std::string &to)
  {
#ifdef _WIN32
    if (!MoveFile(path_from_utf8(from).c_str(), path_from_utf8(to).c_str()))
      throw file_error(strfmt("Could not rename file %s to %s", from.c_str(), to.c_str()), GetLastError());
#else
    if (::g_rename(path_from_utf8(from).c_str(), path_from_utf8(to).c_str()) < 0)
      throw file_error(strfmt("Could not rename file %s to %s", from.c_str(), to.c_str()), errno);
#endif
  }

  bool remove_recursive(const std::string &path)
  {
    GError *error= NULL;
    GDir* dir;
    const char *dir_entry;
    gchar *entry_path;

    dir= g_dir_open(path.c_str(), 0, &error);
    if (!dir && error)
      return false;

    while ((dir_entry= g_dir_read_name(dir)))
    {
      entry_path= g_build_filename(path.c_str(), dir_entry, NULL);
      if (g_file_test(entry_path, G_FILE_TEST_IS_DIR))
        (void) remove_recursive(entry_path);
      else
        (void) ::g_remove(entry_path);
      g_free(entry_path);
    }

    (void) g_rmdir(path.c_str());

    g_dir_close(dir);
    return true;
  }

  bool remove(const std::string &path)
  {
#ifdef _WIN32
    if (is_directory(path))
    {
      if (!RemoveDirectoryW(path_from_utf8(path).c_str()))
      {
        if (GetLastError() == ERROR_FILE_NOT_FOUND
          || GetLastError() == ERROR_PATH_NOT_FOUND)
          return false;
        throw file_error(strfmt("Could not delete file %s", path.c_str()), GetLastError());
      }
    }
    else
    {
      if (!DeleteFileW(path_from_utf8(path).c_str()))
      {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
          return false;
        throw file_error(strfmt("Could not delete file %s", path.c_str()), GetLastError());
      }
    }
#else
    if (::g_remove(path_from_utf8(path).c_str()) < 0)
    {
      if (errno == ENOENT)
        return false;
      throw file_error(strfmt("Could not delete file %s", path.c_str()), errno);
    }
#endif
    return true;
  }

  bool file_exists(const std::string &path)
  {
    char *f = g_filename_from_utf8(path.c_str(), -1, NULL, NULL, NULL);
    if (g_file_test(f, G_FILE_TEST_EXISTS))
    {
      g_free(f);
      return true;
    }
    g_free(f);
    return false;
  }

  bool is_directory(const std::string &path)
  {
    char *f = g_filename_from_utf8(path.c_str(), -1, NULL, NULL, NULL);
    if (g_file_test(f, G_FILE_TEST_IS_DIR))
    {
      g_free(f);
      return true;
    }
    g_free(f);
    return false;
  }
  /*
  std::string make_path(const std::string &path, const std::string &filename)
  {
    if (path.empty())
      return filename;

    if (path[path.size()-1] == '/' || path[path.size()-1] == '\\')
      return path+filename;
    return path+G_DIR_SEPARATOR+filename;
  }*/

  std::string extension(const std::string &path)
  {
    std::string::size_type p = path.rfind('.');
    if (p != std::string::npos)
    {
      std::string ext(path.substr(p));
      if (ext.find('/') != std::string::npos || ext.find('\\') != std::string::npos)
        return "";
      return ext;
    }
    return "";
  }

  std::string dirname(const std::string &path)
  {
    char *dn = g_path_get_dirname(path.c_str());
    std::string tmp(dn);
    g_free(dn);
    return tmp;
  }

  std::string basename(const std::string &path)
  {
    char *dn = g_path_get_basename(path.c_str());
    std::string tmp(dn);
    g_free(dn);
    return tmp;
  }

  std::string strip_extension(const std::string &path)
  {
    std::string ext;
    if (!(ext = extension(path)).empty())
    {
      return path.substr(0, path.size() - ext.size());
    }
    return path;
  }

FileHandle::FileHandle(const char *filename, const char *mode, bool throw_on_fail)
: _file(NULL)
{
    _file = base_fopen(filename, mode);
    if (!_file && throw_on_fail)
      throw file_error(std::string("Failed to open file \"").append(filename).append("\""), errno);
}

  FileHandle & FileHandle::operator =(FileHandle &fh)
  {
    dispose();
    swap(fh);
    return *this;
  }

  void FileHandle::swap(FileHandle &fh)
  {
    std::swap(_file, fh._file);
  }

  void FileHandle::dispose()
  {
    if (_file)
    {
      ::fclose(_file);
      _file= NULL;
    }
  }

/**
 * Returns the last modification time of the given file.
 */
bool file_mtime(const std::string &path, time_t &mtime)
{
#ifdef _WIN32
  struct _stat stbuf;
#else
  struct stat stbuf;
#endif

  if (base_stat(path.c_str(), &stbuf) == 0)
  {
#ifdef __APPLE__
    mtime = (time_t)stbuf.st_mtimespec.tv_sec;
#else
    mtime = stbuf.st_mtime;
#endif
    return true;
  }
  return false;
}

std::string join_path(const char *prefix, ...)
{
  std::string path = prefix;
  char wrong_path_separator = G_DIR_SEPARATOR == '/' ? '\\' : '/';
  std::replace(path.begin(), path.end(), wrong_path_separator, G_DIR_SEPARATOR);
  std::string arg = const_cast<char*>(prefix);
  va_list ap;
  va_start(ap, prefix);
  while (!arg.empty())
  {
    arg = va_arg(ap, char*);
    if (!arg.empty())
    {
      if (path[path.size() - 1] == G_DIR_SEPARATOR)
        path += arg;
      else
        path += G_DIR_SEPARATOR + arg;
    }
  }
  va_end(ap);

  return path;
}

};


text:
class UserConversationSerializer
  include TalkSerializer
  all_attributes
  can_include :user, :conversation
end


text:
import asyncio
import json

from EOSS.aws.instance.DesignEvaluatorInstance import DesignEvaluatorInstance
from EOSS.aws.instance.GeneticAlgorithmInstance import GeneticAlgorithmInstance
from EOSS.aws.clients.InstanceClient import InstanceClient
from EOSS.aws.utils import _save_eosscontext

class InstanceManager:

    def __init__(self, user_info, resource_type='design-evaluator'):
        self.user_info = user_info
        self.user_id = self.user_info.user.id
        self.eosscontext = user_info.eosscontext
        self.resource_type = resource_type

        # --> List of (AbstractInstance) objects
        self.instances = []

    @property
    async def instance_limit(self):
        if self.resource_type == 'design-evaluator':
            return int(self.eosscontext.design_evaluator_instance_count)
        elif self.resource_type == 'genetic-algorithm':
            return int(self.eosscontext.genetic_algorithm_instance_count)
        return 1

    async def initialize(self):

        # --> 1. Find num instances to create
        user_instance_limit = await self.instance_limit
        current_count = len(self.instances)

        # --> 2. Check instances to be created
        if current_count >= user_instance_limit:
            return

        # --> 3. Create instances
        async_tasks = []
        for itr in range(current_count, user_instance_limit):

            # --> Create Instance
            instance = None
            if self.resource_type == 'design-evaluator':
                instance = DesignEvaluatorInstance(self.user_info)
            elif self.resource_type == 'genetic-algorithm':
                instance = GeneticAlgorithmInstance(self.user_info)

            # --> Initialize Instance, add
            async_tasks.append(asyncio.create_task(instance.initialize()))
            self.instances.append(instance)
        for task in async_tasks:
            await task

    async def gather(self):

        async def create_instance(instance, instance_status_info, instance_ssm_info):
            if self.resource_type == 'design-evaluator':
                return DesignEvaluatorInstance(self.user_info, instance=instance,
                                               instance_status_info=instance_status_info,
                                               instance_ssm_info=instance_ssm_info)
            elif self.resource_type == 'genetic-algorithm':
                return GeneticAlgorithmInstance(self.user_info, instance=instance,
                                                instance_status_info=instance_status_info,
                                                instance_ssm_info=instance_ssm_info)

        self.instances = []

        # --> 1. Get user instances
        user_instances, instance_status_info_list, instance_ssm_info_list = await InstanceClient.get_user_active_instances_all(
            self.user_id, self.resource_type)

        # --> 2. Instantiate each user instance
        for idx, instance in enumerate(user_instances):
            instance_status_info = instance_status_info_list[idx]
            instance_ssm_info = instance_ssm_info_list[idx]
            self.instances.append(await create_instance(instance, instance_status_info, instance_ssm_info))

        # --> 3. Initialize each user instance
        async_tasks = []
        for instance in self.instances:
            async_tasks.append(asyncio.create_task(instance.initialize()))
        for task in async_tasks:
            await task

    ########################
    ### INSTANCE GETTERS ###
    ########################

    async def get_instance_by_identifier(self, identifier):
        for instance in self.instances:
            if instance.identifier == identifier:
                return instance
        return None

    async def get_instances_by_state(self, state):
        async def add_if_correct_state(instance_check, state_check, instance_list):
            if (await instance_check.get_instance_state) == state_check:
                instance_list.append(instance_check)

        search_instances = []
        async_tasks = []
        for instance in self.instances:
            async_tasks.append(
                asyncio.create_task(add_if_correct_state(instance, state, search_instances))
            )
        for task in async_tasks:
            await task
        return search_instances

    async def get_instances_by_states(self, states):
        async def add_if_correct_state(instance_check, state_check, instance_list):
            state = await instance_check.get_instance_state
            if state in state_check:
                instance_list.append(instance_check)

        search_instances = []
        async_tasks = []
        for instance in self.instances:
            async_tasks.append(
                asyncio.create_task(add_if_correct_state(instance, states, search_instances))
            )
        for task in async_tasks:
            await task
        return search_instances

    ############
    ### PING ###
    ############

    async def ping_instances(self):
        async def ping_instance(local_instance, local_survey):
            instance_ping = await local_instance.ping()
            if instance_ping is not None:
                local_survey.append(instance_ping)

        survey = []
        async_tasks = []
        for instance in self.instances:
            async_tasks.append(asyncio.create_task(ping_instance(instance, survey)))
        for task in async_tasks:
            await task

        return survey

    #####################
    ### CONTROL PANEL ###
    #####################

    async def resource_msg(self, instance_ids, command, blocking=False):
        target_instances = [await self.get_instance_by_identifier(identifier) for identifier in instance_ids]
        results = []
        async_tasks = []
        for instance in target_instances:
            async_tasks.append(asyncio.create_task(self._resource_msg(instance, command, results)))
        if blocking is False:
            return []
        for task in async_tasks:
            await task
        return results

    async def _resource_msg(self, instance, command, results):
        func = getattr(instance, command)
        results.append({
            'result': await func(),
            'identifier': instance.identifier
        })

    ############
    ### LOCK ###
    ############

    @property
    async def lock(self):
        if self.resource_type == 'design-evaluator':
            return self.eosscontext.design_evaluator_service_lock
        elif self.resource_type == 'genetic-algorithm':
            return self.eosscontext.genetic_algorithm_service_lock
        return True

    async def lock_service(self):
        if self.resource_type == 'design-evaluator':
            self.eosscontext.design_evaluator_service_lock = True
        elif self.resource_type == 'genetic-algorithm':
            self.eosscontext.genetic_algorithm_service_lock = True
        await _save_eosscontext(self.eosscontext)

    async def unlock_service(self):
        if self.resource_type == 'design-evaluator':
            self.eosscontext.design_evaluator_service_lock = False
        elif self.resource_type == 'genetic-algorithm':
            self.eosscontext.genetic_algorithm_service_lock = False
        await _save_eosscontext(self.eosscontext)