<commit_before>/*
 * Copyright 2018 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
(function() {
    var params = new URLSearchParams(window.location.search);

    var shelf = {};
    var contents = {};

    function linkCodeBlocks(elem, linkable=true) {
        codeworldKeywords = {};
        registerStandardHints(function() {
            var pres = elem.getElementsByTagName('pre');
            for (var i = 0; i < pres.length; ++i) {
                (function() {
                    var pre = pres[i];
                    var text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, { name: 'codeworld', overrideKeywords: codeworldKeywords }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable) {
                        if (text.indexOf("main ") != -1 || text.indexOf("program ") != -1) {
                            pre.classList.add('clickable');
                            pre.onclick = function() {
                                if (env && env.loadSample) {
                                    env.loadSample(text);
                                }
                            }
                        }
                    }
                })();
            }
        });
    }

    function linkFunBlocks(elem) {
        var pres = elem.getElementsByTagName('xml');
        var i = 0;

        while (pres != null && pres.length > 0) {
            let pre = pres[0];
            let text = pre.outerHTML;

            var iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", function() {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow, text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            var parent = pre.parentNode;
            parent.insertBefore(iframe, pre);
            parent.removeChild(pre);

            pres = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        var contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        var elems = body.getElementsByTagName('*');

        var currentLevel = 0;
        var currentElem = contents;
        var n = 0;
        for (var i = 0; i < elems.length; ++i) {
            var header = elems[i];
            var match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            var level = parseInt(match[1]);

            while (currentLevel < level) {
                var sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            var anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            var li = document.createElement('li');
            var link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        var popdiv = document.createElement('div');
        popdiv.style = 'text-align: right';
        var popout = document.createElement('a');
        popout.innerHTML = ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = function (e) {
            var tab = open(this.href);
            tab.addEventListener("load", function () {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        var elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                var url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function setContent(elem) {
        var help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)
        document.body.scrollTop = 0;
        if (document.firstElementChild) document.firstElementChild.scrollTop = 0;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];

        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            var request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = function() {
                if (request.readyState != 4) {
                    return;
                }

                var source = new URL(path, location.href);
                var content = document.createElement('div');
                var raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = new Remarkable({ html: true }).render(raw);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                    } else {
                        linkCodeBlocks(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                }

                var spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }

                setContent(content);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        var path = params.get('path');
        if (!path) path = shelf.default;

        var activeIndex = false;

        var acc = document.createElement('div')
        acc.id = 'helpacc';

        var paneNum = 0;
        for (var doc in shelf.named) {
            var hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            var entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: function(event, ui) {
                var name = ui.newHeader.text();
                var path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    if (params.get('shelf')) {
        var request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = function() {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(params.get('path'));
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<commit_msg>Remove HasCallStack context from documentation in the help window.<commit_after>/*
 * Copyright 2018 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
(function() {
    var params = new URLSearchParams(window.location.search);

    var shelf = {};
    var contents = {};

    function linkCodeBlocks(elem, linkable=true) {
        codeworldKeywords = {};
        registerStandardHints(function() {
            var pres = elem.getElementsByTagName('pre');
            for (var i = 0; i < pres.length; ++i) {
                (function() {
                    var pre = pres[i];
                    var text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, { name: 'codeworld', overrideKeywords: codeworldKeywords }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable) {
                        if (text.indexOf("main ") != -1 || text.indexOf("program ") != -1) {
                            pre.classList.add('clickable');
                            pre.onclick = function() {
                                if (env && env.loadSample) {
                                    env.loadSample(text);
                                }
                            }
                        }
                    }
                })();
            }
        });
    }

    function linkFunBlocks(elem) {
        var pres = elem.getElementsByTagName('xml');
        var i = 0;

        while (pres != null && pres.length > 0) {
            let pre = pres[0];
            let text = pre.outerHTML;

            var iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", function() {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow, text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            var parent = pre.parentNode;
            parent.insertBefore(iframe, pre);
            parent.removeChild(pre);

            pres = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        var contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        var elems = body.getElementsByTagName('*');

        var currentLevel = 0;
        var currentElem = contents;
        var n = 0;
        for (var i = 0; i < elems.length; ++i) {
            var header = elems[i];
            var match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            var level = parseInt(match[1]);

            while (currentLevel < level) {
                var sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            var anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            var li = document.createElement('li');
            var link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        var popdiv = document.createElement('div');
        popdiv.style = 'text-align: right';
        var popout = document.createElement('a');
        popout.innerHTML = ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = function (e) {
            var tab = open(this.href);
            tab.addEventListener("load", function () {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        var elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                var url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function removeCallStacks(node) {
        if (node.nodeType == Node.TEXT_NODE) {
            node.nodeValue = node.nodeValue.replace(/HasCallStack => /, '');
        } else {
            for (let child of node.childNodes) removeCallStacks(child);
        }
    }

    function setContent(elem) {
        var help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)
        document.body.scrollTop = 0;
        if (document.firstElementChild) document.firstElementChild.scrollTop = 0;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];

        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            var request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = function() {
                if (request.readyState != 4) {
                    return;
                }

                var source = new URL(path, location.href);
                var content = document.createElement('div');
                var raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = new Remarkable({ html: true }).render(raw);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                    } else {
                        linkCodeBlocks(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                    removeCallStacks(content);
                }

                var spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }

                setContent(content);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        var path = params.get('path');
        if (!path) path = shelf.default;

        var activeIndex = false;

        var acc = document.createElement('div')
        acc.id = 'helpacc';

        var paneNum = 0;
        for (var doc in shelf.named) {
            var hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            var entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: function(event, ui) {
                var name = ui.newHeader.text();
                var path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    if (params.get('shelf')) {
        var request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = function() {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(params.get('path'));
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<|endoftext|>


<commit_before>import { LD, Wall, SpritePlayer, SpriteEnemy, SpriteBullet } from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight
  } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import Enemy from "objects/Enemy";

const needCamera = false;
const Border = 256;
const MaxBorder = 60;
const MinBorder = 30;
const SizeMaze = Math.trunc(Math.random() * (MaxBorder - MinBorder) + MinBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,1000,100);
    this.game.add.existing(this.hero);

    this.enemy = new Enemy(this.game,300,100);
    this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }

    this.camera.follow(this.hero);
    this.room.createRandomSquare(Border,Border,SizeMaze,1, +2, 1 );
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemy, /*this.damage*/null, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemy, this.kill);
    this.game.physics.arcade.overlap(this.enemy, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.enemy.follow(this.hero.body.position);
  }

  kill(enemy, bullet) {
    bullet.kill();
    enemy.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
    this.game.load.image(SpriteBullet, "res/bullet.png");
  }

  render() {
    this.game.debug.text(Bounds, 2, 14, "#00ff00");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default MainMenu;
<commit_msg>add random parameters<commit_after>import { LD, Wall, SpritePlayer, SpriteEnemy, SpriteBullet } from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight
  } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import Enemy from "objects/Enemy";

const needCamera = false;
const Border = 256;

const MinDivision = 1;
const MaxDivision = 5;

const Division = Math.trunc(Math.random() * (MaxDivision - MinDivision) + MinDivision);

const MaxBorder = 60;
const MinBorder = 30;

const SizeMaze = Math.trunc(Math.random() * (MaxBorder - MinBorder) + MinBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,1000,100);
    this.game.add.existing(this.hero);

    this.enemy = new Enemy(this.game,300,100);
    this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }

    this.camera.follow(this.hero);
    this.room.createRandomSquare(Border,Border,SizeMaze, Division, false);
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemy, /*this.damage*/null, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemy, this.kill);
    this.game.physics.arcade.overlap(this.enemy, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.enemy.follow(this.hero.body.position);
  }

  kill(enemy, bullet) {
    bullet.kill();
    enemy.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
    this.game.load.image(SpriteBullet, "res/bullet.png");
  }

  render() {
    this.game.debug.text(Bounds, 2, 14, "#00ff00");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default MainMenu;
<|endoftext|>


<commit_before>import CenteredSprite from '../prefabs/centeredSprite';

class Menu extends Phaser.State {

    init(gameWon) {
        this.gameWon = gameWon;
    }

    create() {
        let message = 'Gameover';
        if (this.gameWon === true) {
            message = "Officer Waverton can finally rest,\n his partner's brutal murder avenged."
            this.music = this.game.sound.play('music-victory', 0.4);
        } else {
            message = "Officer Waverton failed\n in his quest for justice.\n The city remains in danger\n from the Gang of 99."
            this.music = this.game.sound.play('music-gameover', 0.4);
            // this.game.add.sprite(0,0,'wipeout-bg');
            // this.game.add.sprite(0,0,'wipeout-text');
            new CenteredSprite(this.game, 'wipeout-bg');
            new CenteredSprite(this.game, 'wipeout-text');
        }

        message += "\n(Press X to continue)"

        var style = {
            font: "65px Arial",
            fill: "#ffffff",
            stroke: 0x333333,
            strokeThickness: 5,
            align: "center"
        };
        var text = this.add.text(this.game.world.centerX, this.game.world.centerY, message, style);
        text.anchor.set(0.5);
    }

    update() {
        if (this.game.global.controlSettings.isPressingX()) {
            this.restartGame();
        }
    }

    restartGame() {
        this.game.state.start('menu');
    }

    shutdown() {
        if (!!this.xButton) {
            this.xButton.onDown.removeAll();
        }
        this.music.stop();
    }

}

export default Menu;
<commit_msg>wipeout text tweens in<commit_after>import CenteredSprite from '../prefabs/centeredSprite';

class Menu extends Phaser.State {

    init(gameWon) {
        this.gameWon = gameWon;
    }

    create() {
        let message = 'Gameover';
        if (this.gameWon === true) {
            message = "Officer Waverton can finally rest,\n his partner's brutal murder avenged."
            this.music = this.game.sound.play('music-victory', 0.4);
        } else {
            message = "Officer Waverton failed\n in his quest for justice.\n The city remains in danger\n from the Gang of 99."
            this.music = this.game.sound.play('music-gameover', 0.4);
            new CenteredSprite(this.game, 'wipeout-bg');
            const wipeoutText = this.game.add.sprite(0, this.game.world.centerY, 'wipeout-text');
            wipeoutText.anchor.set(0.5);
            wipeoutText.x = -wipeoutText.width;
            this.game.add.tween(wipeoutText).to(
                {x:this.game.world.centerX},
                1500,
                Phaser.Easing.Bounce.Out,
                true
            );
        }

        message += "\n(Press X to continue)"

        var style = {
            font: "65px Arial",
            fill: "#ffffff",
            stroke: 0x333333,
            strokeThickness: 5,
            align: "center"
        };
        var text = this.add.text(this.game.world.centerX, this.game.world.centerY, message, style);
        text.anchor.set(0.5);
    }

    update() {
        if (this.game.global.controlSettings.isPressingX()) {
            this.restartGame();
        }
    }

    restartGame() {
        this.game.state.start('menu');
    }

    shutdown() {
        if (!!this.xButton) {
            this.xButton.onDown.removeAll();
        }
        this.music.stop();
    }

}

export default Menu;
<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular
        .module('mutant-ng-translate')
        .factory('$translateStorageSvc', ['$translateStorage', '$translateCache', '$translateEvents', translateStorageSvc]);

    function translateStorageSvc($translateStorage, $translateCache, $translateEvents) {
        var self = this;

        self.config = config;
        self.options = undefined;

        self.cache = {
            get: {
                language: cacheGetLanguage,
                translations: cacheGetTranslations
            },
            set: {
                language: cacheSetLanguage,
                translations: cacheSetTranslations
            }
        };

        self.storage = {
            get: {
                language: storageGetLanguage,
                translations: storageGetTranslations,
                translation: storageGetTranslation
            },
            set: {
                language: storageSetLanguage,
                translations: storageSetTranslations
            }
        };

        self.setTranslations = setTranslations;
        self.getTranslations = getTranslations;
        self.getTranslation = getTranslation;

        self.setLanguage = setLanguage;
        self.getLanguage = getLanguage;

        return self;

        /* CONFIG */
        function config(options) {
            self.options = options;

            var lang = self.cache.get.language();
            var translations = self.cache.get.translations(lang);

            self.storage.set.language(lang);
            self.storage.set.translations(lang, translations);
        }

        /* TRANSLATIONS */
        function setTranslations(lang, values) {
            self.storage.set.translations(lang, values);
            self.cache.set.translations(lang, values);

            $translateEvents.translationsUpdated.publish({ lang: lang });
        }

        function getTranslations(lang) {
            return self.storage.get.translations(lang);
        }

        function getTranslation(lang, key) {
            return self.storage.get.translation(lang, key);
        }

        /* LANGUAGE */
        function setLanguage(lang) {
            var oldLang = self.storage.get.language();

            self.storage.set.language(lang);
            self.cache.set.language(lang);

            if (!$translateStorage.exists(lang)) {
                var translations = self.cache.get.translations(lang);
                self.storage.set.translations(lang, translations);
            }

            $translateEvents.languageChanged.publish({ from: oldLang, to: lang });
        }

        function getLanguage() {
            return self.storage.get.language();
        }

        /* CACHE */
        function cacheGetLanguage() {
            var lang = undefined;

            if (self.options.cacheSelectedLang) {
                lang = $translateCache.getLang();
            }

            if (!lang) {
                lang = self.options.defaultLang;
            }

            return lang;
        }

        function cacheSetLanguage() {
            if (!self.options.cacheSelectedLang) return;

            $translateCache.setLang(lang);
        }

        function cacheGetTranslations(lang) {
            if (!self.options.cacheTranslations) return {};

            return $translateCache.getValues(lang);
        }

        function cacheSetTranslations(lang, values) {
            if (!self.options.cacheTranslations) return;

            $translateCache.setValues(lang, values);
        }

        /* STORAGE */
        function storageGetLanguage() {
            return self.options.lang;
        }

        function storageSetLanguage(lang) {
            self.options.lang = lang;
        }

        function storageGetTranslations(lang) {
            return $translateStorage.getValues(lang);
        }

        function storageGetTranslation(lang, key) {
            return $translateStorage.getValue(lang, key);
        }

        function storageSetTranslations(lang, values) {
            $translateStorage.setValues(lang, values);
        }
    }
})();<commit_msg>hotfix of storage service<commit_after>(function() {
    'use strict';

    angular
        .module('mutant-ng-translate')
        .factory('$translateStorageSvc', ['$translateStorage', '$translateCache', '$translateEvents', translateStorageSvc]);

    function translateStorageSvc($translateStorage, $translateCache, $translateEvents) {
        var self = this;

        self.config = config;
        self.options = undefined;

        self.cache = {
            get: {
                language: cacheGetLanguage,
                translations: cacheGetTranslations
            },
            set: {
                language: cacheSetLanguage,
                translations: cacheSetTranslations
            }
        };

        self.storage = {
            get: {
                language: storageGetLanguage,
                translations: storageGetTranslations,
                translation: storageGetTranslation
            },
            set: {
                language: storageSetLanguage,
                translations: storageSetTranslations
            }
        };

        self.setTranslations = setTranslations;
        self.getTranslations = getTranslations;
        self.getTranslation = getTranslation;

        self.setLanguage = setLanguage;
        self.getLanguage = getLanguage;

        return self;

        /* CONFIG */
        function config(options) {
            self.options = options;

            var lang = self.cache.get.language();
            var translations = self.cache.get.translations(lang);

            self.storage.set.language(lang);
            self.storage.set.translations(lang, translations);
        }

        /* TRANSLATIONS */
        function setTranslations(lang, values) {
            self.storage.set.translations(lang, values);
            self.cache.set.translations(lang, values);

            $translateEvents.translationsUpdated.publish({ lang: lang });
        }

        function getTranslations(lang) {
            return self.storage.get.translations(lang);
        }

        function getTranslation(lang, key) {
            return self.storage.get.translation(lang, key);
        }

        /* LANGUAGE */
        function setLanguage(lang) {
            var oldLang = self.storage.get.language();

            self.storage.set.language(lang);
            self.cache.set.language(lang);

            if (!$translateStorage.exists(lang)) {
                var translations = self.cache.get.translations(lang);
                self.storage.set.translations(lang, translations);
            }

            $translateEvents.languageChanged.publish({ from: oldLang, to: lang });
        }

        function getLanguage() {
            return self.storage.get.language();
        }

        /* CACHE */
        function cacheGetLanguage() {
            var lang = undefined;

            if (self.options.cacheSelectedLang) {
                lang = $translateCache.getLang();
            }

            if (!lang) {
                lang = self.options.defaultLang;
            }

            return lang;
        }

        function cacheSetLanguage(lang) {
            if (!self.options.cacheSelectedLang) return;

            $translateCache.setLang(lang);
        }

        function cacheGetTranslations(lang) {
            if (!self.options.cacheTranslations) return {};

            return $translateCache.getValues(lang);
        }

        function cacheSetTranslations(lang, values) {
            if (!self.options.cacheTranslations) return;

            $translateCache.setValues(lang, values);
        }

        /* STORAGE */
        function storageGetLanguage() {
            return self.options.lang;
        }

        function storageSetLanguage(lang) {
            self.options.lang = lang;
        }

        function storageGetTranslations(lang) {
            return $translateStorage.getValues(lang);
        }

        function storageGetTranslation(lang, key) {
            return $translateStorage.getValue(lang, key);
        }

        function storageSetTranslations(lang, values) {
            $translateStorage.setValues(lang, values);
        }
    }
})();<|endoftext|>


<commit_before>import { EventEmitter } from 'events';
import assign from 'object-assign';
import { isArray, isEmpty, isObject, isFunction } from 'lodash/lang';
import { defer } from 'lodash/function';
import intersection from 'lodash/array/intersection';
import capitalize from 'lodash/string/capitalize';
import Immutable from 'immutable';
import AppDispatcher from '../dispatcher';

const reservedNames = ["Error", "Status"];

const _instances = [];

/**
* @class CoreStore
*/
class CoreStore extends EventEmitter {

    /**
    * Contructor of the store class.
    */
    constructor(config) {
        super();
        assign(this, {
            config
        });
        //Initialize the data as immutable map.
        this.data = Immutable.Map({});
        this.status = Immutable.Map({});
        this.error = Immutable.Map({});
        this.pendingEvents = [];
        this.customHandler = assign({}, config.customHandler);
        //Register all gernerated methods.
        this.buildDefinition();
        this.buildEachNodeChangeEventListener();
        this.registerDispatcher();
        if (!!__DEV__) {
            this._registerDevTools();
        }
    }
    // Get all the instances of core store.
    get _instances() {
        return [..._instances];
    }
    // register the instances saving
    _registerDevTools() {
        _instances.push(this);
    }
    /**
    * Initialize the store configuration.
    * @param {object} storeConfiguration - The store configuration for the initialization.
    */
    buildDefinition() {
        /**
        * Build the definitions for the entity (may be a subject.)
        * @type {object}
        */
        if (!this.config.definition) {
            throw new Error('Core Store: missing definition', this.config);
        }
        this.definition = this.config.definition;

        const properties = Object.keys(this.definition).map(elt => capitalize(elt));
        const reservedProperties = properties.reduce((acc, elt) => acc.concat(reservedNames.map(w => w + elt)), []);
        if (intersection(properties, reservedProperties).length > 0) {
            throw new Error(`You have a name collision into this store : you cannot use a node named Blabla and anoter named ErrorBlabla, or StatusBlabla : ${intersection(properties, reservedProperties).join(' ')} `);
        }
        return this.definition;
    }
    /**
    * Get the whole value of the
    * @return {[type]} [description]
    */
    getValue() {
        return this.data ? this.data.toJS() : {};
    }
    /**
    * Getter on the identifier property.
    * @return {string} - Store identifier.
    */
    get identifier() {
        return this.config && this.config.identifier ? this.config.identifier : undefined;
    }
    /** Return the status of a definition.
    * @param {string} - The definition to load.
    * @returns {string} - The status of a definition.
    */
    getStatus(def) {
        if (this.status.has(def)) {
            return this.status.get(def);
        }
        return undefined;
    }
    /**
    * Emit all events pending in the pendingEvents map.
    */
    emitPendingEvents() {
        this.pendingEvents.map((evtToEmit) => {
            let { name, data } = evtToEmit;
            this.emit(name, data);
        });
    }

    /**
    * Replace the emit function with a willEmit in otder to store the changing event but send it afterwards.
    * @param eventName {string} - The event name.
    * @param  data {object} - The event's associated data.
    */
    willEmit(eventName, data) {
        this.pendingEvents = this.pendingEvents.reduce((result, current) => {
            if (current.name !== eventName) {
                result.push(current);
            }
            return result;
        }, [{ name: eventName, data: data }]);
    }

    /**
    * Clear all pending events.
    */
    clearPendingEvents() {
        this.pendingEvents = [];
    }
    /**
    * Build a change listener for each property in the definition. (should be macro entities);
    */
    buildEachNodeChangeEventListener() {
        const currentStore = this;
        //Loop through each store properties.
        for (let definition in this.definition) {
            const capitalizeDefinition = capitalize(definition);
            //Creates the change listener
            currentStore[`add${capitalizeDefinition}ChangeListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:change`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}ChangeListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:change`, cb);
                }
            }(definition);
            //Create an update method.
            //Should be named updateData to be more explicit
            if (currentStore[`update${capitalizeDefinition}`] === undefined) {
                currentStore[`update${capitalizeDefinition}`] = function (def) {
                    return function (dataNode, status, informations) {
                        const immutableNode = isFunction(dataNode) ? dataNode : Immutable.fromJS(dataNode);
                        currentStore.data = currentStore.data.set(def, immutableNode);
                        //Update the status on the data.
                        currentStore.status = currentStore.status.set(def, status);

                        currentStore.willEmit(`${def}:change`, { property: def, status: status, informations: informations });
                    }
                }(definition);
            }

            //Create a get method.
            if (currentStore[`get${capitalizeDefinition}`] === undefined) {
                currentStore[`get${capitalizeDefinition}`] = function (def) {
                    return function () {
                        const hasData = currentStore.data.has(def);
                        if (hasData) {
                            const rawData = currentStore.data.get(def);
                            if (rawData && rawData.toJS) {
                                const data = rawData.toJS();
                                return data;
                            }
                            return rawData;
                        }
                        return undefined;
                    };
                }(definition);
            }
            //Creates the error change listener
            currentStore[`add${capitalizeDefinition}ErrorListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:error`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}ErrorListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:error`, cb);
                }
            }(definition);
            //Create an update method.
            currentStore[`updateError${capitalizeDefinition}`] = function (def) {
                return function (dataNode, status, informations) {
                    //CheckIsObject
                    const immutableNode = Immutable[isArray(dataNode) ? "List" : "Map"](dataNode);
                    currentStore.error = currentStore.error.set(def, immutableNode);
                    currentStore.status = currentStore.status.set(def, status);
                    currentStore.willEmit(`${def}:error`, { property: def, status: status, informations: informations });
                }
            }(definition);
            //Create a get method.
            currentStore[`getError${capitalizeDefinition}`] = function (def) {
                return function () {
                    const hasData = currentStore.error.has(def);
                    return hasData ? currentStore.error.get(def).toJS() : undefined;
                };
            }(definition);

            // status
            currentStore[`add${capitalizeDefinition}StatusListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:status`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}StatusListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:status`, cb);
                }
            }(definition);
            //Create an update method.
            currentStore[`updateStatus${capitalizeDefinition}`] = function (def) {
                return function updateStatus(dataNode, status, informations) {
                    //CheckIsObject
                    //console.log(`status  ${JSON.stringify(status) }`);
                    const statusNode = status;//Immutable.fromJS(status); // mMaybe it is a part of the status only.
                    currentStore.status = currentStore.status.set(def, statusNode);
                    currentStore.willEmit(`${def}:status`, { property: def, status: status, informations: informations });
                }
            }(definition);
            //Create a get method.
            currentStore[`getStatus${capitalizeDefinition}`] = function (def) {
                return function getStatus() {
                    const hasData = currentStore.status.has(def);
                    const data = hasData ? currentStore.status.get(def) : undefined;
                    return data.toJS ? data.toJS() : data;
                };
            }(definition);
        }
    }

    delayPendingEvents(context) {
        //Delay all the change emit by the store to be sure it is done after the internal store propagation and to go out of the dispatch function.
        defer(() => {
            context.emitPendingEvents();
            context.clearPendingEvents();
        });
    }
    _buildInformations(incomingInfos) {
        return {
            callerId: incomingInfos.action.callerId
        };
    }
    /**
    * The store registrer itself on the dispatcher.
    */
    registerDispatcher() {
        const currentStore = this;
        this.dispatch = AppDispatcher.register(function (transferInfo) {
            //Check if an identifier check is necessary.
            if (currentStore.identifier) {
                //If an identifier is needed a check is triggered.
                if (!transferInfo || !transferInfo.action || !transferInfo.action.identifier || transferInfo.action.identifier !== currentStore.identifier) {
                    return;
                }
            }
            //currentStore.clearPendingEvents();
            if (currentStore.globalCustomHandler) {
                return currentStore.globalCustomHandler.call(currentStore, transferInfo);
            }

            //Read data from the action transfer information.
            const rawData = transferInfo.action.data;
            const status = transferInfo.action.status || {};
            const type = transferInfo.action.type;
            const otherInformations = currentStore._buildInformations(transferInfo);

            //Call each node handler for the matching definition's node.
            for (let node in rawData) {
                if (currentStore.definition[node]) {
                    //Call a custom handler if this exists.
                    if (currentStore.customHandler && currentStore.customHandler[node] && currentStore.customHandler[node][type]) {
                        currentStore.customHandler[node][type].call(currentStore, rawData[node], status[node], otherInformations);
                    } else {
                        //Update the data for the given node. and emit the change/.
                        if (!isFunction(currentStore[`${type}${capitalize(node)}`])) {
                            throw new Error(`The listener you try to call is unavailable : ${type} ${capitalize(node)} `);
                        }
                        currentStore[`${type} ${capitalize(node)} `](rawData[node], status[node], otherInformations);
                    }
                }
            }
            currentStore.delayPendingEvents(currentStore);
        });
    }
    /**
    * Add a listener on a store event.
    * @param {string}   eventName - Event name.
    * @param {Function} cb - CallBack to call on the event change name.
    */
    addListener(eventName, cb) {
        this.on(eventName, cb);
    }
}
export default CoreStore;
<commit_msg>Fix Critical mistake<commit_after>import { EventEmitter } from 'events';
import assign from 'object-assign';
import { isArray, isEmpty, isObject, isFunction } from 'lodash/lang';
import { defer } from 'lodash/function';
import intersection from 'lodash/array/intersection';
import capitalize from 'lodash/string/capitalize';
import Immutable from 'immutable';
import AppDispatcher from '../dispatcher';

const reservedNames = ["Error", "Status"];

const _instances = [];

/**
* @class CoreStore
*/
class CoreStore extends EventEmitter {

    /**
    * Contructor of the store class.
    */
    constructor(config) {
        super();
        assign(this, {
            config
        });
        //Initialize the data as immutable map.
        this.data = Immutable.Map({});
        this.status = Immutable.Map({});
        this.error = Immutable.Map({});
        this.pendingEvents = [];
        this.customHandler = assign({}, config.customHandler);
        //Register all gernerated methods.
        this.buildDefinition();
        this.buildEachNodeChangeEventListener();
        this.registerDispatcher();
        if (!!__DEV__) {
            this._registerDevTools();
        }
    }
    // Get all the instances of core store.
    get _instances() {
        return [..._instances];
    }
    // register the instances saving
    _registerDevTools() {
        _instances.push(this);
    }
    /**
    * Initialize the store configuration.
    * @param {object} storeConfiguration - The store configuration for the initialization.
    */
    buildDefinition() {
        /**
        * Build the definitions for the entity (may be a subject.)
        * @type {object}
        */
        if (!this.config.definition) {
            throw new Error('Core Store: missing definition', this.config);
        }
        this.definition = this.config.definition;

        const properties = Object.keys(this.definition).map(elt => capitalize(elt));
        const reservedProperties = properties.reduce((acc, elt) => acc.concat(reservedNames.map(w => w + elt)), []);
        if (intersection(properties, reservedProperties).length > 0) {
            throw new Error(`You have a name collision into this store : you cannot use a node named Blabla and anoter named ErrorBlabla, or StatusBlabla : ${intersection(properties, reservedProperties).join(' ')} `);
        }
        return this.definition;
    }
    /**
    * Get the whole value of the
    * @return {[type]} [description]
    */
    getValue() {
        return this.data ? this.data.toJS() : {};
    }
    /**
    * Getter on the identifier property.
    * @return {string} - Store identifier.
    */
    get identifier() {
        return this.config && this.config.identifier ? this.config.identifier : undefined;
    }
    /** Return the status of a definition.
    * @param {string} - The definition to load.
    * @returns {string} - The status of a definition.
    */
    getStatus(def) {
        if (this.status.has(def)) {
            return this.status.get(def);
        }
        return undefined;
    }
    /**
    * Emit all events pending in the pendingEvents map.
    */
    emitPendingEvents() {
        this.pendingEvents.map((evtToEmit) => {
            let { name, data } = evtToEmit;
            this.emit(name, data);
        });
    }

    /**
    * Replace the emit function with a willEmit in otder to store the changing event but send it afterwards.
    * @param eventName {string} - The event name.
    * @param  data {object} - The event's associated data.
    */
    willEmit(eventName, data) {
        this.pendingEvents = this.pendingEvents.reduce((result, current) => {
            if (current.name !== eventName) {
                result.push(current);
            }
            return result;
        }, [{ name: eventName, data: data }]);
    }

    /**
    * Clear all pending events.
    */
    clearPendingEvents() {
        this.pendingEvents = [];
    }
    /**
    * Build a change listener for each property in the definition. (should be macro entities);
    */
    buildEachNodeChangeEventListener() {
        const currentStore = this;
        //Loop through each store properties.
        for (let definition in this.definition) {
            const capitalizeDefinition = capitalize(definition);
            //Creates the change listener
            currentStore[`add${capitalizeDefinition}ChangeListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:change`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}ChangeListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:change`, cb);
                }
            }(definition);
            //Create an update method.
            //Should be named updateData to be more explicit
            if (currentStore[`update${capitalizeDefinition}`] === undefined) {
                currentStore[`update${capitalizeDefinition}`] = function (def) {
                    return function (dataNode, status, informations) {
                        const immutableNode = isFunction(dataNode) ? dataNode : Immutable.fromJS(dataNode);
                        currentStore.data = currentStore.data.set(def, immutableNode);
                        //Update the status on the data.
                        currentStore.status = currentStore.status.set(def, status);

                        currentStore.willEmit(`${def}:change`, { property: def, status: status, informations: informations });
                    }
                }(definition);
            }

            //Create a get method.
            if (currentStore[`get${capitalizeDefinition}`] === undefined) {
                currentStore[`get${capitalizeDefinition}`] = function (def) {
                    return function () {
                        const hasData = currentStore.data.has(def);
                        if (hasData) {
                            const rawData = currentStore.data.get(def);
                            if (rawData && rawData.toJS) {
                                const data = rawData.toJS();
                                return data;
                            }
                            return rawData;
                        }
                        return undefined;
                    };
                }(definition);
            }
            //Creates the error change listener
            currentStore[`add${capitalizeDefinition}ErrorListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:error`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}ErrorListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:error`, cb);
                }
            }(definition);
            //Create an update method.
            currentStore[`updateError${capitalizeDefinition}`] = function (def) {
                return function (dataNode, status, informations) {
                    //CheckIsObject
                    const immutableNode = Immutable[isArray(dataNode) ? "List" : "Map"](dataNode);
                    currentStore.error = currentStore.error.set(def, immutableNode);
                    currentStore.status = currentStore.status.set(def, status);
                    currentStore.willEmit(`${def}:error`, { property: def, status: status, informations: informations });
                }
            }(definition);
            //Create a get method.
            currentStore[`getError${capitalizeDefinition}`] = function (def) {
                return function () {
                    const hasData = currentStore.error.has(def);
                    return hasData ? currentStore.error.get(def).toJS() : undefined;
                };
            }(definition);

            // status
            currentStore[`add${capitalizeDefinition}StatusListener`] = function (def) {
                return function (cb) {
                    currentStore.addListener(`${def}:status`, cb);
                }
            }(definition);
            //Remove the change listener
            currentStore[`remove${capitalizeDefinition}StatusListener`] = function (def) {
                return function (cb) {
                    currentStore.removeListener(`${def}:status`, cb);
                }
            }(definition);
            //Create an update method.
            currentStore[`updateStatus${capitalizeDefinition}`] = function (def) {
                return function updateStatus(dataNode, status, informations) {
                    //CheckIsObject
                    //console.log(`status  ${JSON.stringify(status) }`);
                    const statusNode = status;//Immutable.fromJS(status); // mMaybe it is a part of the status only.
                    currentStore.status = currentStore.status.set(def, statusNode);
                    currentStore.willEmit(`${def}:status`, { property: def, status: status, informations: informations });
                }
            }(definition);
            //Create a get method.
            currentStore[`getStatus${capitalizeDefinition}`] = function (def) {
                return function getStatus() {
                    const hasData = currentStore.status.has(def);
                    const data = hasData ? currentStore.status.get(def) : undefined;
                    return data.toJS ? data.toJS() : data;
                };
            }(definition);
        }
    }

    delayPendingEvents(context) {
        //Delay all the change emit by the store to be sure it is done after the internal store propagation and to go out of the dispatch function.
        defer(() => {
            context.emitPendingEvents();
            context.clearPendingEvents();
        });
    }
    _buildInformations(incomingInfos) {
        return {
            callerId: incomingInfos.action.callerId
        };
    }
    /**
    * The store registrer itself on the dispatcher.
    */
    registerDispatcher() {
        const currentStore = this;
        this.dispatch = AppDispatcher.register(function (transferInfo) {
            //Check if an identifier check is necessary.
            if (currentStore.identifier) {
                //If an identifier is needed a check is triggered.
                if (!transferInfo || !transferInfo.action || !transferInfo.action.identifier || transferInfo.action.identifier !== currentStore.identifier) {
                    return;
                }
            }
            //currentStore.clearPendingEvents();
            if (currentStore.globalCustomHandler) {
                return currentStore.globalCustomHandler.call(currentStore, transferInfo);
            }

            //Read data from the action transfer information.
            const rawData = transferInfo.action.data;
            const status = transferInfo.action.status || {};
            const type = transferInfo.action.type;
            const otherInformations = currentStore._buildInformations(transferInfo);

            //Call each node handler for the matching definition's node.
            for (let node in rawData) {
                if (currentStore.definition[node]) {
                    //Call a custom handler if this exists.
                    if (currentStore.customHandler && currentStore.customHandler[node] && currentStore.customHandler[node][type]) {
                        currentStore.customHandler[node][type].call(currentStore, rawData[node], status[node], otherInformations);
                    } else {
                        //Update the data for the given node. and emit the change/.
                        if (!isFunction(currentStore[`${type}${capitalize(node)}`])) {
                            throw new Error(`The listener you try to call is unavailable : ${type} ${capitalize(node)} `);
                        }
                        currentStore[`${type}${capitalize(node)}`](rawData[node], status[node], otherInformations);
                    }
                }
            }
            currentStore.delayPendingEvents(currentStore);
        });
    }
    /**
    * Add a listener on a store event.
    * @param {string}   eventName - Event name.
    * @param {Function} cb - CallBack to call on the event change name.
    */
    addListener(eventName, cb) {
        this.on(eventName, cb);
    }
}
export default CoreStore;
<|endoftext|>


<commit_before>let Promise
try {
  Promise = require('bluebird')
} catch (err) {
  Promise = global.Promise
}

const { delay: promDelay } = require('../util')

/**
 * Built-in base helper class
 * @abstract
 * @prop {?Logger} logger Logger instance
 * @prop {?Interpreter} i18n Interpreter instance
 */
class Base {
  /**
   * Creates a new Base instance
   * @arg {Client} client Client instance
   */
  constructor (client) {
    this._client = client
    this.logger = client.logger
    this.i18n = client.plugins.get('i18n')
  }

  /**
   * Checks if a user has certain permissions in a channel
   * @arg {external:"Eris.GuildChannel"} channel The channel to check in
   * @arg {external:"Eris.User"} user The user to check
   * @arg {...String} perms The permission(s) to check
   * @returns {Boolean}
   */
  hasPermissions (channel, user, ...perms) {
    if (!channel.guild) return true
    const member = channel.guild.members.get(user.id)

    if (!perms.every(p => member.permission.has(p))) return false
    return perms.every(perm =>
      !channel.permissionOverwrites.find(p => (member.roles.includes(p.id) || p.id === user.id) && p.json[perm] === false)
    )
  }

  /**
   * Parses a string for localisation
   * @arg {String} content The string to parse
   * @arg {String} [lang='en'] The locale name
   * @arg {Object} [tags] Additional interpolation tags
   */
  t (content = '', lang = 'en', tags = {}) {
    if (!this.i18n) return content
    const file = this.name ? this.name.split(':')[0] : (this.labels ? this.labels[0] : 'common')
    return this.i18n.parse(content, this.localeKey || file || null, lang, tags)
  }

  /**
   * Sends a message to a channel
   * @arg {external:"Eris.GuildChannel"} channel The channel to send the message in
   * @arg {String} content The string to send
   * @arg {Object} [options] Message options
   * @arg {String} [options.lang] Message locale
   * @arg {Number} [options.delay=0] Delay to send the message, set to 0 for no delay
   * @arg {Number} [options.deleteDelay=0] Delay to delete the message after it's sent, set to 0 for no deletion
   * @arg {Object} [options.file] A file object
   * @arg {String} [options.file.name] Name of file
   * @arg {Buffer} [options.file.file] Buffer containing file data
   * @arg {Object} [options.embed] Embed object, see {@link https://discordapp.com/developers/docs/resources/channel#embed-object|official Discord API documentation}
   * @returns {Promise.<external:"Eris.Message"|null>}
   */
  async send (chan, content, options = {}) {
    const channel = typeof chan === 'string' ? this._client.getChannel(chan) : chan
    if (!channel) {
      const err = new Error(`Could not send message: Invalid channel - ${chan}`)
      if (this.logger) this.logger.error(err)
      throw err
    }

    let { file = null, lang, delay = 0, deleteDelay = 0, embed } = options
    if (channel.guild && !this.hasPermissions(channel, this._client.user, 'sendMessages')) {
      const err = new Error('Could not send message: Insufficient permissions')
      if (this.logger) this.logger.error(err)
    }

    if (delay) await promDelay(delay)

    if (Array.isArray(content)) content = content.join('\n')
    if (this.i18n) content = this.t(content, lang, options)
    content = content.match(/(.|[\r\n]){1,2000}/g)

    try {
      if (!content || !content.length) {
        const msg = await channel.createMessage({ embed, content: '' }, file)
        return deleteDelay ? promDelay(deleteDelay).then(() => msg.delete()) : msg
      }

      let msg
      for (const c of content) {
        const firstMsg = await channel.createMessage(!msg ? { embed, content: c } : c, !msg ? file : null)
        .then(msg => deleteDelay ? promDelay(deleteDelay).then(() => msg.delete()) : msg)
        msg = firstMsg
      }

      return msg
    } catch (err) {
      if (this.logger) this.logger.error('Could not send message -', err)
      throw err
    }
  }

  /**
   * Edits a message with updated content
   * @arg {external:"Eris.Message"} message The message to edit
   * @arg {String} content The content to edit the message with
   * @arg {Object} [options] Options object
   * @arg {String} [options.lang] Locale of content
   * @arg {Number} [options.delay] Delay to edit the message
   * @returns {Promise}
   */
  edit (msg, content, options) {
    const { lang, delay = 0 } = options

    if (Array.isArray(content)) content = content.join('\n')
    if (this.i18n) content = this.t(content, lang, options)

    return (delay ? promDelay(delay) : Promise.resolve()).then(() => msg.edit(content))
  }

  /**
   * Deletes multiple messages if there are sufficient permissions
   * @arg {...external:"Eris.Message"} messages The messages to delete
   * @returns {Promise}
   */
  deleteMessages (...msgs) {
    const id = this._client.user.id
    return Promise.all(msgs.reduce((arr, msg) => {
      if (!msg || !msg.channel.guild) return arr
      if (msg.author.id === id || this.hasPermissions(msg.channel, msg.member, 'manageMessages')) {
        arr.push(msg.delete())
      }
      return arr
    }, []))
  }
}

module.exports = Base
<commit_msg>Fix permission checking<commit_after>let Promise
try {
  Promise = require('bluebird')
} catch (err) {
  Promise = global.Promise
}

const { delay: promDelay } = require('../util')

/**
 * Built-in base helper class
 * @abstract
 * @prop {?Logger} logger Logger instance
 * @prop {?Interpreter} i18n Interpreter instance
 */
class Base {
  /**
   * Creates a new Base instance
   * @arg {Client} client Client instance
   */
  constructor (client) {
    this._client = client
    this.logger = client.logger
    this.i18n = client.plugins.get('i18n')
  }

  /**
   * Checks if a user has certain permissions in a channel
   * @arg {external:"Eris.GuildChannel"} channel The channel to check in
   * @arg {external:"Eris.User"} user The user to check
   * @arg {...String} perms The permission(s) to check
   * @returns {Boolean}
   */
  hasPermissions (channel, user, ...perms) {
    if (!channel.guild) return true
    const member = channel.guild.members.get(user.id)
    const role_everyone = channel.guild.roles.get(channel.guild.id)

    if (!perms.every(p => member.permission.has(p))) return false
    return perms.every(perm =>
      !channel.permissionOverwrites.find(p => (member.roles.includes(p.id) || p.id === user.id || p.id === role_everyone.id) && p.json[perm] === false)
    )
  }

  /**
   * Parses a string for localisation
   * @arg {String} content The string to parse
   * @arg {String} [lang='en'] The locale name
   * @arg {Object} [tags] Additional interpolation tags
   */
  t (content = '', lang = 'en', tags = {}) {
    if (!this.i18n) return content
    const file = this.name ? this.name.split(':')[0] : (this.labels ? this.labels[0] : 'common')
    return this.i18n.parse(content, this.localeKey || file || null, lang, tags)
  }

  /**
   * Sends a message to a channel
   * @arg {external:"Eris.GuildChannel"} channel The channel to send the message in
   * @arg {String} content The string to send
   * @arg {Object} [options] Message options
   * @arg {String} [options.lang] Message locale
   * @arg {Number} [options.delay=0] Delay to send the message, set to 0 for no delay
   * @arg {Number} [options.deleteDelay=0] Delay to delete the message after it's sent, set to 0 for no deletion
   * @arg {Object} [options.file] A file object
   * @arg {String} [options.file.name] Name of file
   * @arg {Buffer} [options.file.file] Buffer containing file data
   * @arg {Object} [options.embed] Embed object, see {@link https://discordapp.com/developers/docs/resources/channel#embed-object|official Discord API documentation}
   * @returns {Promise.<external:"Eris.Message"|null>}
   */
  async send (chan, content, options = {}) {
    const channel = typeof chan === 'string' ? this._client.getChannel(chan) : chan
    if (!channel) {
      const err = new Error(`Could not send message: Invalid channel - ${chan}`)
      if (this.logger) this.logger.error(err)
      throw err
    }

    let { file = null, lang, delay = 0, deleteDelay = 0, embed } = options
    if (channel.guild && !this.hasPermissions(channel, this._client.user, 'sendMessages')) {
      const err = new Error('Could not send message: Insufficient permissions')
      if (this.logger) this.logger.error(err)
    }

    if (delay) await promDelay(delay)

    if (Array.isArray(content)) content = content.join('\n')
    if (this.i18n) content = this.t(content, lang, options)
    content = content.match(/(.|[\r\n]){1,2000}/g)

    try {
      if (!content || !content.length) {
        const msg = await channel.createMessage({ embed, content: '' }, file)
        return deleteDelay ? promDelay(deleteDelay).then(() => msg.delete()) : msg
      }

      let msg
      for (const c of content) {
        const firstMsg = await channel.createMessage(!msg ? { embed, content: c } : c, !msg ? file : null)
        .then(msg => deleteDelay ? promDelay(deleteDelay).then(() => msg.delete()) : msg)
        msg = firstMsg
      }

      return msg
    } catch (err) {
      if (this.logger) this.logger.error('Could not send message -', err)
      throw err
    }
  }

  /**
   * Edits a message with updated content
   * @arg {external:"Eris.Message"} message The message to edit
   * @arg {String} content The content to edit the message with
   * @arg {Object} [options] Options object
   * @arg {String} [options.lang] Locale of content
   * @arg {Number} [options.delay] Delay to edit the message
   * @returns {Promise}
   */
  edit (msg, content, options) {
    const { lang, delay = 0 } = options

    if (Array.isArray(content)) content = content.join('\n')
    if (this.i18n) content = this.t(content, lang, options)

    return (delay ? promDelay(delay) : Promise.resolve()).then(() => msg.edit(content))
  }

  /**
   * Deletes multiple messages if there are sufficient permissions
   * @arg {...external:"Eris.Message"} messages The messages to delete
   * @returns {Promise}
   */
  deleteMessages (...msgs) {
    const id = this._client.user.id
    return Promise.all(msgs.reduce((arr, msg) => {
      if (!msg || !msg.channel.guild) return arr
      if (msg.author.id === id || this.hasPermissions(msg.channel, msg.member, 'manageMessages')) {
        arr.push(msg.delete())
      }
      return arr
    }, []))
  }
}

module.exports = Base
<|endoftext|>


<commit_before>const config = require('./vue/dist/UIconfig');

const koa = require('koa');
const serve = require('koa-static');
const cors = require('koa-cors');
const _ = require('lodash');
const bodyParser = require('koa-bodyparser');

const opn = require('opn');
const server = require('http').createServer();
const router = require('koa-router')();
const ws = require('ws');
const app = koa();

const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ server: server });

const cache = require('./state/cache');

const nodeCommand = _.last(process.argv[1].split('/'));
const isDevServer = nodeCommand === 'server' || nodeCommand === 'server.js';

wss.on('connection', ws => {
  ws.isAlive = true;
  ws.on('pong', () => {
    ws.isAlive = true;
  });
  ws.ping(_.noop);
});

setInterval(() => {
  wss.clients.forEach(ws => {
    if(!ws.isAlive) {
      console.log(new Date, '[WS] stale websocket client, terminiating..');
      return ws.terminate();
    }

    ws.isAlive = false;
    ws.ping(_.noop);
  });
}, 10 * 1000);

// broadcast function
const broadcast = data => {
  if(_.isEmpty(data)) {
    return;
  }

  const payload = JSON.stringify(data);

  wss.clients.forEach(ws => {
    ws.send(payload, err => {
      if(err) {
        console.log(new Date, '[WS] unable to send data to client:', err);
      }
    });
  }
  );
}
cache.set('broadcast', broadcast);

const ListManager = require('./state/listManager');
const GekkoManager = require('./state/gekkoManager');

// initialize lists and dump into cache
cache.set('imports', new ListManager);
cache.set('gekkos', new GekkoManager);
cache.set('apiKeyManager', require('./apiKeyManager'));

// setup API routes

const WEBROOT = __dirname + '/';
const ROUTE = n => WEBROOT + 'routes/' + n;

// attach routes
const apiKeys = require(ROUTE('apiKeys'));
router.get('/api/info', require(ROUTE('info')));
router.get('/api/strategies', require(ROUTE('strategies')));
router.get('/api/configPart/:part', require(ROUTE('configPart')));
router.get('/api/apiKeys', apiKeys.get);

const listWraper = require(ROUTE('list'));
router.get('/api/imports', listWraper('imports'));
router.get('/api/gekkos', listWraper('gekkos'));
router.get('/api/exchanges', require(ROUTE('exchanges')));

router.post('/api/addApiKey', apiKeys.add);
router.post('/api/removeApiKey', apiKeys.remove);
router.post('/api/scan', require(ROUTE('scanDateRange')));
router.post('/api/scansets', require(ROUTE('scanDatasets')));
router.post('/api/backtest', require(ROUTE('backtest')));
router.post('/api/import', require(ROUTE('import')));
router.post('/api/startGekko', require(ROUTE('startGekko')));
router.post('/api/stopGekko', require(ROUTE('stopGekko')));
router.post('/api/deleteGekko', require(ROUTE('deleteGekko')));
router.post('/api/getCandles', require(ROUTE('getCandles')));

// incoming WS:
// wss.on('connection', ws => {
//   ws.on('message', _.noop);
// });

app
  .use(cors())
  .use(serve(WEBROOT + 'vue/dist'))
  .use(bodyParser())
  .use(require('koa-logger')())
  .use(router.routes())
  .use(router.allowedMethods());

server.timeout = config.api.timeout || 120000;
server.on('request', app.callback());
server.listen(config.api.port, config.api.host, '::', () => {
  const host = `${config.ui.host}:${config.ui.port}${config.ui.path}`;

  if(config.ui.ssl) {
    var location = `https://${host}`;
  } else {
    var location = `http://${host}`;
  }

  console.log('Serving Gekko UI on ' + location +  '\n');

  // only open a browser when running `node gekko`
  // this prevents opening the browser during development
  if(!isDevServer && !config.headless) {
    opn(location)
      .catch(err => {
        console.log('Something went wrong when trying to open your web browser. UI is running on ' + location + '.');
    });
  }
});
<commit_msg>catch remaining individual socket errors<commit_after>const config = require('./vue/dist/UIconfig');

const koa = require('koa');
const serve = require('koa-static');
const cors = require('koa-cors');
const _ = require('lodash');
const bodyParser = require('koa-bodyparser');

const opn = require('opn');
const server = require('http').createServer();
const router = require('koa-router')();
const ws = require('ws');
const app = koa();

const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ server: server });

const cache = require('./state/cache');

const nodeCommand = _.last(process.argv[1].split('/'));
const isDevServer = nodeCommand === 'server' || nodeCommand === 'server.js';

wss.on('connection', ws => {
  ws.isAlive = true;
  ws.on('pong', () => {
    ws.isAlive = true;
  });
  ws.ping(_.noop);
  ws.on('error', e => {
    console.error(new Date, '[WS] connection error:', e);
  });
});

setInterval(() => {
  wss.clients.forEach(ws => {
    if(!ws.isAlive) {
      console.log(new Date, '[WS] stale websocket client, terminiating..');
      return ws.terminate();
    }

    ws.isAlive = false;
    ws.ping(_.noop);
  });
}, 10 * 1000);

// broadcast function
const broadcast = data => {
  if(_.isEmpty(data)) {
    return;
  }

  const payload = JSON.stringify(data);

  wss.clients.forEach(ws => {
    ws.send(payload, err => {
      if(err) {
        console.log(new Date, '[WS] unable to send data to client:', err);
      }
    });
  }
  );
}
cache.set('broadcast', broadcast);

const ListManager = require('./state/listManager');
const GekkoManager = require('./state/gekkoManager');

// initialize lists and dump into cache
cache.set('imports', new ListManager);
cache.set('gekkos', new GekkoManager);
cache.set('apiKeyManager', require('./apiKeyManager'));

// setup API routes

const WEBROOT = __dirname + '/';
const ROUTE = n => WEBROOT + 'routes/' + n;

// attach routes
const apiKeys = require(ROUTE('apiKeys'));
router.get('/api/info', require(ROUTE('info')));
router.get('/api/strategies', require(ROUTE('strategies')));
router.get('/api/configPart/:part', require(ROUTE('configPart')));
router.get('/api/apiKeys', apiKeys.get);

const listWraper = require(ROUTE('list'));
router.get('/api/imports', listWraper('imports'));
router.get('/api/gekkos', listWraper('gekkos'));
router.get('/api/exchanges', require(ROUTE('exchanges')));

router.post('/api/addApiKey', apiKeys.add);
router.post('/api/removeApiKey', apiKeys.remove);
router.post('/api/scan', require(ROUTE('scanDateRange')));
router.post('/api/scansets', require(ROUTE('scanDatasets')));
router.post('/api/backtest', require(ROUTE('backtest')));
router.post('/api/import', require(ROUTE('import')));
router.post('/api/startGekko', require(ROUTE('startGekko')));
router.post('/api/stopGekko', require(ROUTE('stopGekko')));
router.post('/api/deleteGekko', require(ROUTE('deleteGekko')));
router.post('/api/getCandles', require(ROUTE('getCandles')));

// incoming WS:
// wss.on('connection', ws => {
//   ws.on('message', _.noop);
// });

app
  .use(cors())
  .use(serve(WEBROOT + 'vue/dist'))
  .use(bodyParser())
  .use(require('koa-logger')())
  .use(router.routes())
  .use(router.allowedMethods());

server.timeout = config.api.timeout || 120000;
server.on('request', app.callback());
server.listen(config.api.port, config.api.host, '::', () => {
  const host = `${config.ui.host}:${config.ui.port}${config.ui.path}`;

  if(config.ui.ssl) {
    var location = `https://${host}`;
  } else {
    var location = `http://${host}`;
  }

  console.log('Serving Gekko UI on ' + location +  '\n');

  // only open a browser when running `node gekko`
  // this prevents opening the browser during development
  if(!isDevServer && !config.headless) {
    opn(location)
      .catch(err => {
        console.log('Something went wrong when trying to open your web browser. UI is running on ' + location + '.');
    });
  }
});
<|endoftext|>


<commit_before>import { SubtitleParserBase } from './subtitle-parser-base'
// TODO: full path to node source to avoid webpack issues with ebml@3.0.0 'browser' tag
//       https://github.com/node-ebml/node-ebml/pull/113
import { Decoder } from 'ebml/lib/ebml'

export class SubtitleStream extends SubtitleParserBase {
  constructor (prevInstance) {
    super()

    if (prevInstance instanceof SubtitleStream) {
      prevInstance.once('drain', () => prevInstance.end())

      // copy previous metadata
      this.subtitleTracks = prevInstance.subtitleTracks
      this.timecodeScale = prevInstance.timecodeScale

      // may not be at ebml tag offset
      this.unstable = true
    }

    this.decoder = new Decoder()
    this.decoder.on('data', this._parseEbmlSubtitles.bind(this))
  }

  // passthrough stream: data is intercepted but not transformed
  _transform (chunk, _, callback) {
    if (this.unstable) {
      // the ebml decoder expects to see a tag, so we won't use it until we find a cluster
      for (let i = 0; i < chunk.length - 12; i++) {
        if (chunk[i] === 0x1f && chunk[i + 1] === 0x43 && chunk[i + 2] === 0xb6 && chunk[i + 3] === 0x75) {
          // length of cluster size tag
          const len = 8 - Math.floor(Math.log2(chunk[i + 4]))
          // first tag in cluster is cluster timecode
          if (len < 9 && chunk[i + 4 + len] === 0xe7) {
            // okay this is probably a cluster
            this.unstable = false
            this.decoder.write(chunk.slice(i))
            break
          }
        }
      }
    } else {
      this.decoder.write(chunk)
    }

    callback(null, chunk)
  }
}
<commit_msg>fixes<commit_after>import { SubtitleParserBase } from './subtitle-parser-base'
// TODO: full path to node source to avoid webpack issues with ebml@3.0.0 'browser' tag
//       https://github.com/node-ebml/node-ebml/pull/113
import { Decoder } from 'ebml/lib/ebml'

export class SubtitleStream extends SubtitleParserBase {
  constructor (prevInstance) {
    super()

    if (prevInstance instanceof SubtitleStream) {
      prevInstance.once('drain', () => prevInstance.end())

      // copy previous metadata
      this.subtitleTracks = prevInstance.subtitleTracks
      this.timecodeScale = prevInstance.timecodeScale

      // may not be at ebml tag offset
      this.unstable = true
    }

    this.decoder = new Decoder()
    this.decoder.on('data', this._parseEbmlSubtitles.bind(this))
  }

  // passthrough stream: data is intercepted but not transformed
  _transform (chunk, _, callback) {
    if (this.unstable) {
      // the ebml decoder expects to see a tag, so we won't use it until we find a cluster
      for (let i = 0; i < chunk.length - 12; i++) {
        // cluster id
        if (chunk[i] === 0x1f && chunk[i + 1] === 0x43 && chunk[i + 2] === 0xb6 && chunk[i + 3] === 0x75) {
          // length of cluster size tag
          const len = 8 - Math.floor(Math.log2(chunk[i + 4]))
          // first tag in cluster is cluster timecode
          if (chunk[i + 4 + len] === 0xe7) {
            // okay this is probably a cluster
            this.unstable = false
            this.decoder.write(chunk.slice(i))
            break
          }
        }
      }
    } else {
      this.decoder.write(chunk)
    }

    callback(null, chunk)
  }
}
<|endoftext|>


<commit_before>(function() {
  var ui = {
    r: null,
    g: null,
    b: null
  };

  var connection = -1;

  function initializeWindow() {
    for (var k in ui) {
      var id = k.replace(/([A-Z])/, '-$1').toLowerCase();
      var element = document.getElementById(id);
      if (!element) {
        throw "Missing UI element: " + k;
      }
      ui[k] = element;
    }
    setGradients();
    enableControls(false);
    ui.r.addEventListener('input', onColorChanged);
    ui.g.addEventListener('input', onColorChanged);
    ui.b.addEventListener('input', onColorChanged);
    enumerateDevices();
  };

  function enableControls(enabled) {
    ui.r.disabled = !enabled;
    ui.g.disabled = !enabled;
    ui.b.disabled = !enabled;
  };

  function enumerateDevices() {
    chrome.hid.getDevices(
        { "vendorId": 10168, "productId": 493 },
        onDevicesEnumerated);
  };

  function onDevicesEnumerated(devices) {
    if (!devices) {
      console.warn("Unable to enumerate devices: " +
                   chrome.runtime.lastError.message);
      return;
    }

    chrome.hid.connect(devices[0].deviceId, onDeviceConnected);
  };

  function onDeviceConnected(connectInfo) {
    if (!connectInfo) {
      console.warn("Unable to connect to device: " +
                   chrome.runtime.lastError.message);
    }
    connection = connectInfo.connectionId;
    enableControls(true);
  };

  function fadeRGB(r, g, b, fade_ms, led) {
    // Send a fade command to the blink(1). The command protocol operates over
    // feature reports and is documented here:
    //
    // https://github.com/todbot/blink1/blob/master/docs/blink1-hid-commands.md

    var fade_time = fade_ms / 10;
    var th = (fade_time & 0xff00) >> 8;
    var tl = fade_time & 0x00ff;
    var data = new Uint8Array(8);
    data[0] = 'c'.charCodeAt(0);
    data[1] = r;
    data[2] = g;
    data[3] = b;
    data[4] = th;
    data[5] = tl;
    data[6] = 0;
    chrome.hid.sendFeatureReport(connection, 1, data.buffer, function() {
      if (chrome.runtime.lastError) {
        console.warn("Unable to set feature report: " +
                     chrome.runtime.lastError.message);
      }
    });
  }

  function onColorChanged() {
    setGradients();
    fadeRGB(ui.r.value, ui.g.value, ui.b.value, 250, 0);
  }

  function setGradients() {
    var r = ui.r.value, g = ui.g.value, b = ui.b.value;
    ui.r.style.background =
       'linear-gradient(to right, rgb(0, ' + g + ', ' + b + '), ' +
                                 'rgb(255, ' + g + ', ' + b + '))';
    ui.g.style.background =
       'linear-gradient(to right, rgb(' + r + ', 0, ' + b + '), ' +
                                 'rgb(' + r + ', 255, ' + b + '))';
    ui.b.style.background =
       'linear-gradient(to right, rgb(' + r + ', ' + g + ', 0), ' +
                                 'rgb(' + r + ', ' + g + ', 255))';
  }

  window.addEventListener('load', initializeWindow);
}());
<commit_msg>blink(1) command buffer is only 7 bytes.<commit_after>(function() {
  var ui = {
    r: null,
    g: null,
    b: null
  };

  var connection = -1;

  function initializeWindow() {
    for (var k in ui) {
      var id = k.replace(/([A-Z])/, '-$1').toLowerCase();
      var element = document.getElementById(id);
      if (!element) {
        throw "Missing UI element: " + k;
      }
      ui[k] = element;
    }
    setGradients();
    enableControls(false);
    ui.r.addEventListener('input', onColorChanged);
    ui.g.addEventListener('input', onColorChanged);
    ui.b.addEventListener('input', onColorChanged);
    enumerateDevices();
  };

  function enableControls(enabled) {
    ui.r.disabled = !enabled;
    ui.g.disabled = !enabled;
    ui.b.disabled = !enabled;
  };

  function enumerateDevices() {
    chrome.hid.getDevices(
        { "vendorId": 10168, "productId": 493 },
        onDevicesEnumerated);
  };

  function onDevicesEnumerated(devices) {
    if (!devices) {
      console.warn("Unable to enumerate devices: " +
                   chrome.runtime.lastError.message);
      return;
    }

    chrome.hid.connect(devices[0].deviceId, onDeviceConnected);
  };

  function onDeviceConnected(connectInfo) {
    if (!connectInfo) {
      console.warn("Unable to connect to device: " +
                   chrome.runtime.lastError.message);
    }
    connection = connectInfo.connectionId;
    enableControls(true);
  };

  function fadeRGB(r, g, b, fade_ms, led) {
    // Send a fade command to the blink(1). The command protocol operates over
    // feature reports and is documented here:
    //
    // https://github.com/todbot/blink1/blob/master/docs/blink1-hid-commands.md

    var fade_time = fade_ms / 10;
    var th = (fade_time & 0xff00) >> 8;
    var tl = fade_time & 0x00ff;
    var data = new Uint8Array(7);
    data[0] = 'c'.charCodeAt(0);
    data[1] = r;
    data[2] = g;
    data[3] = b;
    data[4] = th;
    data[5] = tl;
    data[6] = led;
    chrome.hid.sendFeatureReport(connection, 1, data.buffer, function() {
      if (chrome.runtime.lastError) {
        console.warn("Unable to set feature report: " +
                     chrome.runtime.lastError.message);
      }
    });
  }

  function onColorChanged() {
    setGradients();
    fadeRGB(ui.r.value, ui.g.value, ui.b.value, 250, 0);
  }

  function setGradients() {
    var r = ui.r.value, g = ui.g.value, b = ui.b.value;
    ui.r.style.background =
       'linear-gradient(to right, rgb(0, ' + g + ', ' + b + '), ' +
                                 'rgb(255, ' + g + ', ' + b + '))';
    ui.g.style.background =
       'linear-gradient(to right, rgb(' + r + ', 0, ' + b + '), ' +
                                 'rgb(' + r + ', 255, ' + b + '))';
    ui.b.style.background =
       'linear-gradient(to right, rgb(' + r + ', ' + g + ', 0), ' +
                                 'rgb(' + r + ', ' + g + ', 255))';
  }

  window.addEventListener('load', initializeWindow);
}());
<|endoftext|>


<commit_before>/* globals CONFIG, GC, logger */

var dispatchWindowEvent = function(eventName) {
  var e = document.createEvent('Event');
  e.initEvent(eventName, true, true);
  window.dispatchEvent(e);
};

exports.onLaunch = function () {
  var deviceId = CONFIG.simulator.deviceId;
  var deviceType = CONFIG.simulator.deviceType;
  var deviceInfo = CONFIG.simulator.deviceInfo;

  import .simulateDevice;
  simulateDevice.simulate(deviceInfo);

  import devkit.debugging;
  var channel = devkit.debugging.getChannel('devkit-simulator');

  var _isHomeScreen = false;
  channel.on('button:home', function () {
    var app = GC.app;

    _isHomeScreen = !_isHomeScreen;
    if (_isHomeScreen) {
      dispatchWindowEvent('pagehide');
      app.engine.pause();

      var canvas = document.getElementsByTagName('canvas');
      if (canvas.length) {
        canvas = canvas[0];
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
          ctx.fillStyle = '#000000';
          ctx.fillRect(0, 0, canvas.width, canvas.height);
        }
      }
    } else {
      dispatchWindowEvent('pageshow');
      app.engine.resume();
    }
  });

  channel.on('button:back', function (evt) {
    GLOBAL.NATIVE.onBackButton && GLOBAL.NATIVE.onBackButton(evt);
  });

  channel.on('screenshot', function (req) {
    devkit.debugging.screenshot(function (err, res) {
      if (err) {
        req.error(err);
      } else {
        req.send(res);
      }
    });
  });

  channel.on('mute', function (evt) {
    console.log('MUTE', evt.shouldMute);
    import AudioManager;
    AudioManager.muteAll(evt.shouldMute);
  });

  channel.on('pause', function () { exports.setPaused(true); });
  channel.on('resume', function () { exports.setPaused(false); });
  channel.on('step', function () { GC.app.engine.stepFrame(); });

  logger.log('waiting for devkit simulator client...');

  import device;

  return channel.connect()
    .timeout(1000)
    .then(function () {
      logger.log('simulator client connected!');
      channel.emit('handshake', {
        deviceId: deviceId,
        deviceType: deviceType,
        userAgent: navigator.userAgent,
        screen: {
          width: device.screen.width,
          height: device.screen.height
        }
      });
    });
};

var _isPaused = false;
exports.setPaused = function (isPaused) {
  _isPaused = isPaused;

  var app = GC.app;
  if (_isPaused) {
    console.log("app paused");
    app.engine.pause();
  } else {
    app.engine.resume();
  }
};
<commit_msg>fix screenshot button<commit_after>/* globals CONFIG, GC, logger */

var dispatchWindowEvent = function(eventName) {
  var e = document.createEvent('Event');
  e.initEvent(eventName, true, true);
  window.dispatchEvent(e);
};

exports.onLaunch = function () {
  var deviceId = CONFIG.simulator.deviceId;
  var deviceType = CONFIG.simulator.deviceType;
  var deviceInfo = CONFIG.simulator.deviceInfo;

  import .simulateDevice;
  simulateDevice.simulate(deviceInfo);

  import devkit.debugging;
  var channel = devkit.debugging.getChannel('devkit-simulator');

  var _isHomeScreen = false;
  channel.on('button:home', function () {
    var app = GC.app;

    _isHomeScreen = !_isHomeScreen;
    if (_isHomeScreen) {
      dispatchWindowEvent('pagehide');
      app.engine.pause();

      var canvas = document.getElementsByTagName('canvas');
      if (canvas.length) {
        canvas = canvas[0];
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
          ctx.fillStyle = '#000000';
          ctx.fillRect(0, 0, canvas.width, canvas.height);
        }
      }
    } else {
      dispatchWindowEvent('pageshow');
      app.engine.resume();
    }
  });

  channel.on('button:back', function (evt) {
    GLOBAL.NATIVE.onBackButton && GLOBAL.NATIVE.onBackButton(evt);
  });

  channel.on('screenshot', function (data, req) {
    devkit.debugging.screenshot(function (err, res) {
      if (err) {
        req.error(err);
      } else {
        req.send(res);
      }
    });
  });

  channel.on('mute', function (evt) {
    console.log('MUTE', evt.shouldMute);
    import AudioManager;
    AudioManager.muteAll(evt.shouldMute);
  });

  channel.on('pause', function () { exports.setPaused(true); });
  channel.on('resume', function () { exports.setPaused(false); });
  channel.on('step', function () { GC.app.engine.stepFrame(); });

  logger.log('waiting for devkit simulator client...');

  import device;

  return channel.connect()
    .timeout(1000)
    .then(function () {
      logger.log('simulator client connected!');
      channel.emit('handshake', {
        deviceId: deviceId,
        deviceType: deviceType,
        userAgent: navigator.userAgent,
        screen: {
          width: device.screen.width,
          height: device.screen.height
        }
      });
    });
};

var _isPaused = false;
exports.setPaused = function (isPaused) {
  _isPaused = isPaused;

  var app = GC.app;
  if (_isPaused) {
    console.log("app paused");
    app.engine.pause();
  } else {
    app.engine.resume();
  }
};
<|endoftext|>