<commit_before>goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.KML');
goog.require('ol.geom.Polygon');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.render');
goog.require('ol.source.Stamen');
goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Icon');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');

var styleCache = {};
var styleFunction = function(feature) {
  // 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
  // standards-violating <magnitude> tag in each Placemark.  We extract it from
  // the Placemark's name instead.
  var name = feature.get('name');
  var magnitude = parseFloat(name.substr(2));
  var size = parseInt(10 + 40 * (magnitude - 5), 10);
  var style = styleCache[size];
  if (!style) {
    var canvas =
        /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
    var vectorContext = ol.render.toContext(
        /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
        {size: [size + 2, size + 2], pixelRatio: size / 10});
    vectorContext.setStyle(new ol.style.Style({
      fill: new ol.style.Fill({color: 'rgba(255, 153, 0, 0.4)'}),
      stroke: new ol.style.Stroke({color: 'rgba(255, 204, 0, 0.2)', width: 1})
    }));
    vectorContext.drawGeometry(new ol.geom.Polygon(
        [[[0, 0], [4, 2], [6, 0], [10, 5], [6, 3], [4, 5], [0, 0]]]));
    style = new ol.style.Style({
      image: new ol.style.Icon({
        img: canvas,
        imgSize: [canvas.width, canvas.height],
        rotation: 1.2
      })
    });
    styleCache[size] = style;
  }
  return style;
};

var vector = new ol.layer.Vector({
  source: new ol.source.Vector({
    url: 'data/kml/2012_Earthquakes_Mag5.kml',
    format: new ol.format.KML({
      extractStyles: false
    })
  }),
  style: styleFunction
});

var raster = new ol.layer.Tile({
  source: new ol.source.Stamen({
    layer: 'toner'
  })
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});
<commit_msg>Fix custom icon positions and rotation<commit_after>goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.KML');
goog.require('ol.geom.Polygon');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.render');
goog.require('ol.source.Stamen');
goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Icon');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');

var symbol = [[0, 0], [4, 2], [6, 0], [10, 5], [6, 3], [4, 5], [0, 0]];
var scale;
var scaleFunction = function(coordinate) {
  return [coordinate[0] * scale, coordinate[1] * scale];
};

var styleCache = {};
var styleFunction = function(feature) {
  // 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
  // standards-violating <magnitude> tag in each Placemark.  We extract it from
  // the Placemark's name instead.
  var name = feature.get('name');
  var magnitude = parseFloat(name.substr(2));
  var size = parseInt(10 + 40 * (magnitude - 5), 10);
  scale = size / 10;
  var style = styleCache[size];
  if (!style) {
    var canvas =
        /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
    var vectorContext = ol.render.toContext(
        /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
        {size: [size, size], pixelRatio: 1});
    vectorContext.setStyle(new ol.style.Style({
      fill: new ol.style.Fill({color: 'rgba(255, 153, 0, 0.4)'}),
      stroke: new ol.style.Stroke({color: 'rgba(255, 204, 0, 0.2)', width: 2})
    }));
    vectorContext.drawGeometry(new ol.geom.Polygon([symbol.map(scaleFunction)]));
    style = new ol.style.Style({
      image: new ol.style.Icon({
        img: canvas,
        imgSize: [size, size],
        rotation: 1.2
      })
    });
    styleCache[size] = style;
  }
  return style;
};

var vector = new ol.layer.Vector({
  source: new ol.source.Vector({
    url: 'data/kml/2012_Earthquakes_Mag5.kml',
    format: new ol.format.KML({
      extractStyles: false
    })
  }),
  style: styleFunction
});

var raster = new ol.layer.Tile({
  source: new ol.source.Stamen({
    layer: 'toner'
  })
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});
<|endoftext|>


<commit_before><%= include 'HEADER' %>

var Prototype = {
  Version: '<%= PROTOTYPE_VERSION %>',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/iPhone.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div').__proto__ !==
       document.createElement('form').__proto__
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;

<%= include 'base.js', 'string.js' %>

<%= include 'enumerable.js', 'array.js', 'number.js', 'hash.js', 'range.js' %>

<%= include 'ajax.js', 'dom.js', 'selector.js', 'form.js', 'event.js', 'deprecated.js' %>

Element.addMethods();
<commit_msg>prototype: Update Prototype.Browser.MobileSafari for iPod touch compatibility.<commit_after><%= include 'HEADER' %>

var Prototype = {
  Version: '<%= PROTOTYPE_VERSION %>',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div').__proto__ !==
       document.createElement('form').__proto__
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;

<%= include 'base.js', 'string.js' %>

<%= include 'enumerable.js', 'array.js', 'number.js', 'hash.js', 'range.js' %>

<%= include 'ajax.js', 'dom.js', 'selector.js', 'form.js', 'event.js', 'deprecated.js' %>

Element.addMethods();
<|endoftext|>


<commit_before>import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import { spawn } from 'child_process';

import { host, port, isElectron, isDev } from '../env';
import webpackConf from '../webpack.config.js';
import webpackElectronMainConf from '../webpack.electron-main.config.js'

const compiler = webpack(webpackConf);
const mainCompiler = webpack(webpackElectronMainConf);

const wdm = webpackDevMiddleware(compiler, {
    publicPath: webpackConf.output.publicPath,
    stats: {
        colors: true,
    },
});

const app = express();
app.use(wdm);
app.use(webpackHotMiddleware(compiler));

let electronChildProcess = null;
const startElectron = () => {
    if (isElectron()) {
        const mainPath = `build/${isDev() ? 'dev' : 'prod'}/main.js`;
        electronChildProcess = spawn('electron', [mainPath], {
            env: process.env,
            detached: true,
            shell: true,
            stdio: 'inherit',
        })
        .on('close', (code, signal) => signal !== 'SIGHUP' && process.exit(code))
        .on('error', spawnError => console.error(spawnError));
    }
};

const stopElectron = (signal = 'SIGINT') => {
    if (electronChildProcess) {
        process.kill(-electronChildProcess.pid, signal);
        electronChildProcess = null;
    }
};

const restartElectron = (signal) => {
    stopElectron(signal);
    setImmediate(startElectron);
}

if (isElectron()) {
    mainCompiler.watch({}, (err, stats) => {
        if (err) {
            console.error(err);
            console.error(stats.toJson().errors);
            process.exit(1);
        }
        restartElectron('SIGHUP');
        console.info(`${webpackConf.output.filename} compiled`);
    });
}

const server = app.listen(port, host, serverError => {
    if (serverError) {
        return console.error(serverError);
    }

    console.log(`Listening at http://${host}:${port}`);
});

const stopDevServer = () => {
    console.log('Stopping dev server');
    wdm.close(() => {
        server.close(() => {
            process.exit(0);
        });
    });
}

process.on('SIGTERM', stopDevServer);

process.on('SIGINT', () => {
    stopElectron('SIGINT');
    stopDevServer();
})
<commit_msg>Refacto server : split in several files<commit_after>import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import { spawn } from 'child_process';

import { host, port, isElectron, isDev } from '../env';
import webpackConf from '../webpack.config.js';
import webpackElectronMainConf from '../webpack.electron-main.config.js'

const compiler = webpack(webpackConf);
const mainCompiler = webpack(webpackElectronMainConf);

let electronChildProcess = null;
const startElectron = () => {
    if (isElectron()) {
        const mainPath = `build/${isDev() ? 'dev' : 'prod'}/main.js`;
        const exit = (code) => {
            console.info('App exited.');
            return stopDevServer(code);
        };
        electronChildProcess = spawn('electron', [mainPath], {
            env: process.env,
            detached: true,
            shell: true,
            stdio: 'inherit',
        })
        .on('close', (code, signal) => signal !== 'SIGHUP' && exit(code))
        .on('error', spawnError => console.error(spawnError));
    }
};

const stopElectron = (signal = 'SIGINT') => {
    if (electronChildProcess) {
        process.kill(-electronChildProcess.pid, signal);
        electronChildProcess = null;
    }
};

const restartElectron = (signal) => {
    stopElectron(signal);
    setImmediate(startElectron);
}

const watchMain = compiler => {
    compiler.watch({}, (err, stats) => {
        if (err) {
            console.error(err);
            console.error(stats.toJson().errors);
            process.exit(1);
        }
        restartElectron('SIGHUP');
        console.info(`${webpackElectronMainConf.output.filename} compiled`);
    });
}

if (isElectron()) {
    watchMain(mainCompiler);
}

let server;
let wdm;
const startDevServer = (compiler) => {
    const app = express();
    wdm = webpackDevMiddleware(compiler, {
        publicPath: webpackConf.output.publicPath,
        stats: {
            colors: true,
        },
    });

    app.use(wdm);
    app.use(webpackHotMiddleware(compiler));
    server = app.listen(port, host, serverError => {
        if (serverError) {
            return console.error(serverError);
        }

        console.log(`listening at http://${host}:${port}`);
    });
}
const stopDevServer = (code = 0) => {
    if (wdm && server) {
        console.info('Closing dev server...');
        server.close(() => {
            console.info('Dev server closed.');
            process.exit(code);
        });
        setTimeout(() => { // prevents to server.close freeze
            process.exit(code)
        }, 1000)
    } else process.exit(code);
}

startDevServer(compiler);

process.on('SIGTERM', stopDevServer);

process.on('SIGINT', () => {
    stopElectron('SIGINT');
    stopDevServer();
})
<|endoftext|>


<commit_before>define('components', ['consts', 'buttons', 'utils'], function(consts, buttons, utils) {
    'use strict';

    let _createTable = (parent) => {
            let table = consts.DOC.createElement('table'),
                rows = 10,
                columns = 10,
                trRange = utils.range(0, rows, 0),
                tdRange = utils.range(0, columns, 0),
                lettersRange = utils.range('a', 'j', 0);

            table.className = 'panelGamerBoard';

            Array.from(trRange).forEach((x) => {
                let trElement = consts.DOC.createElement('tr');

                if (x === 0) {
                    trElement.className = 'tr' + x;
                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdNumber = consts.DOC.createElement('p');

                        if (s !== 0) {
                            tdElement.className = 'td' + s;
                            tdNumber.innerHTML = s + '';
                            tdElement.appendChild(tdNumber);
                        }

                        trElement.appendChild(tdElement);
                    });
                } else {
                    trElement.className = 'tr' + x;

                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdLetter = consts.DOC.createElement('p'),
                            letter = lettersRange[x - 1];

                        tdElement.className = 'td' + s;
                        tdElement.setAttribute('data-number', s + '');
                        tdElement.setAttribute('data-letter', letter);
                        tdLetter.innerHTML = letter;

                        if (s === 0) {
                            tdElement.appendChild(tdLetter);
                        }
                        trElement.appendChild(tdElement);
                    });
                }

                table.appendChild(trElement);
            });
            _moveShips(table);
            _hoverShips(table);
            return table;
        },
        _tableObject = (table) => {
            let tableObject = {};

            Object.keys(table.childNodes).forEach((x) => {
                if (table.childNodes[x].className !== 'tr0') {
                    let arr = [],
                        selected = [];
                    Object.keys(table.childNodes[x].childNodes).forEach((d) => {
                        if (table.childNodes[x].childNodes[d].className !== 'td0') {
                            arr.push(table.childNodes[x].childNodes[d]);
                        }
                        if (table.childNodes[x].childNodes[d].classList.contains('selected')) {
                            selected.push(table.childNodes[x].childNodes[d]);
                        }
                    });
                    tableObject[table.childNodes[x].className] = {
                        childs: arr,
                        selected: selected
                    };
                    arr = [];
                    selected = [];
                }
            });

            return tableObject;
        },
        _hoverSelected = {},
        _showShip = (element) => {
            // TODO: pending...
        },
        _moveShips = (table) => {
            table.onclick = (e) => {
                let tableObject = _tableObject(table),
                    elementClass = e.target.classList,
                    elementDataName = e.target.getAttribute('data-name') || null,
                    elementParent = e.target.parentNode.className,
                    elementNumber = e.target.getAttribute('data-number');

                Array.from(elementClass).forEach((x) => {
                    if (x === 'selected') {
                        let selectedLen = tableObject[elementParent].selected.length,
                            selecteds = tableObject[elementParent].selected;

                        if (elementDataName !== null && selectedLen > 1) {
                            Array.from(selecteds).forEach((f) => {
                                _hoverSelected = {
                                    name: elementDataName,
                                    position: 'horizontal',
                                    parent: elementParent,
                                    len: selectedLen,
                                    number: elementNumber,
                                    selected: e.target,
                                    hover: true
                                }

                                if (f.classList.contains('selected')) {
                                    f.classList.remove('selected');
                                } else if (f.classList.contains('hover')) {
                                    _showShip(_hoverSelected);
                                }
                            });
                        } else if (elementDataName !== null && selectedLen === 1) {
                            // TODO: pending...
                        }
                    } else {
                        return;
                    }
                });
            };
        },
        _hoverShips = (table) => {
            $(table).find('td').hover((e) => {
                let element = e.currentTarget,
                    elementParent = e.currentTarget.parentNode,
                    elementNumber = parseInt(e.currentTarget.getAttribute('data-number')),
                    len = _hoverSelected.len,
                    i = 0;

                if (elementParent.className !== 'tr0'
                    && element.className !== 'td0'
                    && _hoverSelected.hasOwnProperty('name')) {

                    for (i; i < len; i++) {
                        let selected = $('.td' + elementNumber);

                        if (selected.parent().hasClass(elementParent.className)) {
                            $('.' + elementParent.className).find(selected).addClass('selected hover');
                            $('.' + elementParent.className).find(selected).attr('data-name', _hoverSelected.name);
                            elementNumber++;
                        }
                    }
                }
            });
        },
        _shipSelected = {},
        _positionSelected = null,
        _checkTds = (trChilds, range) => {
            let table = {},
                arr = [];

            Array.from(trChilds).forEach((x) => {
                let arr = [],
                    name = [];
                Array.from(x.childNodes).forEach((f) => {
                    if (f.className !== 'td0') arr.push(f);
                    if (f.hasAttribute('data-name')) name.push(f);
                });
                table[x.className] = {
                    childs: arr,
                    childsShips: name
                };
            });
            return table;
        },
        _changeVerticalBox = (trs, range, name) => {
            let i = 0,
                arr = {},
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < range.length) {
                    arr[x] = trs[x];
                    i++;
                }
            });

            if (i === range.length) {
                Object.keys(arr).forEach((d) => {
                    let arrChild = arr[d].childs[0];
                    arrChild.className += ' selected';
                    arrChild.setAttribute('data-name', name);
                });
                menuGamer.removeElement(name);
            } else {
                let message = 'Move your ships form place more.';
                utils.message('green', message);
            }
        },
        _verticalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeVerticalBox(_resultTrs, _range, name);
        },
        _changeHorizontalBox = (trs, range, name) => {
            let i = 0,
                d = 0,
                arr = {},
                firstChild = null,
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < 1) {
                    firstChild = x;
                    arr[x] = trs[x];
                    i++;
                }
            });
            Array.from(arr[firstChild].childs).forEach((j) => {
                let arrChilds = arr[firstChild].childs;
                if (d < range.length) {
                    j.className += ' selected';
                    j.setAttribute('data-name', name);
                    d++;
                }
            });
            menuGamer.removeElement(name);
        },
        _horizontalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeHorizontalBox(_resultTrs, _range, name);
        },
        _placeShip = (ship, position) => {
            let num = 0,
                result = {},
                defaultPosition = (position !== null) ? position : 'horizontal',
                defaultShip = () => {
                    let select = consts.DOC.getElementById('gamerSelect');
                    Object.keys(select.childNodes).forEach((x) => {
                        if (select.hasOwnProperty(x) && num < 1) {
                            let selected = select.childNodes[x];
                            result.value = selected.value;
                            result.name = selected.getAttribute('data-name');
                            result.boxes = selected.getAttribute('data-box');
                            num++;
                        }
                    });
                    return result;
                },
                shipSelected = (typeof ship === 'object' && Object.keys(ship).length !== 0) ? ship : defaultShip();

            if (shipSelected.value && defaultPosition) {
                switch (defaultPosition) {
                    case 'vertical':
                        _verticalShip(shipSelected.boxes, shipSelected.name);
                        break;
                    case 'horizontal':
                        _horizontalShip(shipSelected.boxes, shipSelected.name);
                        break;
                }
            } else {
                let message = 'You must choose one ship and the position you want to place it.';
                utils.message('red', message);
            }
            _shipSelected = {};
            _positionSelected = null;
        };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _MenuGamer {
        constructor() {
            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';
        }
        getMenuGamer() {
            return this.menuGamer;
        }
        removeElement(element) {
            let select = consts.DOC.getElementById('gamerSelect');
            Object.keys(select.childNodes).forEach((x) => {
                if (select.childNodes[x]) {
                    let dataName = select.childNodes[x].getAttribute('data-name');
                    if (dataName === element) {
                        select.remove(select.selectedIndex);
                    }
                }
            });
        }
        shipsMenu() {
            let ships = {
                    aircraftCarrier: {
                        name: 'Aircraft Carrier',
                        boxes: 5
                    },
                    battleship: {
                        name: 'Battleship',
                        boxes: 4
                    },
                    submarine: {
                        name: 'Submarine',
                        boxes: 3
                    },
                    destroyer: {
                        name: 'Destroyer',
                        boxes: 3
                    },
                    patrolBoat: {
                        name: 'Patrol boat',
                        boxes: 2
                    }
                },
                selectTitle = consts.DOC.createElement('h3'),
                selectPositionText = consts.DOC.createElement('h3'),
                position = ['horizontal', 'vertical'],
                divSelect1 = consts.DOC.createElement('div'),
                divSelect2 = consts.DOC.createElement('div'),
                divSelect3 = consts.DOC.createElement('div'),
                placeButton = consts.DOC.createElement('input');

            placeButton.id = 'placeShipButton';
            placeButton.type = 'button';
            placeButton.value = 'PLACE';

            divSelect1.className = 'divSelect1';
            divSelect2.className = 'divSelect2';
            divSelect3.className = 'divSelect3';

            selectTitle.className = 'selectShipsText';
            selectTitle.innerHTML = 'Place your ships:';

            this.selectMenuShips = consts.DOC.createElement('select');
            this.selectMenuShips.id = 'gamerSelect';

            Object.keys(ships).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = ships[x].name;
                option.innerHTML = ships[x].name;
                option.setAttribute('data-name', x + '');
                option.setAttribute('data-box', ships[x].boxes + '');

                this.selectMenuShips.appendChild(option);
            });

            divSelect1.appendChild(selectTitle);
            divSelect1.appendChild(this.selectMenuShips);
            this.menuGamer.appendChild(divSelect1);

            this.selectMenuShips.onchange = (event) => {
                let evTarget = event.target.selectedOptions[0];
                _shipSelected.value = evTarget.value;
                _shipSelected.boxes = evTarget.getAttribute('data-box');
                _shipSelected.name = evTarget.getAttribute('data-name');
            };

            selectPositionText.className = 'selectPositionText';
            selectPositionText.innerHTML = 'Ship Position:';

            this.selectShipPosition = consts.DOC.createElement('select');
            this.selectShipPosition.id = 'selectPosition';

            Array.from(position).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = x;
                option.innerHTML = x + '';

                this.selectShipPosition.appendChild(option);
            });

            divSelect2.appendChild(selectPositionText);
            divSelect2.appendChild(this.selectShipPosition);
            this.menuGamer.appendChild(divSelect2);

            this.selectShipPosition.onchange = (event) => {
                _positionSelected = event.target.selectedOptions[0].value;
            };

            divSelect3.appendChild(placeButton);
            this.menuGamer.appendChild(divSelect3);

            placeButton.onclick = () => {
                _placeShip(_shipSelected, _positionSelected);
            }
        }
        appendMenuGamer(parent) {
            this.shipsMenu();
            parent.appendChild(this.menuGamer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this._menuGamer = new _MenuGamer();
            this._menuGamer.appendMenuGamer(this.panelGamer);

            this._table = _createTable(this.panelGamer);
            this.panelGamer.appendChild(this._table);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        MenuGamer: _MenuGamer,
        PanelGamer: _PanelGamer,
        createTable: _createTable
    }
});
<commit_msg>Working on _hoverShips method<commit_after>define('components', ['consts', 'buttons', 'utils'], function(consts, buttons, utils) {
    'use strict';

    let _createTable = (parent) => {
            let table = consts.DOC.createElement('table'),
                rows = 10,
                columns = 10,
                trRange = utils.range(0, rows, 0),
                tdRange = utils.range(0, columns, 0),
                lettersRange = utils.range('a', 'j', 0);

            table.className = 'panelGamerBoard';

            Array.from(trRange).forEach((x) => {
                let trElement = consts.DOC.createElement('tr');

                if (x === 0) {
                    trElement.className = 'tr' + x;
                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdNumber = consts.DOC.createElement('p');

                        if (s !== 0) {
                            tdElement.className = 'td' + s;
                            tdNumber.innerHTML = s + '';
                            tdElement.appendChild(tdNumber);
                        }

                        trElement.appendChild(tdElement);
                    });
                } else {
                    trElement.className = 'tr' + x;

                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdLetter = consts.DOC.createElement('p'),
                            letter = lettersRange[x - 1];

                        tdElement.className = 'td' + s;
                        tdElement.setAttribute('data-number', s + '');
                        tdElement.setAttribute('data-letter', letter);
                        tdLetter.innerHTML = letter;

                        if (s === 0) {
                            tdElement.appendChild(tdLetter);
                        }
                        trElement.appendChild(tdElement);
                    });
                }

                table.appendChild(trElement);
            });
            _moveShips(table);
            _hoverShips(table);
            return table;
        },
        _tableObject = (table) => {
            let tableObject = {};

            Object.keys(table.childNodes).forEach((x) => {
                if (table.childNodes[x].className !== 'tr0') {
                    let arr = [],
                        selected = [];
                    Object.keys(table.childNodes[x].childNodes).forEach((d) => {
                        if (table.childNodes[x].childNodes[d].className !== 'td0') {
                            arr.push(table.childNodes[x].childNodes[d]);
                        }
                        if (table.childNodes[x].childNodes[d].classList.contains('selected')) {
                            selected.push(table.childNodes[x].childNodes[d]);
                        }
                    });
                    tableObject[table.childNodes[x].className] = {
                        childs: arr,
                        selected: selected
                    };
                    arr = [];
                    selected = [];
                }
            });

            return tableObject;
        },
        _hoverSelected = {},
        _showShip = (element) => {
            // TODO: pending...
        },
        _moveShips = (table) => {
            table.onclick = (e) => {
                let tableObject = _tableObject(table),
                    elementClass = e.target.classList,
                    elementDataName = e.target.getAttribute('data-name') || null,
                    elementParent = e.target.parentNode.className,
                    elementNumber = e.target.getAttribute('data-number');

                Array.from(elementClass).forEach((x) => {
                    if (x === 'selected') {
                        let selectedLen = tableObject[elementParent].selected.length,
                            selecteds = tableObject[elementParent].selected;

                        if (elementDataName !== null && selectedLen > 1) {
                            Array.from(selecteds).forEach((f) => {
                                _hoverSelected = {
                                    name: elementDataName,
                                    position: 'horizontal',
                                    parent: elementParent,
                                    len: selectedLen,
                                    number: elementNumber,
                                    selected: e.target,
                                    hover: true
                                }

                                if (f.classList.contains('selected')) {
                                    f.classList.remove('selected');
                                } else if (f.classList.contains('hover')) {
                                    _showShip(_hoverSelected);
                                }
                            });
                        } else if (elementDataName !== null && selectedLen === 1) {
                            // TODO: pending...
                        }
                    } else {
                        return;
                    }
                });
            };
        },
        _removeSelected = () => {
            let table = consts.DOC.getElementsByClassName('panelGamerBoard');

            Array.from(table[0].childNodes).forEach((tr) => {
                let tds = tr.childNodes;
                Array.from(tds).forEach((td) => {
                    if (td.hasAttribute('class') && td.className !== 'panelGamerBoard' && td.classList.contains('hover')) {
                        $(td).removeClass('selected hover');
                    }
                });
            });

        },
        _hoverShips = (table) => {
            $(table).find('td').hover((e) => {
                let element = e.currentTarget,
                    elementParent = e.currentTarget.parentNode,
                    elementNumber = parseInt(e.currentTarget.getAttribute('data-number')),
                    len = _hoverSelected.len,
                    i = 0;

                if (elementParent.className !== 'tr0' && element.className !== 'td0' && _hoverSelected.hasOwnProperty('name')) {
                    _removeSelected();

                    for (i; i < len; i++) {
                        let selected = $('.td' + elementNumber);

                        if (selected.parent().hasClass(elementParent.className)) {
                            $('.' + elementParent.className).find(selected).addClass('selected hover');
                            $('.' + elementParent.className).find(selected).attr('data-name', _hoverSelected.name);
                            elementNumber++;
                        }
                    }
                }
            });
        },
        _shipSelected = {},
        _positionSelected = null,
        _checkTds = (trChilds, range) => {
            let table = {},
                arr = [];

            Array.from(trChilds).forEach((x) => {
                let arr = [],
                    name = [];
                Array.from(x.childNodes).forEach((f) => {
                    if (f.className !== 'td0') arr.push(f);
                    if (f.hasAttribute('data-name')) name.push(f);
                });
                table[x.className] = {
                    childs: arr,
                    childsShips: name
                };
            });
            return table;
        },
        _changeVerticalBox = (trs, range, name) => {
            let i = 0,
                arr = {},
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < range.length) {
                    arr[x] = trs[x];
                    i++;
                }
            });

            if (i === range.length) {
                Object.keys(arr).forEach((d) => {
                    let arrChild = arr[d].childs[0];
                    arrChild.className += ' selected';
                    arrChild.setAttribute('data-name', name);
                });
                menuGamer.removeElement(name);
            } else {
                let message = 'Move your ships form place more.';
                utils.message('green', message);
            }
        },
        _verticalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeVerticalBox(_resultTrs, _range, name);
        },
        _changeHorizontalBox = (trs, range, name) => {
            let i = 0,
                d = 0,
                arr = {},
                firstChild = null,
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < 1) {
                    firstChild = x;
                    arr[x] = trs[x];
                    i++;
                }
            });
            Array.from(arr[firstChild].childs).forEach((j) => {
                let arrChilds = arr[firstChild].childs;
                if (d < range.length) {
                    j.className += ' selected';
                    j.setAttribute('data-name', name);
                    d++;
                }
            });
            menuGamer.removeElement(name);
        },
        _horizontalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeHorizontalBox(_resultTrs, _range, name);
        },
        _placeShip = (ship, position) => {
            let num = 0,
                result = {},
                defaultPosition = (position !== null) ? position : 'horizontal',
                defaultShip = () => {
                    let select = consts.DOC.getElementById('gamerSelect');
                    Object.keys(select.childNodes).forEach((x) => {
                        if (select.hasOwnProperty(x) && num < 1) {
                            let selected = select.childNodes[x];
                            result.value = selected.value;
                            result.name = selected.getAttribute('data-name');
                            result.boxes = selected.getAttribute('data-box');
                            num++;
                        }
                    });
                    return result;
                },
                shipSelected = (typeof ship === 'object' && Object.keys(ship).length !== 0) ? ship : defaultShip();

            if (shipSelected.value && defaultPosition) {
                switch (defaultPosition) {
                    case 'vertical':
                        _verticalShip(shipSelected.boxes, shipSelected.name);
                        break;
                    case 'horizontal':
                        _horizontalShip(shipSelected.boxes, shipSelected.name);
                        break;
                }
            } else {
                let message = 'You must choose one ship and the position you want to place it.';
                utils.message('red', message);
            }
            _shipSelected = {};
            _positionSelected = null;
        };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _MenuGamer {
        constructor() {
            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';
        }
        getMenuGamer() {
            return this.menuGamer;
        }
        removeElement(element) {
            let select = consts.DOC.getElementById('gamerSelect');
            Object.keys(select.childNodes).forEach((x) => {
                if (select.childNodes[x]) {
                    let dataName = select.childNodes[x].getAttribute('data-name');
                    if (dataName === element) {
                        select.remove(select.selectedIndex);
                    }
                }
            });
        }
        shipsMenu() {
            let ships = {
                    aircraftCarrier: {
                        name: 'Aircraft Carrier',
                        boxes: 5
                    },
                    battleship: {
                        name: 'Battleship',
                        boxes: 4
                    },
                    submarine: {
                        name: 'Submarine',
                        boxes: 3
                    },
                    destroyer: {
                        name: 'Destroyer',
                        boxes: 3
                    },
                    patrolBoat: {
                        name: 'Patrol boat',
                        boxes: 2
                    }
                },
                selectTitle = consts.DOC.createElement('h3'),
                selectPositionText = consts.DOC.createElement('h3'),
                position = ['horizontal', 'vertical'],
                divSelect1 = consts.DOC.createElement('div'),
                divSelect2 = consts.DOC.createElement('div'),
                divSelect3 = consts.DOC.createElement('div'),
                placeButton = consts.DOC.createElement('input');

            placeButton.id = 'placeShipButton';
            placeButton.type = 'button';
            placeButton.value = 'PLACE';

            divSelect1.className = 'divSelect1';
            divSelect2.className = 'divSelect2';
            divSelect3.className = 'divSelect3';

            selectTitle.className = 'selectShipsText';
            selectTitle.innerHTML = 'Place your ships:';

            this.selectMenuShips = consts.DOC.createElement('select');
            this.selectMenuShips.id = 'gamerSelect';

            Object.keys(ships).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = ships[x].name;
                option.innerHTML = ships[x].name;
                option.setAttribute('data-name', x + '');
                option.setAttribute('data-box', ships[x].boxes + '');

                this.selectMenuShips.appendChild(option);
            });

            divSelect1.appendChild(selectTitle);
            divSelect1.appendChild(this.selectMenuShips);
            this.menuGamer.appendChild(divSelect1);

            this.selectMenuShips.onchange = (event) => {
                let evTarget = event.target.selectedOptions[0];
                _shipSelected.value = evTarget.value;
                _shipSelected.boxes = evTarget.getAttribute('data-box');
                _shipSelected.name = evTarget.getAttribute('data-name');
            };

            selectPositionText.className = 'selectPositionText';
            selectPositionText.innerHTML = 'Ship Position:';

            this.selectShipPosition = consts.DOC.createElement('select');
            this.selectShipPosition.id = 'selectPosition';

            Array.from(position).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = x;
                option.innerHTML = x + '';

                this.selectShipPosition.appendChild(option);
            });

            divSelect2.appendChild(selectPositionText);
            divSelect2.appendChild(this.selectShipPosition);
            this.menuGamer.appendChild(divSelect2);

            this.selectShipPosition.onchange = (event) => {
                _positionSelected = event.target.selectedOptions[0].value;
            };

            divSelect3.appendChild(placeButton);
            this.menuGamer.appendChild(divSelect3);

            placeButton.onclick = () => {
                _placeShip(_shipSelected, _positionSelected);
            }
        }
        appendMenuGamer(parent) {
            this.shipsMenu();
            parent.appendChild(this.menuGamer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this._menuGamer = new _MenuGamer();
            this._menuGamer.appendMenuGamer(this.panelGamer);

            this._table = _createTable(this.panelGamer);
            this.panelGamer.appendChild(this._table);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        MenuGamer: _MenuGamer,
        PanelGamer: _PanelGamer,
        createTable: _createTable
    }
});
<|endoftext|>


<commit_before>'use strict';

angular.module('doc.client', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/client', {
    templateUrl: 'client/client.html',
    controller: 'ClientCtrl'
  });
  $routeProvider.when('/', {
    templateUrl: 'client/client.html',
    controller: 'ClientCtrl'
  });
}])

.controller('ClientCtrl', ["$scope", function($scope, $mdThemingProvider) {

	/* Definitions */
    $scope.theme = localStorage.getItem("theme_color");
    if($scope.theme === null || $scope.theme === undefined){
        $scope.theme = 'yellow';
    }

    $scope.darkTheme = localStorage.getItem("darkTheme");
    if($scope.darkTheme === null || $scope.darkTheme === undefined){
        $scope.darkTheme = true;
    }
    if($scope.darkTheme !== null && $scope.darkTheme !== undefined){
        $scope.darkTheme = ( $scope.darkTheme == 'true' );
    }

    $scope.favorites = localStorage.getItem("favorites");
    if($scope.favorites !== null && $scope.favorites !== undefined){
        $scope.favorites = JSON.parse($scope.favorites);
    }
    else {
        $scope.favorites = [];
    }

	$scope.queue = [];
    $scope.history = [];
    $scope.volume = 0;
    $scope.mute = false;
	$scope.currentlyPlaying = null;
    $scope.currentlyPlayingAuto = false;
    $scope.showFullQueue = false;
    $scope.showFullHistory= false;
    $scope.showFullFavorites = false;
    $scope.showFullSearch = false;
    $scope.historyHeight = "200px";
    $scope.queueHeight = "200px";
    $scope.favoritesHeight = "200px";
    $scope.searchHeight = "200px";
	$scope.chk = {
		recent: false,
		related: false,
		relatedToRecent: false
	}
	$scope.showControls = false;
	$scope.playbackState = false;
	$scope.magicModeState = true;
	$scope.playbackStateIcon = "play_arrow";
	$scope.playbackStateMessage = "Resume Playback";
	$scope.playbackMaxLengthState = true;
    $scope.tickerTapeTimer = null;
    $scope.tickerTapeCounter = 0;

    $scope.themeColors = [
        "red",
        "pink",
        "purple",
        "deep-purple",
        "indigo",
        "blue",
        "light-blue",
        "cyan",
        "teal",
        "green",
        "light-green",
        "lime",
        "yellow",
        "amber",
        "orange",
        "deep-orange",
        "brown",
        "grey",
        "blue-grey",
    ];

	/* Skip Current Song */
	$scope.skipSong = function(){
        client.send({
            type: "command",
            key: "set.skip",
            details: {}
        }, true);
    }

	$scope.clearRecent = function(){
        client.send({
            type: "command",
            key: "remove.history"
        }, true);
        $scope.history = [];
	}

	/* Playback State */

	$scope.playbackStateButtonClicked = function(){
        // send toggle command
        client.send({
            type: "command",
            key: "toggle.play_pause"
        }, true);

	};

    client.subscribe("toggle.play_pause", function(data){
        // update playback state
		$scope.playbackState = !$scope.playbackState;

        if($scope.playbackState){
            $scope.playbackStateIcon = "pause";
            $scope.playbackStateMessage = "Pause Playback";
        }
        else{
            $scope.playbackStateIcon = "play_arrow";
            $scope.playbackStateMessage = "Resume Playback";
        }
    });

    client.subscribe("get.play_pause", function(data){
        $scope.playbackState = data.payload.playing;

        if($scope.playbackState){
            $scope.playbackStateIcon = "pause";
            $scope.playbackStateMessage = "Pause Playback";
        }
        else{
            $scope.playbackStateIcon = "play_arrow";
            $scope.playbackStateMessage = "Resume Playback";
        }
    });

	/* Search Song */

	$scope.searchSong = function(){
        client.send({
            type: "command",
            key: "get.search",
            details: {
                query: $scope.url
            }
        })
    };

    client.subscribe("get.search", function(results){
        $scope.searchResults = results.payload;
        $scope.$apply();
    });

    $scope.requestSong = function(song){

        //validate the song isnt already in the queue
        for(var v of $scope.queue){
            if( song.id === v.id ){
                return;
            }
        }

        client.send({
            type: "command",
            key: "add.queue",
            details: song
        }, true);
    }

    client.subscribe("set.current_song", function(data){
        $scope.currentlyPlaying = data.payload.song;

        if($scope.tickerTapeTimer !== null){
            clearTimeout($scope.tickerTapeTimer);
        }
        $scope.tickerTapeTimer = setInterval(ticker_tape, 250)
    });

    client.subscribe("get.current_song", function(data){
        $scope.currentlyPlaying = data.payload;

        if($scope.tickerTapeTimer !== null){
            clearTimeout($scope.tickerTapeTimer);
        }
        $scope.tickerTapeTimer = setInterval(ticker_tape, 250)
    });

    function ticker_tape(){
        if ($scope.tickerTapeCounter >= $scope.currentlyPlaying.title.length){
            $scope.tickerTapeCounter = -5;
        }

        if($scope.tickerTapeCounter < 0){
            document.title = "Doc: " + $scope.currentlyPlaying.title;
            $scope.tickerTapeCounter += 1
            return
        }

        document.title = "Doc: " + $scope.currentlyPlaying.title.substring($scope.tickerTapeCounter, $scope.currentlyPlaying.title.length);
        console.log(document.title)

        $scope.tickerTapeCounter += 1
    }

    client.subscribe("set.skip", function(){
        $scope.currentlyPlaying = null;
    });

    $scope.clearSearch = function(){
        $scope.searchResults = [];
    }

    /* TODO REPLACE
    client.subscribe("add.queue", function(song){
        alert("Song Requested\n" + song.title);
    });
    */

    client.subscribe("get.queue", function(data){
        $scope.queue = data.payload;
        $scope.$apply();
        /*
         * TODO UPDATE TO get current and autoqueue status
        $scope.currentlyPlaying = queue.current;
        $scope.currentlyPlayingAuto = queue.auto;

        */
    });

    client.subscribe("remove.queue", function(data){
        var id = data.payload.id;
        for(var i=0; i < $scope.queue.length; i++){
            if( id === $scope.queue[i].id ){
                $scope.queue.splice(i, 1);
            }
        }
    });

    client.subscribe("add.queue", function(data){
        $scope.queue.push(data.details);

    });

	/* Hide/Show Controls */

	$scope.toggleControls = function(){
		$scope.showControls = !$scope.showControls;
	};

	/* Magic Mode */
	$scope.toggleMagicMode = function(){
        client.send({
            type: "command",
            key: "toggle.magic_mode"
        }, true);
	}

    client.subscribe("toggle.magic_mode", function(data){
		$scope.magicModeState = !$scope.magicModeState;
    });

    client.subscribe("get.magic_mode", function(data){
		$scope.magicModeState = data.payload.magic_mode;
    });

	/* Easter Eggs */
	$scope.easterEgg = function(){
		alert("It looked unbalanced without the one on the left...");
	}

	var egg = new Egg("up,up,down,down,left,right,left,right,b,a", function() {
        client.send({
            type: "command",
            key: "toggle.duration_limit"
        }, true);
	}).listen();

    client.subscribe("toggle.duration_limit", function(){
        $scope.playbackMaxLengthState = ! $scope.playbackMaxLengthState;
    })

    client.subscribe("get.duration_limit", function(data){
        $scope.playbackMaxLengthState = data.payload.duration_limit;
    });

    /* Volume Control */
    client.subscribe("get.volume", function(resp){
        $scope.volume = resp.payload.volume;
    });

    $scope.volumeUpdate = function(){
        if($scope.volume > 100) $scope.volume = 100;
        if($scope.volume < 0) $scope.volume = 0;

        client.send({
            type: "command",
            key: "set.volume",
            details: {
                volume: $scope.volume
            }
        }, true);
    }

    client.subscribe("set.volume", function(resp){
        $scope.volume = resp.details.volume;
    });

    client.subscribe("get.history", function(data){
        $scope.history = data.payload;
    });

    client.subscribe("add.history", function(data){
        $scope.history.push(data.payload);
    })

    client.subscribe("remove.history", function(){
        $scope.history = [];
    });

    $scope.addFavorite = function(song){
        /* check to see if already in favs*/
        for(var s of $scope.favorites){
            if(s.id === song.id){
                return;
            }
        }
        $scope.favorites.push(song)
        localStorage.setItem("favorites", JSON.stringify($scope.favorites));
    }

    $scope.rmFavorite = function(song){
        for(var i=0; i < $scope.favorites.length; i++){
            if(song.id === $scope.favorites[i].id){
                $scope.favorites.splice(i, 1);
                localStorage.setItem("favorites", JSON.stringify($scope.favorites));
            }
        }
    }

   $scope.toggleShowFullFavorites= function(){
        $scope.showFullFavorites = ! $scope.showFullFavorites
        $scope.favoritesHeight = $scope.favoritesHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullQueue = function(){
        $scope.showFullQueue = ! $scope.showFullQueue
        $scope.queueHeight = $scope.queueHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullHistory = function(){
        $scope.showFullHistory = ! $scope.showFullHistory
        $scope.historyHeight = $scope.historyHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullSearch = function(){
        $scope.showFullSearch = ! $scope.showFullSearch
        $scope.searchHeight = $scope.searchHeight === "200px" ? "500px" : "200px"
   }

   $scope.changeTheme = function(){
        localStorage.setItem("theme_color", $scope.theme);
        localStorage.setItem("darkTheme", $scope.darkTheme);
        location.reload();
    }

   client.registerInitHook(()=>{
        client.send({type:"command", key:"get.queue"});
        client.send({type:"command", key:"get.current_song"});
        client.send({type:"command", key:"get.play_pause"});
        client.send({type:"command", key:"get.magic_mode"});
        client.send({type:"command", key:"get.duration_limit"});
        client.send({type:"command", key:"get.volume"});
        client.send({type:"command", key:"get.history"});
    });

}]).
filter('capitalizeThemeName', function(){
    return function(input){
        var output = "";
        for(var i of input.split("-")){
            output += i.charAt(0).toUpperCase() + i.substring(1) + " ";
        }
        return output
    };
});
<commit_msg>removes console log<commit_after>'use strict';

angular.module('doc.client', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/client', {
    templateUrl: 'client/client.html',
    controller: 'ClientCtrl'
  });
  $routeProvider.when('/', {
    templateUrl: 'client/client.html',
    controller: 'ClientCtrl'
  });
}])

.controller('ClientCtrl', ["$scope", function($scope, $mdThemingProvider) {

	/* Definitions */
    $scope.theme = localStorage.getItem("theme_color");
    if($scope.theme === null || $scope.theme === undefined){
        $scope.theme = 'yellow';
    }

    $scope.darkTheme = localStorage.getItem("darkTheme");
    if($scope.darkTheme === null || $scope.darkTheme === undefined){
        $scope.darkTheme = true;
    }
    if($scope.darkTheme !== null && $scope.darkTheme !== undefined){
        $scope.darkTheme = ( $scope.darkTheme == 'true' );
    }

    $scope.favorites = localStorage.getItem("favorites");
    if($scope.favorites !== null && $scope.favorites !== undefined){
        $scope.favorites = JSON.parse($scope.favorites);
    }
    else {
        $scope.favorites = [];
    }

	$scope.queue = [];
    $scope.history = [];
    $scope.volume = 0;
    $scope.mute = false;
	$scope.currentlyPlaying = null;
    $scope.currentlyPlayingAuto = false;
    $scope.showFullQueue = false;
    $scope.showFullHistory= false;
    $scope.showFullFavorites = false;
    $scope.showFullSearch = false;
    $scope.historyHeight = "200px";
    $scope.queueHeight = "200px";
    $scope.favoritesHeight = "200px";
    $scope.searchHeight = "200px";
	$scope.chk = {
		recent: false,
		related: false,
		relatedToRecent: false
	}
	$scope.showControls = false;
	$scope.playbackState = false;
	$scope.magicModeState = true;
	$scope.playbackStateIcon = "play_arrow";
	$scope.playbackStateMessage = "Resume Playback";
	$scope.playbackMaxLengthState = true;
    $scope.tickerTapeTimer = null;
    $scope.tickerTapeCounter = 0;

    $scope.themeColors = [
        "red",
        "pink",
        "purple",
        "deep-purple",
        "indigo",
        "blue",
        "light-blue",
        "cyan",
        "teal",
        "green",
        "light-green",
        "lime",
        "yellow",
        "amber",
        "orange",
        "deep-orange",
        "brown",
        "grey",
        "blue-grey",
    ];

	/* Skip Current Song */
	$scope.skipSong = function(){
        client.send({
            type: "command",
            key: "set.skip",
            details: {}
        }, true);
    }

	$scope.clearRecent = function(){
        client.send({
            type: "command",
            key: "remove.history"
        }, true);
        $scope.history = [];
	}

	/* Playback State */

	$scope.playbackStateButtonClicked = function(){
        // send toggle command
        client.send({
            type: "command",
            key: "toggle.play_pause"
        }, true);

	};

    client.subscribe("toggle.play_pause", function(data){
        // update playback state
		$scope.playbackState = !$scope.playbackState;

        if($scope.playbackState){
            $scope.playbackStateIcon = "pause";
            $scope.playbackStateMessage = "Pause Playback";
        }
        else{
            $scope.playbackStateIcon = "play_arrow";
            $scope.playbackStateMessage = "Resume Playback";
        }
    });

    client.subscribe("get.play_pause", function(data){
        $scope.playbackState = data.payload.playing;

        if($scope.playbackState){
            $scope.playbackStateIcon = "pause";
            $scope.playbackStateMessage = "Pause Playback";
        }
        else{
            $scope.playbackStateIcon = "play_arrow";
            $scope.playbackStateMessage = "Resume Playback";
        }
    });

	/* Search Song */

	$scope.searchSong = function(){
        client.send({
            type: "command",
            key: "get.search",
            details: {
                query: $scope.url
            }
        })
    };

    client.subscribe("get.search", function(results){
        $scope.searchResults = results.payload;
        $scope.$apply();
    });

    $scope.requestSong = function(song){

        //validate the song isnt already in the queue
        for(var v of $scope.queue){
            if( song.id === v.id ){
                return;
            }
        }

        client.send({
            type: "command",
            key: "add.queue",
            details: song
        }, true);
    }

    client.subscribe("set.current_song", function(data){
        $scope.currentlyPlaying = data.payload.song;

        if($scope.tickerTapeTimer !== null){
            clearTimeout($scope.tickerTapeTimer);
        }
        $scope.tickerTapeTimer = setInterval(ticker_tape, 250)
    });

    client.subscribe("get.current_song", function(data){
        $scope.currentlyPlaying = data.payload;

        if($scope.tickerTapeTimer !== null){
            clearTimeout($scope.tickerTapeTimer);
        }
        $scope.tickerTapeTimer = setInterval(ticker_tape, 250)
    });

    function ticker_tape(){
        if ($scope.tickerTapeCounter >= $scope.currentlyPlaying.title.length){
            $scope.tickerTapeCounter = -5;
        }

        if($scope.tickerTapeCounter < 0){
            document.title = "Doc: " + $scope.currentlyPlaying.title;
            $scope.tickerTapeCounter += 1
            return
        }

        document.title = "Doc: " + $scope.currentlyPlaying.title.substring($scope.tickerTapeCounter, $scope.currentlyPlaying.title.length);

        $scope.tickerTapeCounter += 1
    }

    client.subscribe("set.skip", function(){
        $scope.currentlyPlaying = null;
    });

    $scope.clearSearch = function(){
        $scope.searchResults = [];
    }

    /* TODO REPLACE
    client.subscribe("add.queue", function(song){
        alert("Song Requested\n" + song.title);
    });
    */

    client.subscribe("get.queue", function(data){
        $scope.queue = data.payload;
        $scope.$apply();
        /*
         * TODO UPDATE TO get current and autoqueue status
        $scope.currentlyPlaying = queue.current;
        $scope.currentlyPlayingAuto = queue.auto;

        */
    });

    client.subscribe("remove.queue", function(data){
        var id = data.payload.id;
        for(var i=0; i < $scope.queue.length; i++){
            if( id === $scope.queue[i].id ){
                $scope.queue.splice(i, 1);
            }
        }
    });

    client.subscribe("add.queue", function(data){
        $scope.queue.push(data.details);

    });

	/* Hide/Show Controls */

	$scope.toggleControls = function(){
		$scope.showControls = !$scope.showControls;
	};

	/* Magic Mode */
	$scope.toggleMagicMode = function(){
        client.send({
            type: "command",
            key: "toggle.magic_mode"
        }, true);
	}

    client.subscribe("toggle.magic_mode", function(data){
		$scope.magicModeState = !$scope.magicModeState;
    });

    client.subscribe("get.magic_mode", function(data){
		$scope.magicModeState = data.payload.magic_mode;
    });

	/* Easter Eggs */
	$scope.easterEgg = function(){
		alert("It looked unbalanced without the one on the left...");
	}

	var egg = new Egg("up,up,down,down,left,right,left,right,b,a", function() {
        client.send({
            type: "command",
            key: "toggle.duration_limit"
        }, true);
	}).listen();

    client.subscribe("toggle.duration_limit", function(){
        $scope.playbackMaxLengthState = ! $scope.playbackMaxLengthState;
    })

    client.subscribe("get.duration_limit", function(data){
        $scope.playbackMaxLengthState = data.payload.duration_limit;
    });

    /* Volume Control */
    client.subscribe("get.volume", function(resp){
        $scope.volume = resp.payload.volume;
    });

    $scope.volumeUpdate = function(){
        if($scope.volume > 100) $scope.volume = 100;
        if($scope.volume < 0) $scope.volume = 0;

        client.send({
            type: "command",
            key: "set.volume",
            details: {
                volume: $scope.volume
            }
        }, true);
    }

    client.subscribe("set.volume", function(resp){
        $scope.volume = resp.details.volume;
    });

    client.subscribe("get.history", function(data){
        $scope.history = data.payload;
    });

    client.subscribe("add.history", function(data){
        $scope.history.push(data.payload);
    })

    client.subscribe("remove.history", function(){
        $scope.history = [];
    });

    $scope.addFavorite = function(song){
        /* check to see if already in favs*/
        for(var s of $scope.favorites){
            if(s.id === song.id){
                return;
            }
        }
        $scope.favorites.push(song)
        localStorage.setItem("favorites", JSON.stringify($scope.favorites));
    }

    $scope.rmFavorite = function(song){
        for(var i=0; i < $scope.favorites.length; i++){
            if(song.id === $scope.favorites[i].id){
                $scope.favorites.splice(i, 1);
                localStorage.setItem("favorites", JSON.stringify($scope.favorites));
            }
        }
    }

   $scope.toggleShowFullFavorites= function(){
        $scope.showFullFavorites = ! $scope.showFullFavorites
        $scope.favoritesHeight = $scope.favoritesHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullQueue = function(){
        $scope.showFullQueue = ! $scope.showFullQueue
        $scope.queueHeight = $scope.queueHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullHistory = function(){
        $scope.showFullHistory = ! $scope.showFullHistory
        $scope.historyHeight = $scope.historyHeight === "200px" ? "500px" : "200px"
   }

   $scope.toggleShowFullSearch = function(){
        $scope.showFullSearch = ! $scope.showFullSearch
        $scope.searchHeight = $scope.searchHeight === "200px" ? "500px" : "200px"
   }

   $scope.changeTheme = function(){
        localStorage.setItem("theme_color", $scope.theme);
        localStorage.setItem("darkTheme", $scope.darkTheme);
        location.reload();
    }

   client.registerInitHook(()=>{
        client.send({type:"command", key:"get.queue"});
        client.send({type:"command", key:"get.current_song"});
        client.send({type:"command", key:"get.play_pause"});
        client.send({type:"command", key:"get.magic_mode"});
        client.send({type:"command", key:"get.duration_limit"});
        client.send({type:"command", key:"get.volume"});
        client.send({type:"command", key:"get.history"});
    });

}]).
filter('capitalizeThemeName', function(){
    return function(input){
        var output = "";
        for(var i of input.split("-")){
            output += i.charAt(0).toUpperCase() + i.substring(1) + " ";
        }
        return output
    };
});
<|endoftext|>


<commit_before>//  punctuation-cleanup.js
//  use:   $ node punctuation-cleanup.js  file-to-clean.txt  cleaned-file.txt
/*
 * MIT license http://opensource.org/licenses/MIT
 *
 * Original author of this script: rsperberg@gmail.com
 */

var fs = require("fs");

//  identify each type of change, particularly for the apostrophe, since global change (e.g., /.'./g or /(\w|\d)'(\w|\d)/g) is just too risky
//  By making only known changes, stray apostrophes and quotes can be located easily
//  not yet defined:  single quotes within double quotes

var replacements = [
    { searchFor: /Character set encoding: ASCII/, replaceWith: "Character set encoding: UTF-8"},  //  dashes and curly quotes aren't in ASCII
    { searchFor: /(That|this) 'ere/g, replaceWith: "$1 ’ere"},   //  elided consonant (Youth)
    { searchFor: /([C|c]atch|Give|Eat) 'im/g, replaceWith: "$1 ’im"},   //  Catch 'im, Give 'im (Heart of Darkness)
    { searchFor: /^'im\./gm, replaceWith: "’im."},   //  catch 'im (Heart of Darkness) [Be specific so as not to change something unwittingly]
    { searchFor: /'d\b/g, replaceWith: "’d"},    // I'd
    { searchFor: /'ll\b/g, replaceWith: "’ll"},    //  you'll
    { searchFor: /'m\b/g, replaceWith: "’m"},    //  I'm
    { searchFor: /'re\b/g, replaceWith: "’re"},    //  you're
    { searchFor: /'(s|S)\b/g, replaceWith: "’$1"},    //  it's, GRIMM'S (Youth)
    { searchFor: /s'(\s)/g, replaceWith: "s’$1"},    //  plural possessive
    { searchFor: /'st\b/g, replaceWith: "’st"},    //  look'st (Rime of the Ancient Mariner)
    { searchFor: /'t\b/g, replaceWith: "’t"},   //  don't
    { searchFor: /'ve\b/g, replaceWith: "’ve"},   //  I've
    { searchFor: /(\s)'(\d\ds)/g, replaceWith: "$1’$2"},   //  ’90s
    { searchFor: /O'([A-Z])/g, replaceWith: "O’$1"},    //  O'Reilly
    { searchFor: /(o|e)'e/g, replaceWith: "$1’e"},    //  o'er, ne'er (Rime)
    { searchFor: /(sou)'west/g, replaceWith: "$1’west"},    //  sou'west (Youth)
    { searchFor: /'(em|gan)\b/g, replaceWith: "’em"},    //  'em, 'gan  (Rime)
//    { searchFor: /",/g, replaceWith: ',”'},    // comma outside quote mark
//    { searchFor: /"\./g, replaceWith: '.”'},    // period outside quote mark (transpose only)
    { searchFor: /"\b/g, replaceWith: '“'},    //  open quote (eg, precedes a 'word boundary')
    { searchFor: /(\?)"' /g, replaceWith: '$1”’ '},    //  close double quote preceding close single quote at sentence end
    { searchFor: /\b"/g, replaceWith: '”'},    //  close quote (eg, is preceded by a 'word boundary') needs to be set to follow punctuation as well
    { searchFor: /\b([\.|,|\?|!|;|:|-])"/g, replaceWith: '$1”'},    //  close quote after period (eg, is preceded by a 'word boundary')
    { searchFor: /'(Twas|Tis|twas|tis)/g, replaceWith: '’$1'},    //  'Twas, 'tis
    { searchFor: / - /g, replaceWith: " — "},    //  em dash between spaces
    { searchFor: /(\w)-- /g, replaceWith: "$1— "},    //  em dash after character followed by space
    { searchFor: /(\w)--'(\w)/g, replaceWith: "$1—‘$2"},    //  em dash after character followed by right single quote and space
    { searchFor: /(\w)'--(\w)/g, replaceWith: "$1’—$2"},    //  right single quote after character followed by em dash
    { searchFor: /(\w)'-(\w)/g, replaceWith: "$1’-$2"},    //  right single quote after character followed by hyphen and character (stun'-sails, Youth)
    { searchFor: /(\w)--' /g, replaceWith: "$1—’ "},    //  em dash after character followed by right single quote and space
    { searchFor: /(\w)'; /g, replaceWith: "$1’; "},    //  apostrophe after character followed by semi-colon and space
    { searchFor: /(\?)--\b/g, replaceWith: "$1—"},    //  em dash after question mark followed by word boundary
    { searchFor: /(\w)--"$/gm, replaceWith: '$1—”'},    //  em dash after character followed by right double quote at line end
    { searchFor: /(\w)--'$/gm, replaceWith: "$1—’"},    //  em dash after character followed by right single quote at line end
    { searchFor: /(\w|!|,|\?|”)--$/gm, replaceWith: "$1—"},    //  em dash after character at end of line
    { searchFor: /(\w|!|,|\?|”)'--'/g, replaceWith: "$1’—‘"},    //  em dash after left single quote followed by right single quote
    { searchFor: /(\w|!|,|\?|”)'--(\w)/g, replaceWith: "$1’—$2"},    //  em dash after left single quote followed by right single quote
    { searchFor: /(\w|”)--(\w|“|\s)/gm, replaceWith: "$1—$2"},    //  em dash after characters (or quote) followed by letter
    { searchFor: /(!|,)--(\w|“|\s)/gm, replaceWith: "$1—$2"},    //  em dash after punctuation and before characters (and between quotes)
    { searchFor: / '(Change)/g, replaceWith: " ’$1"},    //  'Change (Heart of Darkness)
    { searchFor: / '([A-Z])/g, replaceWith: " ‘$1"},    //  'Word (inner quote)
    { searchFor: / '([a-z])/g, replaceWith: " ‘$1"},    //  'word (inner quote, as in Heart of Darkness)
    { searchFor: /(\.|\?|!)'\.\.\./g, replaceWith: "$1’..."},    //  close single quote after end punctuation followed by ellipsis
    { searchFor: /(\w|,|\.|\?|!|;|:|-)' /g, replaceWith: "$1’ "},    //  close single quote after period etc
    { searchFor: /(\w|,|\.|\?|!|;|:|-)'$/gm, replaceWith: "$1’"},    //  close single quote after period etc at end of line
    { searchFor: /^'\b/gm, replaceWith: '‘'},    //  open single quote line beginning (eg, precedes a 'word boundary')
    { searchFor: /^"'\b/gm, replaceWith: '“‘'},    //  open double quote preceding open single quote at line beginning (eg, precedes a 'word boundary')
    { searchFor: /(\w)'\.\.\.$/gm, replaceWith: "$1’..."},    //  em dash after character followed by space
    { searchFor: /(\w)\.\.\.(\.|!)?"$/gm, replaceWith: '$1...$2”'},    //  em dash after character followed by space (Youth)
    { searchFor: /^"\.\.\./gm, replaceWith: '“...'},    //  open quote at line beginning, followed by ellipsis
    { searchFor: /^(\s*)"\.\.\./gm, replaceWith: '$1“...'},    //  spaces then open quote at line beginning, followed by ellipsis (Youth)
    { searchFor: /^"'\.\.\./gm, replaceWith: '“‘...'},    //  open quote then open single quote at line beginning, followed by ellipsis
    { searchFor: /(d)'ye/g, replaceWith: "$1’ye"},   //  d'ye (Heart of Darkness)
    { searchFor: /(:|,) '_(\w)/g, replaceWith: "$1 ‘_$2"}   //  italic inside single quote, markdown (Youth)
];
//  sou'west
var inFile = process.argv[2];
var outFile = process.argv[3]

// using package.json script: cleanup to read README.md via cat
var aFile = fs.readFile(inFile, 'utf8', function (err,data) {
    if (err) {
        return console.log(err);
    }

    //  for each object in the replacements array, go through the document and make the replacement
    function cleanUp(someFile) {
        replacements.forEach(function(replacement) {
            someFile = someFile.replace(replacement.searchFor, replacement.replaceWith);
        })
        return someFile;
   }
    var result = cleanUp(data);
    // now pipe the result to be stored in build/README.md
//    console.log(result);

    fs.writeFile(outFile, result, function (err) {
        if (err) throw err;
        console.log('It\'s saved!');
    });

});
<commit_msg>add patterns discovered in 'Narcissus'<commit_after>//  punctuation-cleanup.js
//  use:   $ node punctuation-cleanup.js  file-to-clean.txt  cleaned-file.txt
/*
 * MIT license http://opensource.org/licenses/MIT
 *
 * Original author of this script: rsperberg@gmail.com
 */

var fs = require("fs");

//  identify each type of change, particularly for the apostrophe, since global change (e.g., /.'./g or /(\w|\d)'(\w|\d)/g) is just too risky
//  By making only known changes, stray apostrophes and quotes can be located easily
//  not yet defined:  single quotes within double quotes

var replacements = [
    { searchFor: /Character set encoding: ASCII/, replaceWith: "Character set encoding: UTF-8"},  //  dashes and curly quotes aren't in ASCII
    { searchFor: /(That|that|this) 'ere/g, replaceWith: "$1 ’ere"},   //  elided consonant: (h)ere (Youth)
    { searchFor: /black 'arts/g, replaceWith: "black ’arts"},   //  black (he)arts (Conrad 'Narcissus')
    { searchFor: /fo'c'sle/g, replaceWith: "fo’c’sle"},   //  fo'c'sle (forecastle) (Conrad 'Narcissus')
    { searchFor: /(A|a)'n't/g, replaceWith: "$1’n’t"},   //  ain't (Conrad 'Narcissus')
    { searchFor: /'art/g, replaceWith: "’art"},   //  (he)art (Conrad 'Narcissus')
    { searchFor: /'art/g, replaceWith: "’art"},   //  (he)art (Conrad 'Narcissus')
    { searchFor: /'(As|as)\b/g, replaceWith: "’$1"},   //  (h)ard (Conrad 'Narcissus')
    { searchFor: /"'(Cos)/g, replaceWith: "“’$1"},   //  (be)cause (Conrad 'Narcissus')
    { searchFor: /'(Cos|cos)/g, replaceWith: "’$1"},   //  (be)cause (Conrad 'Narcissus')
    { searchFor: / 'ome/g, replaceWith: " ’ome"},   //  (h)omeward (Conrad 'Narcissus')
    { searchFor: / '(ed|ad|un)\b/g, replaceWith: " ’$1"},   //  (h)e(a)d, (h)ad, good 'un (Conrad 'Narcissus')
    { searchFor: /([C|c]atch|Give|Eat) 'im/g, replaceWith: "$1 ’im"},   //  Catch 'im, Give 'im (Heart of Darkness)
    { searchFor: /^'im\./gm, replaceWith: "’im."},   //  catch 'im (Heart of Darkness) [Be specific so as not to change something unwittingly]
    { searchFor: /'d\b/g, replaceWith: "’d"},    // I'd
    { searchFor: /'ll\b/g, replaceWith: "’ll"},    //  you'll
    { searchFor: /'m\b/g, replaceWith: "’m"},    //  I'm
    { searchFor: /'re\b/g, replaceWith: "’re"},    //  you're
    { searchFor: /'(s|S)\b/g, replaceWith: "’$1"},    //  it's, GRIMM'S (Youth)
    { searchFor: /s'(\s)/g, replaceWith: "s’$1"},    //  plural possessive
    { searchFor: /s'(long)/g, replaceWith: "s’$1"},    //  s'long (Conrad 'Narcissus')
    { searchFor: /'st\b/g, replaceWith: "’st"},    //  look'st (Rime of the Ancient Mariner)
    { searchFor: /'t\b/g, replaceWith: "’t"},   //  don't
    { searchFor: /'ve\b/g, replaceWith: "’ve"},   //  I've
    { searchFor: /(\s)'(\d\ds)/g, replaceWith: "$1’$2"},   //  ’90s
    { searchFor: /O'([A-Z])/g, replaceWith: "O’$1"},    //  O'Reilly
    { searchFor: /o'clock/g, replaceWith: "o’clock"},    //  o'clock
    { searchFor: /(o|e)'e/g, replaceWith: "$1’e"},    //  o'er, ne'er (Rime)
    { searchFor: /(sou)'west/g, replaceWith: "$1’west"},    //  sou'west (Youth)
    { searchFor: /'(em|gan|baccy|ave|ee )\b/g, replaceWith: "’$1"},    //  'em, 'gan  (Rime), 'baccy, 'ave, 'ee (Conrad 'Narcissus')
    { searchFor: /'ave/g, replaceWith: "’ave"},    //   'ave, 'aven't (Conrad 'Narcissus')
//    { searchFor: /",/g, replaceWith: ',”'},    // comma outside quote mark
//    { searchFor: /"\./g, replaceWith: '.”'},    // period outside quote mark (transpose only)
    { searchFor: /"\b/g, replaceWith: '“'},    //  open quote (eg, precedes a 'word boundary')
    { searchFor: /(\?)"' /g, replaceWith: '$1”’ '},    //  close double quote preceding close single quote at sentence end
    { searchFor: /\b"/g, replaceWith: '”'},    //  close quote (eg, is preceded by a 'word boundary') needs to be set to follow punctuation as well
    { searchFor: /\b([\.|,|\?|!|;|:|-])"/g, replaceWith: '$1”'},    //  close quote after period (eg, is preceded by a 'word boundary')
    { searchFor: /'(Twas|Tis|twas|tis)/g, replaceWith: '’$1'},    //  'Twas, 'tis
    { searchFor: / - /g, replaceWith: " — "},    //  em dash between spaces
    { searchFor: /(\w)-- /g, replaceWith: "$1— "},    //  em dash after character followed by space
    { searchFor: /(\w)--'(\w)/g, replaceWith: "$1—‘$2"},    //  em dash after character followed by right single quote and space
    { searchFor: /(\w)'--(\w)/g, replaceWith: "$1’—$2"},    //  right single quote after character followed by em dash
    { searchFor: /(\w)'-(\w)/g, replaceWith: "$1’-$2"},    //  right single quote after character followed by hyphen and character (stun'-sails, Youth)
    { searchFor: /(\w)--' /g, replaceWith: "$1—’ "},    //  em dash after character followed by right single quote and space
    { searchFor: /(\w)'; /g, replaceWith: "$1’; "},    //  apostrophe after character followed by semi-colon and space
    { searchFor: /----(--)?/g, replaceWith: "——"},    //  2-em dash (Conrad 'Narcissus')
    { searchFor: /(\?)--\b/g, replaceWith: "$1—"},    //  em dash after question mark followed by word boundary
    { searchFor: /(\w)--"$/gm, replaceWith: '$1—”'},    //  em dash after character followed by right double quote at line end
    { searchFor: /(\w)--'$/gm, replaceWith: "$1—’"},    //  em dash after character followed by right single quote at line end
    { searchFor: /(\w|!|,|\?|”)--$/gm, replaceWith: "$1—"},    //  em dash after character at end of line
    { searchFor: /(\w)--!\.\.\."$/gm, replaceWith: '$1—!...”'},    //  by--!..."  (Conrad 'Narcissus')
    { searchFor: /(\w|!|,|\?|”)'--'/g, replaceWith: "$1’—‘"},    //  em dash after left single quote followed by right single quote
    { searchFor: /(\w|!|,|\?|”)'--(\w)/g, replaceWith: "$1’—$2"},    //  em dash after left single quote followed by right single quote
    { searchFor: /(\w|”)--(\w|“|\s)/gm, replaceWith: "$1—$2"},    //  em dash after characters (or quote) followed by letter
    { searchFor: /(!|,|:|\.)--(\w|“|\s)/gm, replaceWith: "$1—$2"},    //  em dash after punctuation and before characters (and between quotes)
    { searchFor: / '(Change)/g, replaceWith: " ’$1"},    //  'Change (Heart of Darkness)
    { searchFor: / '([A-Z])/g, replaceWith: " ‘$1"},    //  'Word (inner quote)
    { searchFor: / '([a-z])/g, replaceWith: " ‘$1"},    //  'word (inner quote, as in Heart of Darkness)
    { searchFor: /(\.|\?|!)'\.\.\./g, replaceWith: "$1’..."},    //  close single quote after end punctuation followed by ellipsis
    { searchFor: /(\w|,|\.|\?|!|;|:|-)' /g, replaceWith: "$1’ "},    //  close single quote after period etc
    { searchFor: /(\w|,|\.|\?|!|;|:|-)'$/gm, replaceWith: "$1’"},    //  close single quote after period etc at end of line
    { searchFor: /^(\s*)?'\b/gm, replaceWith: '$1‘'},    //  open single quote line beginning (eg, precedes a 'word boundary')
    { searchFor: /(\w)'" /g, replaceWith: '$1’” '},    //  close single quote followed by close double quote and space
    { searchFor: /^(\s*)?"'\b/gm, replaceWith: '$1“‘'},    //  open double quote preceding open single quote at line beginning (eg, precedes a 'word boundary')
    { searchFor: /(\w)'\.\.\.$/gm, replaceWith: "$1’..."},    //  em dash after character followed by space
    { searchFor: /(\w)(!)\.\.\.(\.|!)?"$/gm, replaceWith: '$1$2...$destroy”'},    //  em dash after character followed by space (Youth)
    { searchFor: /^(\s*)?"\.\.\./gm, replaceWith: '$1“...'},    //  open quote at line beginning, followed by ellipsis
    { searchFor: /^(\s*)"\.\.\./gm, replaceWith: '$1“...'},    //  spaces then open quote at line beginning, followed by ellipsis (Youth)
    { searchFor: /^(\s*)?"'\.\.\./gm, replaceWith: '$1“‘...'},    //  open quote then open single quote at line beginning, followed by ellipsis
    { searchFor: /(D|d)'ye/g, replaceWith: "$1’ye"},   //  d'ye (Heart of Darkness)
    { searchFor: /(:|,) '_(\w)/g, replaceWith: "$1 ‘_$2"},   //  italic inside single quote, markdown (Youth)
    { searchFor: / '<i>/g, replaceWith: " ‘<i>"}   //  italic inside single quote, html (Heart of Darkness)
];

var inFile = process.argv[2];
var outFile = process.argv[3]

// using package.json script: cleanup to read README.md via cat
var aFile = fs.readFile(inFile, 'utf8', function (err,data) {
    if (err) {
        return console.log(err);
    }

    //  for each object in the replacements array, go through the document and make the replacement
    function cleanUp(someFile) {
        replacements.forEach(function(replacement) {
            someFile = someFile.replace(replacement.searchFor, replacement.replaceWith);
        })
        return someFile;
   }
    var result = cleanUp(data);
    // now pipe the result to be stored in build/README.md
//    console.log(result);

    fs.writeFile(outFile, result, function (err) {
        if (err) throw err;
        console.log('It\'s saved!');
    });

});
<|endoftext|>


<commit_before>const isVisible = require('./common_functions').isVisible;
const Url = require('./url');

const ScrollToAnchor = (() => {
    const init = () => {
        scrollToAnchorInQuery();
        addAnchorsToElements();
    };

    const makeAnchorLink = (id) => {
        const anchor_link = document.createElement('a');
        const url = new URL(window.location);
        url.search = `anchor=${encodeURI(id)}`;
        anchor_link.href = url.href;
        anchor_link.classList.add('data-anchor-link');
        return anchor_link;
    };

    const addAnchorsToElements = () => {
        const els = document.querySelectorAll('[data-anchor]');
        els.forEach(el => {
            const id = el.dataset.anchor;
            const anchor_link = makeAnchorLink(id);
            el.appendChild(anchor_link);
            anchor_link.addEventListener('click', (e) => {
                e.preventDefault();
                $.scrollTo(el, 500);
                const params = Url.paramsHash();
                params.anchor = window.encodeURI(id);
                Url.setQueryStringWithoutReload(
                    Url.paramsHashToString(params)
                );
            });
        });
    };

    const scrollToAnchorInQuery = () => {
        const params = Url.paramsHash();
        const id = window.decodeURI(params.anchor);
        if (!id) return;
        const candidates = document.querySelectorAll(`[data-anchor="${id}"]`);
        const el = Array.from(candidates).find(isVisible);
        if (!el) return;
        $.scrollTo(el, 500);
    };

    const cleanup = () => {
        const params = Url.paramsHash();
        delete params.anchor;
        const new_query_string = Url.paramsHashToString(params);
        Url.setQueryStringWithoutReload(new_query_string);
    };

    return {
        init,
        cleanup,
    };
})();

module.exports = ScrollToAnchor;<commit_msg>custom encode function<commit_after>const isVisible = require('./common_functions').isVisible;
const Url = require('./url');

const ScrollToAnchor = (() => {
    const init = () => {
        addAnchorsToElements();
        scrollToAnchorInQuery();
    };

    const encode = (str) => {
        const prep = str.toLowerCase().replace(/\s/g, '-');
        return encodeURI(prep);
    };

    const makeAnchorLink = (id) => {
        const anchor_link = document.createElement('a');
        const url = new URL(window.location);
        url.search = `anchor=${id}`;
        anchor_link.href = url.href;
        anchor_link.classList.add('data-anchor-link');
        return anchor_link;
    };

    const addAnchorsToElements = () => {
        const els = document.querySelectorAll('[data-anchor]');
        els.forEach(el => {
            const title = el.dataset.anchor;
            const id = encode(title);
            el.dataset.anchor = id;
            const anchor_link = makeAnchorLink(id);
            el.appendChild(anchor_link);
            anchor_link.addEventListener('click', (e) => {
                e.preventDefault();
                $.scrollTo(el, 500);
                const params = Url.paramsHash();
                params.anchor = id;
                Url.setQueryStringWithoutReload(
                    Url.paramsHashToString(params)
                );
            });
        });
    };

    const scrollToAnchorInQuery = () => {
        const params = Url.paramsHash();
        const id = params.anchor;
        if (!id) return;
        const candidates = document.querySelectorAll(`[data-anchor="${id}"]`);
        const el = Array.from(candidates).find(isVisible);
        if (!el) return;
        $.scrollTo(el, 500);
    };

    const cleanup = () => {
        const params = Url.paramsHash();
        delete params.anchor;
        const new_query_string = Url.paramsHashToString(params);
        Url.setQueryStringWithoutReload(new_query_string);
    };

    return {
        init,
        cleanup,
    };
})();

module.exports = ScrollToAnchor;<|endoftext|>


<commit_before>import React from 'react';
import Login from 'react-native-login';
import {
  Text,
  View,
  Body,
  Button,
  Col,
  Icon,
  Container,
  Content,
} from 'native-base';

const styles = {
  buttonBigText: {
    fontSize: 20,
    padding: 15,
    fontWeight: 'bold',
  },
  buttonRedText: {
    color: '#db3236',
  },
  buttonBlackText: {
    color: '#000',
  },
  inline: {
    flexDirection: 'row',
  },
};

export default class LoginScreen extends React.Component {
  keycloakConfig = {};

  static navigationOptions = {
    title: 'Login',
  };

  constructor(props) {
    super(props);
    this.keycloakConfig = props.navigation.state.params.keycloakConfig;
  }

  _login(loginServicePref) {
    var usableConfig = Object.assign({}, this.keycloakConfig, {
      kc_idp_hint: loginServicePref,
    });
    Login.start(usableConfig);
  }

  render() {
    return (
      <Container style={{ padding: 30 }}>

        <Content>

          <Button iconLeft transparent onPress={() => this._login('github')}>
            <Icon name="logo-github" size={40} style={styles.buttonBlackText} />
            <Text
              style={{ ...styles.buttonBlackText, ...styles.buttonBigText }}
            >
              Sign-in with GitHub
            </Text>
          </Button>
          <Button iconLeft transparent onPress={() => this._login('google')}>
            <Icon
              name="logo-googleplus"
              size={40}
              style={styles.buttonRedText}
            />
            <Text style={{ ...styles.buttonRedText, ...styles.buttonBigText }}>
              Sign-in with Google
            </Text>
          </Button>

        </Content>

      </Container>
    );
  }
}
<commit_msg>Facebook<commit_after>import React from 'react';
import Login from 'react-native-login';
import {
  Text,
  View,
  Body,
  Button,
  Col,
  Icon,
  Container,
  Content,
} from 'native-base';

const styles = {
  buttonBigText: {
    fontSize: 20,
    padding: 15,
    fontWeight: 'bold',
  },
  buttonBlueText: {
    color: '#3b5998',
  },
  buttonBlackText: {
    color: '#000',
  },
  inline: {
    flexDirection: 'row',
  },
};

export default class LoginScreen extends React.Component {
  keycloakConfig = {};

  static navigationOptions = {
    title: 'Login',
  };

  constructor(props) {
    super(props);
    this.keycloakConfig = props.navigation.state.params.keycloakConfig;
  }

  _login(loginServicePref) {
    var usableConfig = Object.assign({}, this.keycloakConfig, {
      kc_idp_hint: loginServicePref,
    });
    Login.start(usableConfig);
  }

  render() {
    return (
      <Container style={{ padding: 30 }}>

        <Content>

          <Button iconLeft transparent onPress={() => this._login('github')}>
            <Icon name="logo-github" size={40} style={styles.buttonBlackText} />
            <Text
              style={{ ...styles.buttonBlackText, ...styles.buttonBigText }}
            >
              Sign-in with GitHub
            </Text>
          </Button>
          <Button iconLeft transparent onPress={() => this._login('facebook')}>
            <Icon
              name="logo-facebook"
              size={40}
              style={styles.buttonBlueText}
            />
            <Text style={{ ...styles.buttonBlueText, ...styles.buttonBigText }}>
              Sign-in with Facebook
            </Text>
          </Button>

        </Content>

      </Container>
    );
  }
}
<|endoftext|>