<commit_before>#!/usr/bin/env node
'use strict';

var url = require('url');
var path = require('path');
var client = require('http-request');
var cheerio = require('cheerio');
var shell = require('shelljs');

function fname(urlString) {
    var parsed = url.parse(urlString);
    var pathname = parsed.pathname.replace(/\/(index\.html)?$/, '/index.html');
    return parsed.hostname + pathname.split('/').map(encodeURIComponent).join('/') + (parsed.query ? encodeURIComponent('?' + parsed.query) : '');
}

function writeAsset(name, res) {
    shell.mkdir('-p', path.dirname(name));
    fs.writeFileSync(name, res.data, 'utf8');
}

// keepalive
function setKeepalive() {
    var http = require('http');
    var https = require('https');

    var keepAliveAgent = new http.Agent({ keepAlive: true });
    http.globalAgent = keepAliveAgent;
    https.globalAgent = keepAliveAgent;
}

function wget(urlString, options) {
    if (!urlString) return;

    console.log('fetch\\', urlString, options._.length);
    var fetchOpts = {
        url: urlString,
        headers: options.headers,

        stream: true,
        noRedirect: false
    };
    client.get(fetchOpts, function(err, res) {
        let next = _ => {
            console.log('fetch/', res.code);
            wget(options._.shift(), options);
        };

        if (err) {
            res = err;
            console.error(urlString + ':', err);
            next();
            return;
        }

        res.url = urlString;
        if (res.headers['content-type'] !== 'text/html') {
            next();
            return;
        }

        var content = '';
        res.stream.on('data', chunk => content += chunk);
        res.stream.on('end', function() {
            res.data = content;
            res.$ = cheerio.load(content, {decodeEntities: false});

            if (!options.recursive) {
                options.process(res, options);
                next();
                return;
            }

            // recursively go through the links
            var hrefs = [];
            res.$('a[href]').each((idx, e) => hrefs.push(e.attribs.href));

            var base = res.$('html head base[href]').attr('href') || res.url;
            hrefs.forEach(href => {
                var absHref = url.resolve(base, href);

                // strip the href fragment
                absHref = absHref.replace(/\#.*/, '');

                if (options.acceptHref(absHref, href)) {
                    options._visited = options._visited || {};
                    var entry = options._visited[absHref];
                    if (!entry) {
                        options._visited[absHref] = true;
                        console.log('href', absHref, fname(absHref));

                        options._.push(absHref);
                    }
                }
            });

            options.process(res, options);
            next();
        });
    });
}

if (module.parent) {
    // for use as a node.js module
    // node -e 'require("./wget.js")("http://www.yahoo.com", {_: [], acceptHref: _ => _, process: _ => _})'
    module.exports = wget;
    return;
}

// command-line utility use
var argv = require('yargs')
    .usage('Usage: $0 [options] <url>')
    .demand(1)
    .example('$0 http://www.yahoo.com', 'fetch the site content')
    .option('np', {
        alias: 'no-parent',
        describe: `don't ascend to the parent directory`,
        boolean: true,
        default: false
    })
    .option('r', {
        alias: 'recursive',
        describe: `specify recursive download`,
        boolean: true,
        default: false
    })
    .option('P', {
        alias: 'directory-prefix',
        describe: `save files to PREFIX/...`,
        string: true,
        default: ''
    })
    .option('process', {
        describe: `javascript module/function handling the contents`,
        optional: true
    })
    // .alias('H', 'header')
    // .nargs('H', 1)
    // .describe('H', 'Request header')
    .help('h')
    .alias('h', 'help')
    // .epilog('Copyright 2016')
    .argv;

var firstUrl = argv._.shift();

// single origin only
firstUrl = firstUrl.match(/\w+:\/\//) ? firstUrl : 'http://' + firstUrl;
var parsedFirst = url.parse(firstUrl);

argv.acceptHref = href => {
    var parsedHref = url.parse(href);
    return parsedHref.host === parsedFirst.host &&
           parsedHref.protocol === parsedFirst.protocol;
};

if (argv.np) {
    // no-parent hrefs only
    argv.acceptHref = ((acceptHref) => href => {
        return href.startsWith(firstUrl) && acceptHref(href);
    })(argv.acceptHref);
}

try {
    argv.process = require(argv.process);
} catch(e) {
    try {
        argv.process = eval(argv.process);
    } catch(e) {
        argv.process = undefined;
    }

    var fs = require('fs');
    argv.process = argv.process || (res => {
        var name = path.normalize(path.join(argv.P, fname(res.url)));
        writeAsset(name, res);
        console.log('Done', res.url, res.code, '->', fname(res.url));
    });
}

argv.headers = {
  "accept-charset" : "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
  "accept-language" : "en-US,en;q=0.8",
  "accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  "user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
  "accept-encoding" : "gzip,deflate",
};

// if (typeof argv.header === 'string') argv.header = [argv.header];
// argv.header.forEach(h => {
//     var parts = h.split(':');
//     argv.headers[parts.shift()] = parts.join(':');
// })

setKeepalive();
wget(firstUrl, argv);
<commit_msg>Fetching also other resources than text/html<commit_after>#!/usr/bin/env node
'use strict';

var url = require('url');
var path = require('path');
var client = require('http-request');
var cheerio = require('cheerio');
var shell = require('shelljs');

function fname(urlString) {
    var parsed = url.parse(urlString);
    var pathname = parsed.pathname.replace(/\/(index\.html)?$/, '/index.html');
    return parsed.hostname + pathname.split('/').map(encodeURIComponent).join('/') + (parsed.query ? encodeURIComponent('?' + parsed.query) : '');
}

function writeAsset(name, res) {
    shell.mkdir('-p', path.dirname(name));
    fs.writeFileSync(name, res.buffer);
}

// keepalive
function setKeepalive() {
    var http = require('http');
    var https = require('https');

    var keepAliveAgent = new http.Agent({ keepAlive: true });
    http.globalAgent = keepAliveAgent;
    https.globalAgent = keepAliveAgent;
}

function parseRequest(res, options) {
    if (res.headers['content-type'] !== 'text/html') {
        return;
    }

    res.$ = cheerio.load(res.buffer.toString(), {decodeEntities: false});

    if (!options.recursive) {
        return;
    }

    // recursively go through the links
    var hrefs = [];

    // see http://html5doctor.com/microdata/ for the attributes...?
    res.$('a[href], link[href]').each((idx, e) => hrefs.push(e.attribs.href));
    res.$('script[src], img[src], embed[src], iframe[src], audio[src], video[src]').each((idx, e) => hrefs.push(e.attribs.src));

    var base = res.$('html head base[href]').attr('href') || res.url;
    hrefs.forEach(href => {
        var absHref = url.resolve(base, href);

        // strip the href fragment
        absHref = absHref.replace(/\#.*/, '');

        if (options.acceptHref(absHref, href)) {
            options._visited = options._visited || {};
            var entry = options._visited[absHref];
            if (!entry) {
                options._visited[absHref] = true;
                // console.log('href', absHref, fname(absHref));

                options._.push(absHref);
            }
        }
    });
}

function wget(urlString, options) {
    if (!urlString) return;

    console.log('fetch\\', urlString, options._.length);
    var fetchOpts = {
        url: urlString,
        headers: options.headers,

        // stream: true,
        noRedirect: false
    };
    client.get(fetchOpts, function(err, res) {
        let next = _ => {
            console.log('fetch/', res.code);
            wget(options._.shift(), options);
        };

        if (err) {
            res = err;
            console.error(urlString + ':', err);
            next();
            return;
        }

        function onEnd() {
            parseRequest(res, options);
            options.process(res, options);
            next();
        }

        res.url = urlString;

        if (!res.buffer) {
            var content = [];
            res.stream.on('error', function(err) {
                console.error('error:', err);
            });
            res.stream.on('data', chunk => (console.log('data', chunk.length), content.push(chunk)));
            res.stream.on('end', () => {
                res.buffer = Buffer.concat(content);
                onEnd();
            });
        } else {
            onEnd();
        }

    });
}

if (module.parent) {
    // for use as a node.js module
    // node -e 'require("./wget.js")("http://www.yahoo.com", {_: [], acceptHref: _ => _, process: _ => _})'
    module.exports = wget;
    return;
}

// command-line utility use
var argv = require('yargs')
    .usage('Usage: $0 [options] <url>')
    .demand(1)
    .example('$0 http://www.yahoo.com', 'fetch the site content')
    .option('np', {
        alias: 'no-parent',
        describe: `don't ascend to the parent directory`,
        boolean: true,
        default: false
    })
    .option('r', {
        alias: 'recursive',
        describe: `specify recursive download`,
        boolean: true,
        default: false
    })
    .option('P', {
        alias: 'directory-prefix',
        describe: `save files to PREFIX/...`,
        string: true,
        default: ''
    })
    .option('process', {
        describe: `javascript module/function handling the contents`,
        optional: true
    })
    // .alias('H', 'header')
    // .nargs('H', 1)
    // .describe('H', 'Request header')
    .help('h')
    .alias('h', 'help')
    // .epilog('Copyright 2016')
    .argv;

var firstUrl = argv._.shift();

// single origin only
firstUrl = firstUrl.match(/\w+:\/\//) ? firstUrl : 'http://' + firstUrl;
var parsedFirst = url.parse(firstUrl);

argv.acceptHref = href => {
    var parsedHref = url.parse(href);
    return parsedHref.host === parsedFirst.host &&
           parsedHref.protocol === parsedFirst.protocol;
};

if (argv.np) {
    // no-parent hrefs only
    argv.acceptHref = ((acceptHref) => href => {
        return href.startsWith(firstUrl) && acceptHref(href);
    })(argv.acceptHref);
}

try {
    argv.process = require(argv.process);
} catch(e) {
    try {
        argv.process = eval(argv.process);
    } catch(e) {
        argv.process = undefined;
    }

    var fs = require('fs');
    argv.process = argv.process || (res => {
        var name = path.normalize(path.join(argv.P, fname(res.url)));
        writeAsset(name, res);
        console.log('Done', res.url, res.code, '->', fname(res.url));
    });
}

argv.headers = {
  "accept-charset" : "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
  "accept-language" : "en-US,en;q=0.8",
  "accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  "user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
  "accept-encoding" : "gzip,deflate",
};

// if (typeof argv.header === 'string') argv.header = [argv.header];
// argv.header.forEach(h => {
//     var parts = h.split(':');
//     argv.headers[parts.shift()] = parts.join(':');
// })

setKeepalive();
wget(firstUrl, argv);
<|endoftext|>


<commit_before>import React from "react";
import { compose, mount, route, withView } from "navi";
import { View } from "react-navi";
import axios from "axios";
import Home from "./pages/Home";
import Group from "./pages/Group";
import Resource from "./pages/Resource";
import Transition from "./pages/Transition";
import Layout from "./components/Layout";
import {
  permalinkPrefix as prefix,
  toGroupPermalink,
  toResourcePermalink,
  toTransitionPermalink
} from "./lib/util";

const basePath = "/__json__/";

export async function fetchJSON(uuid) {
  const fullPath = `${basePath}${uuid}.json`;
  const { data } = await axios.get(fullPath);

  return data;
}

function getResource(ctx, req) {
  let selected;
  let selectedGroup;
  const permalink = toResourcePermalink(req);

  ctx.groups.forEach(group => {
    group.resources.forEach(resource => {
      if (resource.permalink === permalink) {
        selected = resource;
        selectedGroup = group;
      }
    });
  });

  return [selected, selectedGroup];
}

function routeHome(req, ctx) {
  return {
    title: ctx.title,
    view: <Home title={ctx.title} description={ctx.description} />
  };
}

async function routeGroup(req, ctx) {
  const permalink = toGroupPermalink(req);
  const group = ctx.groups.find(group => {
    return group.permalink == permalink;
  });

  return {
    title: `${group.title} - ${ctx.title}`,
    view: <Group group={group} />
  };
}

async function routeResource(req, ctx) {
  const [resource, group] = getResource(ctx, req);

  return {
    title: `${resource.title} - ${ctx.title}`,
    view: <Resource resource={resource} group={group} />
  };
}

async function routeTransition(req, ctx) {
  const permalink = toTransitionPermalink(req);
  const uuid = ctx.uuids[permalink];
  const transition = await fetchJSON(uuid);

  return {
    title: `${transition.title} - ${ctx.title}`,
    view: <Transition transition={transition} />
  };
}

export default compose(
  withView((req, ctx) => {
    return (
      <Layout title={ctx.title} groups={ctx.groups}>
        <View />
      </Layout>
    );
  }),
  mount({
    [`/`]: route(routeHome),
    [`/${prefix.group}/:id`]: route(routeGroup),
    [`/${prefix.resource}/:id`]: route(routeResource),
    [`/${prefix.transition}/:id`]: route(routeTransition)
  })
);
<commit_msg>handle not found<commit_after>import React from "react";
import { compose, mount, route, withView } from "navi";
import { NotFoundError } from "navi";
import { View } from "react-navi";
import axios from "axios";
import Home from "./pages/Home";
import Group from "./pages/Group";
import Resource from "./pages/Resource";
import Transition from "./pages/Transition";
import Layout from "./components/Layout";
import {
  permalinkPrefix as prefix,
  toGroupPermalink,
  toResourcePermalink,
  toTransitionPermalink
} from "./lib/util";

const basePath = "/__json__/";

export async function fetchJSON(uuid) {
  const fullPath = `${basePath}${uuid}.json`;
  const { data } = await axios.get(fullPath);

  return data;
}

function getResource(ctx, req) {
  let selected;
  let selectedGroup;

  const permalink = toResourcePermalink(req);

  ctx.groups.forEach(group => {
    group.resources.forEach(resource => {
      if (resource.permalink === permalink) {
        selected = resource;
        selectedGroup = group;
      }
    });
  });

  return [selected, selectedGroup];
}

function routeHome(req, ctx) {
  return {
    title: ctx.title,
    view: <Home title={ctx.title} description={ctx.description} />
  };
}

async function routeGroup(req, ctx) {
  const permalink = toGroupPermalink(req);
  const group = ctx.groups.find(group => {
    return group.permalink == permalink;
  });

  if (!group) {
    throw new NotFoundError();
  }

  return {
    title: `${group.title} - ${ctx.title}`,
    view: <Group group={group} />
  };
}

async function routeResource(req, ctx) {
  const [resource, group] = getResource(ctx, req);

  if (!resource) {
    throw new NotFoundError();
  }

  return {
    title: `${resource.title} - ${ctx.title}`,
    view: <Resource resource={resource} group={group} />
  };
}

async function routeTransition(req, ctx) {
  const permalink = toTransitionPermalink(req);
  const uuid = ctx.uuids[permalink];

  if (!uuid) {
    throw new NotFoundError();
  }

  const transition = await fetchJSON(uuid);

  return {
    title: `${transition.title} - ${ctx.title}`,
    view: <Transition transition={transition} />
  };
}

export default compose(
  withView((req, ctx) => {
    return (
      <Layout title={ctx.title} groups={ctx.groups}>
        <View />
      </Layout>
    );
  }),
  mount({
    [`/`]: route(routeHome),
    [`/${prefix.group}/:id`]: route(routeGroup),
    [`/${prefix.resource}/:id`]: route(routeResource),
    [`/${prefix.transition}/:id`]: route(routeTransition)
  })
);
<|endoftext|>


<commit_before>Date.prototype.isSameDate = function(b) {
  return this.getDate() == b.getDate() && this.getMonth() == b.getMonth() && this.getFullYear() == b.getFullYear();
}

Date.prototype.isSameWeekFuzzy = function(b) {
  var startOfWeek = new Date(b.getTime());
  startOfWeek.setHours(startOfWeek.getHours(), 0, 0, 0);
  var day = startOfWeek.getDay() || 7;
  if(day !== 1) startOfWeek.setHours(-24 * (day - 1));
  startOfWeek.setHours(-24);

  var endOfWeek = new Date(startOfWeek.getTime());
  endOfWeek.setHours(24 * 9);

  return this.getTime() >= startOfWeek.getTime() && this.getTime() < endOfWeek.getTime();
}

Date.prototype.formatDate = function(today) {
  var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  var ampm = (this.getHours() > 12) ? 'PM' : 'AM';
  var hours = this.getHours() % 12;
  if(hours == 0) hours = 12;

  var minutes = this.getMinutes();
  if(minutes == 0) minutes = '';
  else if(minutes < 10) minutes = ':0' + minutes;
  else minutes = ':' + minutes;

  if(this.isSameDate(today))
    var parts = ['Today', hours + minutes + ampm];
  else
    var parts = [days[this.getDay()], this.getDate(), months[this.getMonth()], hours + minutes + ampm];
  return parts.join(" ");
}

function parseTimes() {
  var now = new Date();

  var times = document.querySelectorAll(".time");
  for(var i = 0; i < times.length; i++) {
    var time = new Date(times[i].dataset.value);

    times[i].innerHTML = time.formatDate(now);

    var earlyStart = new Date(time.getTime());
    earlyStart.setHours(time.getHours() - 3);
    var scheduledEnd = new Date(time.getTime());
    scheduledEnd.setHours(time.getHours() + 3);

    var matchElement = times[i].parentNode;
    if(scheduledEnd.getTime() < now.getTime()) matchElement.classList.add("past");
    if((now.getTime() >= earlyStart) && (now.getTime() <= scheduledEnd)) matchElement.classList.add("current");
    if(time.isSameDate(now)) matchElement.classList.add("today");
    if(time.isSameWeekFuzzy(now)) matchElement.classList.add("current-week");
    if(earlyStart.getTime() >= now.getTime()) matchElement.classList.add("future");
  }
}

document.addEventListener("DOMContentLoaded", function(event) {
  parseTimes();
  window.setInterval(parseTimes, 60000);
});<commit_msg>Speed up parseTimes by using textContent instead of innerHTML<commit_after>Date.prototype.isSameDate = function(b) {
  return this.getDate() == b.getDate() && this.getMonth() == b.getMonth() && this.getFullYear() == b.getFullYear();
}

Date.prototype.isSameWeekFuzzy = function(b) {
  var startOfWeek = new Date(b.getTime());
  startOfWeek.setHours(startOfWeek.getHours(), 0, 0, 0);
  var day = startOfWeek.getDay() || 7;
  if(day !== 1) startOfWeek.setHours(-24 * (day - 1));
  startOfWeek.setHours(-24);

  var endOfWeek = new Date(startOfWeek.getTime());
  endOfWeek.setHours(24 * 9);

  return this.getTime() >= startOfWeek.getTime() && this.getTime() < endOfWeek.getTime();
}

Date.prototype.formatDate = function(today) {
  var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  var ampm = (this.getHours() > 12) ? 'PM' : 'AM';
  var hours = this.getHours() % 12;
  if(hours == 0) hours = 12;

  var minutes = this.getMinutes();
  if(minutes == 0) minutes = '';
  else if(minutes < 10) minutes = ':0' + minutes;
  else minutes = ':' + minutes;

  if(this.isSameDate(today))
    var parts = ['Today', hours + minutes + ampm];
  else
    var parts = [days[this.getDay()], this.getDate(), months[this.getMonth()], hours + minutes + ampm];
  return parts.join(" ");
}

function parseTimes() {
  var now = new Date();

  var times = document.querySelectorAll(".time");
  for(var i = 0; i < times.length; i++) {
    var time = new Date(times[i].dataset.value);

    times[i].textContent = time.formatDate(now);

    var earlyStart = new Date(time.getTime());
    earlyStart.setHours(time.getHours() - 3);
    var scheduledEnd = new Date(time.getTime());
    scheduledEnd.setHours(time.getHours() + 3);

    var matchElement = times[i].parentNode;
    if(scheduledEnd.getTime() < now.getTime()) matchElement.classList.add("past");
    if((now.getTime() >= earlyStart) && (now.getTime() <= scheduledEnd)) matchElement.classList.add("current");
    if(time.isSameDate(now)) matchElement.classList.add("today");
    if(time.isSameWeekFuzzy(now)) matchElement.classList.add("current-week");
    if(earlyStart.getTime() >= now.getTime()) matchElement.classList.add("future");
  }
}

document.addEventListener("DOMContentLoaded", function(event) {
  parseTimes();
  window.setInterval(parseTimes, 60000);
});<|endoftext|>


<commit_before>import Immutable from 'immutable'
import ol from 'openlayers'
import Rect from 'javascript/rect'
import Sector from 'javascript/sector'
import HeroPoint from 'javascript/heroPoint'
import Heart from 'javascript/heart'
import PointOfInterest from 'javascript/pointOfInterest'

export default class Zone {
  constructor(mapDef) {
    this.name = mapDef.get('name')
    this.minLevel = mapDef.get('min_level')
    this.maxLevel = mapDef.get('max_level')
    this.id = mapDef.get('id')
    this.defaultFloor = mapDef.get('default_floor')
    this.continentRect = new Rect(mapDef.get('continent_rect'))
    this.pois = mapDef.get('points_of_interest').map(poi => new PointOfInterest(poi))
    this.sectors = mapDef.get('sectors').map(sector => new Sector(sector))
    this.heroPoints = mapDef.get('skill_challenges').map(sc => new HeroPoint(sc))
    this.hearts = mapDef.get('tasks').map(task => new Heart(task))
  }

  get olFeature() {
    return new ol.Feature({
      geometry: this.continentRect.center.olPoint,
      name: this.name
    })
  }

  static get falseZones() {
    return Immutable.Set([37, 55, 61, 77, 79, 80, 89, 92, 97, 110, 113, 120,
      138, 140, 142, 143, 144, 145, 147, 148, 149, 152, 153, 154, 157, 159, 161,
      162, 163, 171, 172, 178, 179, 180, 182, 184, 185, 186, 190, 191, 192, 193,
      195, 196, 198, 199, 201, 202, 203, 211, 212, 215, 216, 217, 222, 224, 225,
      226, 232, 234, 237, 238, 239, 242, 244, 248, 249, 250, 251, 252, 254, 255,
      256, 257, 258, 259, 260, 262, 263, 264, 267, 269, 271, 272, 274, 275, 276,
      282, 283, 284, 287, 288, 290, 294, 330, 327, 334, 363, 364, 365, 371, 372,
      373, 374, 375, 376, 378, 379, 380, 381, 382, 385, 386, 387, 388, 389, 390,
      391, 392, 393, 394, 396, 397, 399, 400, 401, 405, 407, 410, 411, 412, 413,
      414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 427, 428, 429,
      430, 434, 435, 436, 439, 440, 441, 444, 447, 449, 453, 454, 455, 458, 459,
      460, 464, 465, 466, 470, 471, 474, 476, 477, 480, 481, 483, 485, 487, 488,
      490, 492, 497, 498, 499, 502, 503, 504, 505, 507, 509, 511, 512, 513, 514,
      515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 527, 528, 529, 532,
      533, 534, 535, 536, 537, 538, 539, 540, 542, 543, 544, 545, 546, 547, 548,
      552, 556, 557, 558, 559, 560, 561, 563, 564, 567, 569, 570, 571, 573, 574,
      575, 576, 577, 578, 579, 581, 582, 583, 584, 586, 587, 588, 589, 590, 591,
      592, 594, 595, 596, 597, 598, 599, 606, 607, 608, 609, 610, 611, 613, 614,
      617, 618, 620, 621, 622, 623, 624, 625, 628, 629, 630, 631, 634, 635, 636,
      638, 642, 643, 644, 645, 648, 649, 650, 651, 652, 653, 655, 656, 657, 659,
      662, 663, 664, 666, 667, 668, 669, 670, 672, 673, 674, 675, 676, 677, 678,
      680, 681, 682, 683, 684, 685, 686, 687, 691, 692, 693, 694, 698, 700, 703,
      706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 719, 726, 727, 728, 729,
      730, 731, 732, 733, 735, 736, 737, 738, 739, 743, 744, 745, 746, 747, 750,
      751, 758, 760, 761, 762, 763, 767, 768, 769, 772, 775, 777, 778, 779, 781,
      783, 784, 785, 786, 787, 788, 790, 792, 793, 797, 799, 806, 807, 820, 821,
      825, 827, 828, 830, 833, 845, 849, 905, 914, 938, 939, 980, 989, 990, 991,
      992, 993, 994, 997, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
      1009, 1010, 1016, 1017, 1018, 1021, 1022, 1023, 1024, 1025, 1026, 1027,
      1028, 1029, 1032, 1033, 1037, 1048, 1050, 1051, 1054, 1058, 1062, 1063,
      1064, 1065, 1066, 1067, 1069, 1070, 1071, 1072, 1073, 1074, 1076, 1079,
      1080, 1081, 1082, 1083, 1084, 1087, 1088, 1089, 1090, 1092, 1094, 1095,
      1097, 1098, 1100, 1101, 1104, 1106, 1107, 1108, 1109, 1110, 1113, 1115,
      1117, 1121, 1122, 1123, 1124, 1125, 1128, 1129, 1130, 1133, 1134, 1135,
      1136, 1137, 1139, 1140, 1142, 1144, 1146])
  }
}
<commit_msg>Added levels to zone labels.<commit_after>import Immutable from 'immutable'
import ol from 'openlayers'
import Rect from 'javascript/rect'
import Sector from 'javascript/sector'
import HeroPoint from 'javascript/heroPoint'
import Heart from 'javascript/heart'
import PointOfInterest from 'javascript/pointOfInterest'

export default class Zone {
  constructor(mapDef) {
    this.name = mapDef.get('name')
    this.minLevel = mapDef.get('min_level')
    this.maxLevel = mapDef.get('max_level')
    this.id = mapDef.get('id')
    this.defaultFloor = mapDef.get('default_floor')
    this.continentRect = new Rect(mapDef.get('continent_rect'))
    this.pois = mapDef.get('points_of_interest').map(poi => new PointOfInterest(poi))
    this.sectors = mapDef.get('sectors').map(sector => new Sector(sector))
    this.heroPoints = mapDef.get('skill_challenges').map(sc => new HeroPoint(sc))
    this.hearts = mapDef.get('tasks').map(task => new Heart(task))
  }

  get olFeature() {
    return new ol.Feature({
      geometry: this.continentRect.center.olPoint,
      name: `${this.name} (${this.minLevel}-${this.maxLevel})`
    })
  }

  static get falseZones() {
    return Immutable.Set([37, 55, 61, 77, 79, 80, 89, 92, 97, 110, 113, 120,
      138, 140, 142, 143, 144, 145, 147, 148, 149, 152, 153, 154, 157, 159, 161,
      162, 163, 171, 172, 178, 179, 180, 182, 184, 185, 186, 190, 191, 192, 193,
      195, 196, 198, 199, 201, 202, 203, 211, 212, 215, 216, 217, 222, 224, 225,
      226, 232, 234, 237, 238, 239, 242, 244, 248, 249, 250, 251, 252, 254, 255,
      256, 257, 258, 259, 260, 262, 263, 264, 267, 269, 271, 272, 274, 275, 276,
      282, 283, 284, 287, 288, 290, 294, 330, 327, 334, 363, 364, 365, 371, 372,
      373, 374, 375, 376, 378, 379, 380, 381, 382, 385, 386, 387, 388, 389, 390,
      391, 392, 393, 394, 396, 397, 399, 400, 401, 405, 407, 410, 411, 412, 413,
      414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 427, 428, 429,
      430, 434, 435, 436, 439, 440, 441, 444, 447, 449, 453, 454, 455, 458, 459,
      460, 464, 465, 466, 470, 471, 474, 476, 477, 480, 481, 483, 485, 487, 488,
      490, 492, 497, 498, 499, 502, 503, 504, 505, 507, 509, 511, 512, 513, 514,
      515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 527, 528, 529, 532,
      533, 534, 535, 536, 537, 538, 539, 540, 542, 543, 544, 545, 546, 547, 548,
      552, 556, 557, 558, 559, 560, 561, 563, 564, 567, 569, 570, 571, 573, 574,
      575, 576, 577, 578, 579, 581, 582, 583, 584, 586, 587, 588, 589, 590, 591,
      592, 594, 595, 596, 597, 598, 599, 606, 607, 608, 609, 610, 611, 613, 614,
      617, 618, 620, 621, 622, 623, 624, 625, 628, 629, 630, 631, 634, 635, 636,
      638, 642, 643, 644, 645, 648, 649, 650, 651, 652, 653, 655, 656, 657, 659,
      662, 663, 664, 666, 667, 668, 669, 670, 672, 673, 674, 675, 676, 677, 678,
      680, 681, 682, 683, 684, 685, 686, 687, 691, 692, 693, 694, 698, 700, 703,
      706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 719, 726, 727, 728, 729,
      730, 731, 732, 733, 735, 736, 737, 738, 739, 743, 744, 745, 746, 747, 750,
      751, 758, 760, 761, 762, 763, 767, 768, 769, 772, 775, 777, 778, 779, 781,
      783, 784, 785, 786, 787, 788, 790, 792, 793, 797, 799, 806, 807, 820, 821,
      825, 827, 828, 830, 833, 845, 849, 905, 914, 938, 939, 980, 989, 990, 991,
      992, 993, 994, 997, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
      1009, 1010, 1016, 1017, 1018, 1021, 1022, 1023, 1024, 1025, 1026, 1027,
      1028, 1029, 1032, 1033, 1037, 1048, 1050, 1051, 1054, 1058, 1062, 1063,
      1064, 1065, 1066, 1067, 1069, 1070, 1071, 1072, 1073, 1074, 1076, 1079,
      1080, 1081, 1082, 1083, 1084, 1087, 1088, 1089, 1090, 1092, 1094, 1095,
      1097, 1098, 1100, 1101, 1104, 1106, 1107, 1108, 1109, 1110, 1113, 1115,
      1117, 1121, 1122, 1123, 1124, 1125, 1128, 1129, 1130, 1133, 1134, 1135,
      1136, 1137, 1139, 1140, 1142, 1144, 1146])
  }
}
<|endoftext|>


<commit_before>const passport = require('passport');
const axios = require('axios');
const moment = require('moment');
const session = require('express-session');
const SpotifyWebApi = require('spotify-web-api-node');
const pool = require('./database');
require('dotenv').config();

const spotifyApi = new SpotifyWebApi({
  clientId: process.env.APP_KEY,
  clientSecret: process.env.APP_SECRET,
  redirectUri: 'http://localhost:8000/auth/callback',
});

const getArtistIDList = (artistList) => {
  return artistList.map((artist) => {
    return spotifyApi.searchArtists(artist)
            .then((response) => {
                     return response.body.artists.items[0].id;
            })
            .catch(err => console.error('Spotify API Error: ', err));
  });
};
const getTopTracks = artistIDList => artistIDList.map(artist => spotifyApi.getArtistTopTracks(artist, 'US')
      .then((data) => {
        const tracks = data.body.tracks;
        const tracklist = {};
        tracklist[artist] = [];
        tracks.forEach(((track) => {
          tracklist[artist].push(`spotify:track:${track.id}`);
        }));
        const artistCount = artistIDList.length;
        const allTracks = tracklist[Object.keys(tracklist)[0]];
        const sizing = Math.floor(30 / artistCount);

        if (allTracks.length > sizing) {
          tracklist[Object.keys(tracklist)[0]].splice(sizing);
        }
        return tracklist;
      })
      .catch(err => console.error(err)));

  const getArtistImages = artistIDList => spotifyApi.getArtists(artistIDList)
    .then((data) => {
      const artistImages = [];
      data.body.artists.forEach((artist) => {
        if (artist.images[1] === undefined) {
          artistImages.push('../assets/gigify-g-background.png');
        } else {
          artistImages.push(artist.images[1].url);
        }

      });
      return artistImages
    })
    .catch(err => console.error(err))

let userID;

module.exports = {
  getSpotlightOnePlaylist: (req, res) => {
    //console.log('GETTING FIRST SPOTLIGHT REQUEST');
    res.send('FIRST FESTIVAL RESPONSE');
  },
  getSpotlightTwoPlaylist: (req, res) => {
    //console.log('GETTING SECOND SPOTLIGHT REQUEST');
    res.send('SECOND FESTIVAL RESPONSE');
  },
  createPlaylist: (req, res) => {
    // console.log('SELECTED', req.body.selected);
    Promise.all(getArtistIDList(req.body.selected))
      .then(artistIDList => getTopTracks(artistIDList))
      .then((tracksArray) => {
        Promise.all(tracksArray)
          .then((results) => {
            const merged = Object.assign(...results);
            return merged;
          })
          .then((merged) => {
            spotifyApi.getMe()
              .then((data) => {
<<<<<<< HEAD
                // console.log(data);
=======
                console.log(data, 'USER DATA');
>>>>>>> ArtistInfo
                userID = data.body.id;
                name = data.body.display_name;
                return [userID, name];
              })
              .then((user) => {
                spotifyApi.createPlaylist(user[0], `${user[1]}'s Gigify Playlist - ${moment().format('M/D, hA')}`, { public: false })
                .then((data) => {
                  //console.log('Created playlist!');
                  return [user[0], data.body.id];
                })
                .then((playlistInfo) => {
                  let tracksToAdd = [];
                  for (artist in merged) {
                    tracksToAdd = tracksToAdd.concat(merged[artist]);
                  }
                  spotifyApi.addTracksToPlaylist(playlistInfo[0], playlistInfo[1], tracksToAdd)
                    .then((data) => {
                      //console.log('ADDED SONGS TO PLAYLIST');
                    })
                    .catch(err => console.error(err));

                  res.send(playlistInfo);
                })
                .catch(err => console.error(err));
              });
          });
      });
  },
  goHome: (req, res) => {
    res.redirect('/home');
  },
  checkSession: (req, res) => {
    spotifyApi.getMe()
    .then(() => {
      res.send('logged');
    }).catch(() => {
      res.send('notlogged');
    });
  },
  getEvents: (req, res) => {
    axios.get(`http://api.songkick.com/api/3.0/users/${req.params.username}/calendar.json?reason=tracked_artist&apikey=${process.env.SONGKICK_KEY}`)
    .then((results) => {
      const eventList = results.data.resultsPage.results.calendarEntry;
      const events = [];
      const festivals = [];
      const allArtists = [];
      eventList.forEach((item) => {
        const concert = item.event;
        let eventTime = moment(concert.start.datetime).format('hA');
        if (eventTime === 'Invalid date') {
          eventTime = 'TBD';
        }
        let eventDate = moment(concert.start.date).format('M[/]D') || 'TBD';
        if (eventDate === 'Invalid date') {
          eventDate = 'TBD';
        }
        const artists = [];
        concert.performance.forEach((artist) => {
          artists.push(artist.displayName);
        });

        if (artists.length < 7) {
          allArtists.push(artists[0]);
        }

        const event = {
          eventName: concert.displayName,
          eventUrl: concert.uri,
          performers: artists,
          venueName: concert.venue.displayName,
          venueUrl: concert.venue.uri,
          time: eventTime,
          date: eventDate,
        };
        if (event.performers.length > 7) {
          festivals.push(event);
        } else {
          events.push(event);
        }
      });
      Promise.all(getArtistIDList(allArtists))
        .then(artistIds => getArtistImages(artistIds))
          .then((imageUrls) => {
            events.forEach((event, i) => {
                event.imageUrl = imageUrls[i];
                event.id = i;
            });
          })
          .then(() => res.send(events));
    });
  },
  spotifyApi,
};
<commit_msg>Conflict Resolved<commit_after>const passport = require('passport');
const axios = require('axios');
const moment = require('moment');
const session = require('express-session');
const SpotifyWebApi = require('spotify-web-api-node');
const pool = require('./database');
require('dotenv').config();

const spotifyApi = new SpotifyWebApi({
  clientId: process.env.APP_KEY,
  clientSecret: process.env.APP_SECRET,
  redirectUri: 'http://localhost:8000/auth/callback',
});

const getArtistIDList = (artistList) => {
  return artistList.map((artist) => {
    return spotifyApi.searchArtists(artist)
            .then((response) => {
                     return response.body.artists.items[0].id;
            })
            .catch(err => console.error('Spotify API Error: ', err));
  });
};
const getTopTracks = artistIDList => artistIDList.map(artist => spotifyApi.getArtistTopTracks(artist, 'US')
      .then((data) => {
        const tracks = data.body.tracks;
        const tracklist = {};
        tracklist[artist] = [];
        tracks.forEach(((track) => {
          tracklist[artist].push(`spotify:track:${track.id}`);
        }));
        const artistCount = artistIDList.length;
        const allTracks = tracklist[Object.keys(tracklist)[0]];
        const sizing = Math.floor(30 / artistCount);

        if (allTracks.length > sizing) {
          tracklist[Object.keys(tracklist)[0]].splice(sizing);
        }
        return tracklist;
      })
      .catch(err => console.error(err)));

  const getArtistImages = artistIDList => spotifyApi.getArtists(artistIDList)
    .then((data) => {
      const artistImages = [];
      data.body.artists.forEach((artist) => {
        if (artist.images[1] === undefined) {
          artistImages.push('../assets/gigify-g-background.png');
        } else {
          artistImages.push(artist.images[1].url);
        }

      });
      return artistImages
    })
    .catch(err => console.error(err))

let userID;

module.exports = {
  getSpotlightOnePlaylist: (req, res) => {
    //console.log('GETTING FIRST SPOTLIGHT REQUEST');
    res.send('FIRST FESTIVAL RESPONSE');
  },
  getSpotlightTwoPlaylist: (req, res) => {
    //console.log('GETTING SECOND SPOTLIGHT REQUEST');
    res.send('SECOND FESTIVAL RESPONSE');
  },
  createPlaylist: (req, res) => {
    // console.log('SELECTED', req.body.selected);
    Promise.all(getArtistIDList(req.body.selected))
      .then(artistIDList => getTopTracks(artistIDList))
      .then((tracksArray) => {
        Promise.all(tracksArray)
          .then((results) => {
            const merged = Object.assign(...results);
            return merged;
          })
          .then((merged) => {
            spotifyApi.getMe()
              .then((data) => {
                userID = data.body.id;
                name = data.body.display_name;
                return [userID, name];
              })
              .then((user) => {
                spotifyApi.createPlaylist(user[0], `${user[1]}'s Gigify Playlist - ${moment().format('M/D, hA')}`, { public: false })
                .then((data) => {
                  //console.log('Created playlist!');
                  return [user[0], data.body.id];
                })
                .then((playlistInfo) => {
                  let tracksToAdd = [];
                  for (artist in merged) {
                    tracksToAdd = tracksToAdd.concat(merged[artist]);
                  }
                  spotifyApi.addTracksToPlaylist(playlistInfo[0], playlistInfo[1], tracksToAdd)
                    .then((data) => {
                      //console.log('ADDED SONGS TO PLAYLIST');
                    })
                    .catch(err => console.error(err));

                  res.send(playlistInfo);
                })
                .catch(err => console.error(err));
              });
          });
      });
  },
  goHome: (req, res) => {
    res.redirect('/home');
  },
  checkSession: (req, res) => {
    spotifyApi.getMe()
    .then(() => {
      res.send('logged');
    }).catch(() => {
      res.send('notlogged');
    });
  },
  getEvents: (req, res) => {
    axios.get(`http://api.songkick.com/api/3.0/users/${req.params.username}/calendar.json?reason=tracked_artist&apikey=${process.env.SONGKICK_KEY}`)
    .then((results) => {
      const eventList = results.data.resultsPage.results.calendarEntry;
      const events = [];
      const festivals = [];
      const allArtists = [];
      eventList.forEach((item) => {
        const concert = item.event;
        let eventTime = moment(concert.start.datetime).format('hA');
        if (eventTime === 'Invalid date') {
          eventTime = 'TBD';
        }
        let eventDate = moment(concert.start.date).format('M[/]D') || 'TBD';
        if (eventDate === 'Invalid date') {
          eventDate = 'TBD';
        }
        const artists = [];
        concert.performance.forEach((artist) => {
          artists.push(artist.displayName);
        });

        if (artists.length < 7) {
          allArtists.push(artists[0]);
        }

        const event = {
          eventName: concert.displayName,
          eventUrl: concert.uri,
          performers: artists,
          venueName: concert.venue.displayName,
          venueUrl: concert.venue.uri,
          time: eventTime,
          date: eventDate,
        };
        if (event.performers.length > 7) {
          festivals.push(event);
        } else {
          events.push(event);
        }
      });
      Promise.all(getArtistIDList(allArtists))
        .then(artistIds => getArtistImages(artistIds))
          .then((imageUrls) => {
            events.forEach((event, i) => {
                event.imageUrl = imageUrls[i];
                event.id = i;
            });
          })
          .then(() => res.send(events));
    });
  },
  spotifyApi,
};
<|endoftext|>


<commit_before>import minimist from 'minimist';
import path from "path";
import webpack from "webpack";

const argv = minimist(process.argv.slice(2));

const DEBUG = !argv.release;

module.exports = {
  cache: DEBUG,
  debug: DEBUG,
  devtool: DEBUG ? 'source-map' : false,
  entry: {
    app: "./src/app",
    styles: './src/styles'
  },
  output: {
    path: path.join(__dirname, "dist/assets"),
    publicPath: "/assets/",
    filename: "[name].js",
    chunkFilename: "[chunkhash].js"
  },
  resolve: {
    root: [path.join(__dirname, "bower_components")]
  },
  module: {
    preLoaders: [
      {test: /\.js$/, loader: "eslint-loader", exclude: /node_modules/}
    ],

    loaders: [
      {
        test: /\.scss|\.css$/,
        loader: "style!css!sass?outputStyle=expanded&indentedSyntax" +
        "includePaths[]=" +
        (path.resolve(__dirname, "./bower_components")) + "&" +
        "includePaths[]=" +
        (path.resolve(__dirname, "./node_modules"))
      },

      {
        test: /\.png$/,
        loader: "file-loader"
      },

      // required for bootstrap icons
      { test: /\.woff$/, loader: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff" },
      { test: /\.ttf$/, loader: "file-loader?prefix=font/" },
      { test: /\.eot$/, loader: "file-loader?prefix=font/" },
      { test: /\.svg$/, loader: "file-loader?prefix=font/" },

      {
        test: /\.js$/,
        loader: "babel",
        exclude: /(node_modules|bower_components)/,
        query: {
          optional: ['strict', 'es7.classProperties']
        }
      }
    ]
  },
  plugins: [
    new webpack.ResolverPlugin([
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("package.json", ["main"]),
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
    ]),
    new webpack.optimize.DedupePlugin()
  ],
  eslint: {
    configFile: './.eslintrc'
  }
};
<commit_msg>chore(web): hot module reload<commit_after>import minimist from 'minimist';
import path from "path";
import webpack from "webpack";

const argv = minimist(process.argv.slice(2));

const DEBUG = !argv.release;

module.exports = {
  cache: DEBUG,
  debug: DEBUG,
  devtool: DEBUG ? 'source-map' : false,
  hotComponents: true,
  entry: {
    app: [
      "./src/app"
    ],
    styles: [
      'webpack-dev-server/client?http://localhost:3000',
      'webpack/hot/dev-server',
      './src/styles'
    ]
  },
  output: {
    path: path.join(__dirname, "dist/assets"),
    publicPath: "/assets/",
    filename: "[name].js",
    chunkFilename: "[chunkhash].js"
  },
  resolve: {
    root: [path.join(__dirname, "bower_components")]
  },
  module: {
    preLoaders: [
      {test: /\.js$/, loader: "eslint-loader", exclude: /node_modules/}
    ],

    loaders: [
      {
        test: /\.scss|\.css$/,
        loader: "style!css!sass?outputStyle=expanded&indentedSyntax" +
        "includePaths[]=" +
        (path.resolve(__dirname, "./bower_components")) + "&" +
        "includePaths[]=" +
        (path.resolve(__dirname, "./node_modules"))
      },

      {
        test: /\.png$/,
        loader: "file-loader"
      },

      // required for bootstrap icons
      {test: /\.woff$/, loader: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff"},
      {test: /\.ttf$/, loader: "file-loader?prefix=font/"},
      {test: /\.eot$/, loader: "file-loader?prefix=font/"},
      {test: /\.svg$/, loader: "file-loader?prefix=font/"},

      {
        test: /\.js$/,
        loader: "babel",
        exclude: /(node_modules|bower_components)/,
        query: {
          optional: ['strict', 'es7.classProperties']
        }
      }
    ]
  },
  plugins: [
    new webpack.ResolverPlugin([
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("package.json", ["main"]),
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
    ]),
    new webpack.optimize.DedupePlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  eslint: {
    configFile: './.eslintrc'
  }
};
<|endoftext|>


<commit_before>const passport = require('passport');
const axios = require('axios');
const moment = require('moment');
const session = require('express-session');
const SpotifyWebApi = require('spotify-web-api-node');
const pool = require('./database');
require('dotenv').config();

const spotifyApi = new SpotifyWebApi({
  clientId: process.env.APP_KEY,
  clientSecret: process.env.APP_SECRET,
  redirectUri: 'http://localhost:8000/auth/callback',
});

const getArtistIDList = (artistList) => {
  return artistList.map((artist) => {
    return spotifyApi.searchArtists(artist)
            .then((response) => {
                     return response.body.artists.items[0].id;
            })
            .catch(err => console.error('Spotify API Error: ', err));
  });
};
const getTopTracks = artistIDList => artistIDList.map(artist => spotifyApi.getArtistTopTracks(artist, 'US')
      .then((data) => {
        const tracks = data.body.tracks;
        const tracklist = {};
        tracklist[artist] = [];
        tracks.forEach(((track) => {
          tracklist[artist].push(`spotify:track:${track.id}`);
        }));
        const artistCount = artistIDList.length;
        const allTracks = tracklist[Object.keys(tracklist)[0]];
        const sizing = Math.floor(30 / artistCount);

        if (allTracks.length > sizing) {
          tracklist[Object.keys(tracklist)[0]].splice(sizing);
        }
        return tracklist;
      })
      .catch(err => console.error(err)));

  const getArtistImages = artistIDList => spotifyApi.getArtists(artistIDList)
    .then((data) => {
      const artistImages = [];
      data.body.artists.forEach((artist) => {
        if (artist.images[1] === undefined) {
          artistImages.push('../assets/gigify-g-background.png');
        } else {
          artistImages.push(artist.images[1].url);
        }

      });
      return artistImages
    })
    .catch(err => console.error(err))

let userID;

module.exports = {
  getSpotlightOnePlaylist: (req, res) => {
    //console.log('GETTING FIRST SPOTLIGHT REQUEST');
    res.send('FIRST FESTIVAL RESPONSE');
  },
  getSpotlightTwoPlaylist: (req, res) => {
    //console.log('GETTING SECOND SPOTLIGHT REQUEST');
    res.send('SECOND FESTIVAL RESPONSE');
  },
  createPlaylist: (req, res) => {
    // console.log('SELECTED', req.body.selected);
    Promise.all(getArtistIDList(req.body.selected))
      .then(artistIDList => getTopTracks(artistIDList))
      .then((tracksArray) => {
        Promise.all(tracksArray)
          .then((results) => {
            const merged = Object.assign(...results);
            return merged;
          })
          .then((merged) => {
            spotifyApi.getMe()
              .then((data) => {
                userID = data.body.id;
                name = data.body.display_name;
                return [userID, name];
              })
              .then((user) => {
                spotifyApi.createPlaylist(user[0], `${user[1]}'s Gigify Playlist - ${moment().format('M/D, hA')}`, { public: false })
                .then((data) => {
                  //console.log('Created playlist!');
                  return [user[0], data.body.id];
                })
                .then((playlistInfo) => {
                  let tracksToAdd = [];
                  for (artist in merged) {
                    tracksToAdd = tracksToAdd.concat(merged[artist]);
                  }
                  spotifyApi.addTracksToPlaylist(playlistInfo[0], playlistInfo[1], tracksToAdd)
                    .then((data) => {
                      //console.log('ADDED SONGS TO PLAYLIST');
                    })
                    .catch(err => console.error(err));

                  res.send(playlistInfo);
                })
                .catch(err => console.error(err));
              });
          });
      });
  },
  goHome: (req, res) => {
    res.redirect('/home');
  },
  checkSession: (req, res) => {
    spotifyApi.getMe()
    .then(() => {
      res.send('logged');
    }).catch(() => {
      res.send('notlogged');
    });
  },
  getEvents: (req, res) => {
    axios.get(`http://api.songkick.com/api/3.0/users/${req.params.username}/calendar.json?reason=tracked_artist&apikey=${process.env.SONGKICK_KEY}`)
    .then((results) => {
      const eventList = results.data.resultsPage.results.calendarEntry;
      const events = [];
      const festivals = [];
      const allArtists = [];
      eventList.forEach((item) => {
        const concert = item.event;
        let eventTime = moment(concert.start.datetime).format('hA');
        if (eventTime === 'Invalid date') {
          eventTime = 'TBD';
        }
        let eventDate = moment(concert.start.date).format('M[/]D') || 'TBD';
        if (eventDate === 'Invalid date') {
          eventDate = 'TBD';
        }
        const artists = [];
        concert.performance.forEach((artist) => {
          artists.push(artist.displayName);
        });

        if (artists.length < 7) {
          allArtists.push(artists[0]);
        }

        const event = {
          eventName: concert.displayName,
          eventUrl: concert.uri,
          performers: artists,
          venueName: concert.venue.displayName,
          venueUrl: concert.venue.uri,
          time: eventTime,
          date: eventDate,
        };
        if (event.performers.length > 7) {
          festivals.push(event);
        } else {
          events.push(event);
        }
      });
      Promise.all(getArtistIDList(allArtists))
        .then(artistIds => getArtistImages(artistIds))
          .then((imageUrls) => {
            events.forEach((event, i) => {
                event.imageUrl = imageUrls[i];
                event.id = i;
            });
          })
          .then(() => res.send(events));
    });
  },
  spotifyApi,
};
<commit_msg>Revert "Conflict Resolved"<commit_after>const passport = require('passport');
const axios = require('axios');
const moment = require('moment');
const session = require('express-session');
const SpotifyWebApi = require('spotify-web-api-node');
const pool = require('./database');
require('dotenv').config();

const spotifyApi = new SpotifyWebApi({
  clientId: process.env.APP_KEY,
  clientSecret: process.env.APP_SECRET,
  redirectUri: 'http://localhost:8000/auth/callback',
});

const getArtistIDList = (artistList) => {
  return artistList.map((artist) => {
    return spotifyApi.searchArtists(artist)
            .then((response) => {
                     return response.body.artists.items[0].id;
            })
            .catch(err => console.error('Spotify API Error: ', err));
  });
};
const getTopTracks = artistIDList => artistIDList.map(artist => spotifyApi.getArtistTopTracks(artist, 'US')
      .then((data) => {
        const tracks = data.body.tracks;
        const tracklist = {};
        tracklist[artist] = [];
        tracks.forEach(((track) => {
          tracklist[artist].push(`spotify:track:${track.id}`);
        }));
        const artistCount = artistIDList.length;
        const allTracks = tracklist[Object.keys(tracklist)[0]];
        const sizing = Math.floor(30 / artistCount);

        if (allTracks.length > sizing) {
          tracklist[Object.keys(tracklist)[0]].splice(sizing);
        }
        return tracklist;
      })
      .catch(err => console.error(err)));

  const getArtistImages = artistIDList => spotifyApi.getArtists(artistIDList)
    .then((data) => {
      const artistImages = [];
      data.body.artists.forEach((artist) => {
        if (artist.images[1] === undefined) {
          artistImages.push('../assets/gigify-g-background.png');
        } else {
          artistImages.push(artist.images[1].url);
        }

      });
      return artistImages
    })
    .catch(err => console.error(err))

let userID;

module.exports = {
  getSpotlightOnePlaylist: (req, res) => {
    //console.log('GETTING FIRST SPOTLIGHT REQUEST');
    res.send('FIRST FESTIVAL RESPONSE');
  },
  getSpotlightTwoPlaylist: (req, res) => {
    //console.log('GETTING SECOND SPOTLIGHT REQUEST');
    res.send('SECOND FESTIVAL RESPONSE');
  },
  createPlaylist: (req, res) => {
    // console.log('SELECTED', req.body.selected);
    Promise.all(getArtistIDList(req.body.selected))
      .then(artistIDList => getTopTracks(artistIDList))
      .then((tracksArray) => {
        Promise.all(tracksArray)
          .then((results) => {
            const merged = Object.assign(...results);
            return merged;
          })
          .then((merged) => {
            spotifyApi.getMe()
              .then((data) => {
<<<<<<< HEAD
                // console.log(data);
=======
                console.log(data, 'USER DATA');
>>>>>>> ArtistInfo
                userID = data.body.id;
                name = data.body.display_name;
                return [userID, name];
              })
              .then((user) => {
                spotifyApi.createPlaylist(user[0], `${user[1]}'s Gigify Playlist - ${moment().format('M/D, hA')}`, { public: false })
                .then((data) => {
                  //console.log('Created playlist!');
                  return [user[0], data.body.id];
                })
                .then((playlistInfo) => {
                  let tracksToAdd = [];
                  for (artist in merged) {
                    tracksToAdd = tracksToAdd.concat(merged[artist]);
                  }
                  spotifyApi.addTracksToPlaylist(playlistInfo[0], playlistInfo[1], tracksToAdd)
                    .then((data) => {
                      //console.log('ADDED SONGS TO PLAYLIST');
                    })
                    .catch(err => console.error(err));

                  res.send(playlistInfo);
                })
                .catch(err => console.error(err));
              });
          });
      });
  },
  goHome: (req, res) => {
    res.redirect('/home');
  },
  checkSession: (req, res) => {
    spotifyApi.getMe()
    .then(() => {
      res.send('logged');
    }).catch(() => {
      res.send('notlogged');
    });
  },
  getEvents: (req, res) => {
    axios.get(`http://api.songkick.com/api/3.0/users/${req.params.username}/calendar.json?reason=tracked_artist&apikey=${process.env.SONGKICK_KEY}`)
    .then((results) => {
      const eventList = results.data.resultsPage.results.calendarEntry;
      const events = [];
      const festivals = [];
      const allArtists = [];
      eventList.forEach((item) => {
        const concert = item.event;
        let eventTime = moment(concert.start.datetime).format('hA');
        if (eventTime === 'Invalid date') {
          eventTime = 'TBD';
        }
        let eventDate = moment(concert.start.date).format('M[/]D') || 'TBD';
        if (eventDate === 'Invalid date') {
          eventDate = 'TBD';
        }
        const artists = [];
        concert.performance.forEach((artist) => {
          artists.push(artist.displayName);
        });

        if (artists.length < 7) {
          allArtists.push(artists[0]);
        }

        const event = {
          eventName: concert.displayName,
          eventUrl: concert.uri,
          performers: artists,
          venueName: concert.venue.displayName,
          venueUrl: concert.venue.uri,
          time: eventTime,
          date: eventDate,
        };
        if (event.performers.length > 7) {
          festivals.push(event);
        } else {
          events.push(event);
        }
      });
      Promise.all(getArtistIDList(allArtists))
        .then(artistIds => getArtistImages(artistIds))
          .then((imageUrls) => {
            events.forEach((event, i) => {
                event.imageUrl = imageUrls[i];
                event.id = i;
            });
          })
          .then(() => res.send(events));
    });
  },
  spotifyApi,
};
<|endoftext|>


<commit_before>function createContextMenu() {
  chrome.contextMenus.create({ id: 'bracketless', title: 'local.clear()' });
}
function updateContextMenu(text) {
  chrome.contextMenus.update('bracketless', { title: text });
}

const tabState = {
  get(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.get(tabId.toString(), (singleState) => {
        resolve(singleState[tabId]);
      });
    });
  },
  set(tabId, value) {
    return new Promise((resolve) => {
      chrome.storage.local.set({ [tabId]: value }, () => resolve());
    });
  },
  remove(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.remove(tabId.toString(), () => resolve());
    });
  },
  getAll() { // Dev QoL
    chrome.storage.local.get(null, (all) => {
      console.warn('local.get(null)');
      console.log(all);
    });
  },
  clearAll() {
    chrome.storage.local.clear(() => {
      console.warn('local.clear(null)');
      this.getAll();
    });
  },
};

function load(tabId) {
  return new Promise((resolve) => {
    chrome.tabs.executeScript(tabId, { file: 'src/bracketless.js' }, () => {
      chrome.browserAction.setIcon({ tabId, path: 'icons/play.png' });
      chrome.browserAction.setTitle({ tabId, title: 'Collapse brackets' });
      // updateContextMenu('Collapse brackets');
      chrome.tabs.insertCSS(tabId, { file: 'css/action.css' });
      chrome.tabs.executeScript(tabId, { file: 'src/action.js' }, () => {
        tabState.set(tabId, false) // { 322: false }
          .then(() => resolve('load resolved'));
      });
    });
  });
}

function activate(tabId, active) {
  return new Promise((resolve) => {
    const action = active === true ?
      { message: 'Pause collapsing', reverseIcon: 'pause' } :
      { message: 'Collapse brackets', reverseIcon: 'play' };
    chrome.browserAction.setIcon({ tabId, path: `icons/${action.reverseIcon}.png` });
    chrome.browserAction.setTitle({ tabId, title: action.message });
    // updateContextMenu(state.message);
    chrome.tabs.sendMessage(tabId, { active }, () => {
      tabState.set(tabId, active) // { 322: bool}
        .then(() => { resolve(`action resolved. enabled: ${active}`); });
    });
  });
}

function listenerAction(tabId) {
  tabState.get(tabId)
    .then((state) => {
      console.warn('getState.then()');
      console.log(state);

      if (state === undefined) {
        return load(tabId);
      } else if (state === false) {
        return activate(tabId, true);
      } else if (state === true) {
        return activate(tabId, false);
      }
      return Promise.reject(new Error('listenerAction if else didn\'t work'));
    })
    .then((action) => {
      console.log(action);
      console.log('------------------------');
    });
}

function checkPermission() {
  return new Promise((resolve, reject) => chrome.permissions.contains({
    permissions: ['tabs'],
    origins: ['http://*/', 'https://*/'],
  }, (permission) => {
    if (permission) resolve(permission);
    else reject(new Error(`Bracketless. Tabs at any origins was denied. Permission: ${permission}`));
  }));
}

function autoAction() {
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    // if (this is not the same page AND already loaded) OR (chrome browser utility page) - like "chrome://"
    if ((tabId !== tab.id && loadedTabs[tabId]) || /(chrome)(?:[/:-])/.test(tab.url)) return;
    if (changeInfo.status === 'complete' && tab.active) {
      chrome.storage.sync.get(null, (options) => {
        if (options.autoLoad && options.autoPlay === false) load(tabId);
        if (options.autoLoad && options.autoPlay) {
          load(tabId)
            .then(() => activate(tabId, 'play'));
        }
      });
    }
  });
}

// DEV
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete' && tab.active) {
    // localClear();
    tabState.getAll();
  }
});
// integer tabId, object removeInfo
chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
  tabState.get(tabId).then((diz) => {
    if (diz === undefined) {
      console.log('I have no power over hea.');
    } else {
      console.log('FEEL THE POWER!');
      tabState.remove(tabId);
    }
  });
});

function syncDefault() {
  chrome.storage.sync.set({
    lowLimit: 13,
    upLimit: 255,
    autoLoad: false,
    autoPlay: false,
  });
}
function checkOptsUse(cb) {
  chrome.storage.sync.getBytesInUse(null, (bytes) => { if (bytes === 0) cb(); });
}

chrome.runtime.onInstalled.addListener(() => {
  checkOptsUse(syncDefault); // if not in use, sync default
  createContextMenu();
  chrome.browserAction.onClicked.addListener(tab => listenerAction(tab.id));
  chrome.contextMenus.onClicked.addListener((_, tab) => tabState.clearAll());
  // checkPermission()
  //   .then(autoAction, e => console.warn(e)); // no permission, just ignore?
});
<commit_msg>Update onRemove listener<commit_after>function createContextMenu() {
  chrome.contextMenus.create({ id: 'bracketless', title: 'local.clear()' });
}
function updateContextMenu(text) {
  chrome.contextMenus.update('bracketless', { title: text });
}

const tabState = {
  get(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.get(tabId.toString(), (singleState) => {
        resolve(singleState[tabId]);
      });
    });
  },
  set(tabId, value) {
    return new Promise((resolve) => {
      chrome.storage.local.set({ [tabId]: value }, () => resolve());
    });
  },
  remove(tabId) {
    return new Promise((resolve) => {
      chrome.storage.local.remove(tabId.toString(), () => resolve());
    });
  },
  getAll() { // Dev QoL
    chrome.storage.local.get(null, (all) => {
      console.warn('local.get(null)');
      console.log(all);
    });
  },
  clearAll() {
    chrome.storage.local.clear(() => {
      console.warn('local.clear(null)');
      this.getAll();
    });
  },
};

function load(tabId) {
  return new Promise((resolve) => {
    chrome.tabs.executeScript(tabId, { file: 'src/bracketless.js' }, () => {
      chrome.browserAction.setIcon({ tabId, path: 'icons/play.png' });
      chrome.browserAction.setTitle({ tabId, title: 'Collapse brackets' });
      // updateContextMenu('Collapse brackets');
      chrome.tabs.insertCSS(tabId, { file: 'css/action.css' });
      chrome.tabs.executeScript(tabId, { file: 'src/action.js' }, () => {
        tabState.set(tabId, false) // { 322: false }
          .then(() => resolve('load resolved'));
      });
    });
  });
}

function activate(tabId, active) {
  return new Promise((resolve) => {
    const action = active === true ?
      { message: 'Pause collapsing', reverseIcon: 'pause' } :
      { message: 'Collapse brackets', reverseIcon: 'play' };
    chrome.browserAction.setIcon({ tabId, path: `icons/${action.reverseIcon}.png` });
    chrome.browserAction.setTitle({ tabId, title: action.message });
    // updateContextMenu(state.message);
    chrome.tabs.sendMessage(tabId, { active }, () => {
      tabState.set(tabId, active) // { 322: bool}
        .then(() => { resolve(`action resolved. enabled: ${active}`); });
    });
  });
}

function listenerAction(tabId) {
  tabState.get(tabId)
    .then((state) => {
      console.warn('getState.then()');
      console.log(state);

      if (state === undefined) {
        return load(tabId);
      } else if (state === false) {
        return activate(tabId, true);
      } else if (state === true) {
        return activate(tabId, false);
      }
      return Promise.reject(new Error('listenerAction if else didn\'t work'));
    })
    .then((action) => {
      console.log(action);
      console.log('------------------------');
    });
}

function checkPermission() {
  return new Promise((resolve, reject) => chrome.permissions.contains({
    permissions: ['tabs'],
    origins: ['http://*/', 'https://*/'],
  }, (permission) => {
    if (permission) resolve(permission);
    else reject(new Error(`Bracketless. Tabs at any origins was denied. Permission: ${permission}`));
  }));
}

function autoAction() {
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    // if (this is not the same page AND already loaded) OR (chrome browser utility page) - like "chrome://"
    if ((tabId !== tab.id && loadedTabs[tabId]) || /(chrome)(?:[/:-])/.test(tab.url)) return;
    if (changeInfo.status === 'complete' && tab.active) {
      chrome.storage.sync.get(null, (options) => {
        if (options.autoLoad && options.autoPlay === false) load(tabId);
        if (options.autoLoad && options.autoPlay) {
          load(tabId)
            .then(() => activate(tabId, 'play'));
        }
      });
    }
  });
}

// DEV
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === 'complete' && tab.active) {
    // localClear();
    tabState.getAll();
  }
});
// integer tabId, object removeInfo
chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
  tabState.get(tabId).then((state) => {
    // act only if state is defined (user granted currentTab permission)
    if (state !== undefined) {
      console.warn('onRemoved IF');
      console.log(state, removeInfo);
      tabState.remove(tabId);
    } else {
      console.warn('onRemoved ELSE');
    }
  });
});

function syncDefault() {
  chrome.storage.sync.set({
    lowLimit: 13,
    upLimit: 255,
    autoLoad: false,
    autoPlay: false,
  });
}
function checkOptsUse(cb) {
  chrome.storage.sync.getBytesInUse(null, (bytes) => { if (bytes === 0) cb(); });
}

chrome.runtime.onInstalled.addListener(() => {
  checkOptsUse(syncDefault); // if not in use, sync default
  createContextMenu();
  chrome.browserAction.onClicked.addListener(tab => listenerAction(tab.id));
  chrome.contextMenus.onClicked.addListener((_, tab) => tabState.clearAll());
  // checkPermission()
  //   .then(autoAction, e => console.warn(e)); // no permission, just ignore?
});
<|endoftext|>


<commit_before>function findValue (parent, dotNot) {

    if (!dotNot) return undefined;

    var splits = dotNot.split('.');
    var value;

    for (var i = 0; i < splits.length; i++) {
        value = parent[splits[i]];
        if (value === undefined) return undefined;
        if (typeof value === 'object') parent = value;
    }

    return value;
}

function findFunction (parent, dotNot) {

    var func = findValue(parent, dotNot);

    if (typeof func !== 'function') {
        return undefined;
    }

    return func;
}

function fillForm () {
    var self = this;

    // check if template form exists
    if (!self.formCache[self.template._id]) {
        return;
    }

    // reset only form UI data
    self.emit('reset', true);

    var fields = self.formCache[self.template._id].refs;

    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        // ignore data if no dom ref is available
        if (typeof self.data[field] === 'undefined') {
            continue;
        }

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {

            // change value using filters
            var value = JSON.parse(JSON.stringify(self.data))[field];

            var filterValue = fields[field].value[i].getAttribute('data-filter');
            var filterFunction = findFunction(window, filterValue);

            if (typeof filterFunction === 'function') {
                value = filterFunction(self, self.data, field, value, fields[field].value[i]);
            }

            // fill data
            if (fields[field].value[i].html) {
                fields[field].value[i].innerHTML = value;
            } else {
                if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                   fields[field].value[i].checked = toBoolean(value);
                } else {
                    fields[field].value[i].value = value;
                }
            }
        }
    }

    self.emit('formFilled');
}

function toBoolean(value) {
    if (value === true || value === 'true' || value === 'on' || value === 'yes' || value == 1) {
        return true;
    }

    return false;
}

function updateData (callback) {
    var self = this;

    if (!self.data) {
        self.data = {};
    }

    self.send = {};

    var fields = self.formCache[self.template._id].refs;

    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {
            // update data
            if (fields[field].value[i] && !fields[field].value[i].html) {

                // the value is for some inputs the "checked" property
                var value = fields[field].value[i].value;
                if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                    value = fields[field].value[i].checked;
                }

                if (self.template.schema[field].type === 'boolean') {
                    self.data[field] = self.send[field] = toBoolean(value);
                } else {
                    self.data[field] = value;

                    // ingore empty fields
                    if (value !== '') {
                        self.send[field] = value;
                    }
                }
            }
        }
    }

    self.emit('dataUpdated', callback);
}

function reset (formOnly) {
    var self = this;

    // check if template form exists
    if (!self.formCache[self.template._id]) {
        return;
    }

    var fields = self.formCache[self.template._id].refs;

    if (!formOnly) {
        // reset internal data
        self.data = {};
    }

    // reset value fields
    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {
            // textarea inputs
            if (fields[field].value[i].html) {
                fields[field].value[i].innerHTML = '';
            }
            // radio and checkbox inputs
            else if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                fields[field].value[i].checked = false;
            }
            // select inputs
            else if (fields[field].value[i].tagName === 'SELECT') {
                var select = fields[field].value[i];
                select.value = '';
                for (var j = 0; j < select.children.length; ++j) {
                    if (select.children[j].hasAttribute('selected')) {
                        select.value = select.children[j].hasAttribute('selected');
                        break;
                    }
                }
            }
            // other inputs
            else {
                fields[field].value[i].value = '';
            }
        }
    }

    self.emit('formReseted');
}

function init () {
    var self = this;

    //self.on('setFields', setFields);
    self.on('updateData', updateData);
    self.on('dataSet', fillForm);
    self.on('fieldSet', fillForm);
    self.on('reset', reset);
}

module.exports = init;

<commit_msg>Improved the SELECT default value for form reset<commit_after>function findValue (parent, dotNot) {

    if (!dotNot) return undefined;

    var splits = dotNot.split('.');
    var value;

    for (var i = 0; i < splits.length; i++) {
        value = parent[splits[i]];
        if (value === undefined) return undefined;
        if (typeof value === 'object') parent = value;
    }

    return value;
}

function findFunction (parent, dotNot) {

    var func = findValue(parent, dotNot);

    if (typeof func !== 'function') {
        return undefined;
    }

    return func;
}

function fillForm () {
    var self = this;

    // check if template form exists
    if (!self.formCache[self.template._id]) {
        return;
    }

    // reset only form UI data
    self.emit('reset', true);

    var fields = self.formCache[self.template._id].refs;

    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        // ignore data if no dom ref is available
        if (typeof self.data[field] === 'undefined') {
            continue;
        }

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {

            // change value using filters
            var value = JSON.parse(JSON.stringify(self.data))[field];

            var filterValue = fields[field].value[i].getAttribute('data-filter');
            var filterFunction = findFunction(window, filterValue);

            if (typeof filterFunction === 'function') {
                value = filterFunction(self, self.data, field, value, fields[field].value[i]);
            }

            // fill data
            if (fields[field].value[i].html) {
                fields[field].value[i].innerHTML = value;
            } else {
                if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                   fields[field].value[i].checked = toBoolean(value);
                } else {
                    fields[field].value[i].value = value;
                }
            }
        }
    }

    self.emit('formFilled');
}

function toBoolean(value) {
    if (value === true || value === 'true' || value === 'on' || value === 'yes' || value == 1) {
        return true;
    }

    return false;
}

function updateData (callback) {
    var self = this;

    if (!self.data) {
        self.data = {};
    }

    self.send = {};

    var fields = self.formCache[self.template._id].refs;

    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {
            // update data
            if (fields[field].value[i] && !fields[field].value[i].html) {

                // the value is for some inputs the "checked" property
                var value = fields[field].value[i].value;
                if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                    value = fields[field].value[i].checked;
                }

                if (self.template.schema[field].type === 'boolean') {
                    self.data[field] = self.send[field] = toBoolean(value);
                } else {
                    self.data[field] = value;

                    // ingore empty fields
                    if (value !== '') {
                        self.send[field] = value;
                    }
                }
            }
        }
    }

    self.emit('dataUpdated', callback);
}

function reset (formOnly) {
    var self = this;

    // check if template form exists
    if (!self.formCache[self.template._id]) {
        return;
    }

    var fields = self.formCache[self.template._id].refs;

    if (!formOnly) {
        // reset internal data
        self.data = {};
    }

    // reset value fields
    for (var field in fields) {
        if (!fields.hasOwnProperty(field)) continue;

        for (var i = 0, l = fields[field].value.length; i < l; ++i) {
            // textarea inputs
            if (fields[field].value[i].html) {
                fields[field].value[i].innerHTML = '';
            }
            // radio and checkbox inputs
            else if (['checkbox', 'radio'].indexOf(fields[field].value[i].getAttribute('type')) > -1) {
                fields[field].value[i].checked = false;
            }
            // select inputs
            else if (fields[field].value[i].tagName === 'SELECT') {
                var select = fields[field].value[i];
                select.value = '';
                for (var j = 0; j < select.children.length; ++j) {
                    if (select.children[j].hasAttribute('selected')) {
                        if (select.children[j].hasAttribute('value')) {
                            select.value = select.children[j].getAttribute('value');
                        } else {
                            select.value = select.children[j].innerText;
                        }
                        break;
                    }
                }
            }
            // other inputs
            else {
                fields[field].value[i].value = '';
            }
        }
    }

    self.emit('formReseted');
}

function init () {
    var self = this;

    //self.on('setFields', setFields);
    self.on('updateData', updateData);
    self.on('dataSet', fillForm);
    self.on('fieldSet', fillForm);
    self.on('reset', reset);
}

module.exports = init;

<|endoftext|>


<commit_before>/* eslint-env node */
module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: ['PhantomJS'],
  launch_in_dev: ['Chrome'],
};
<commit_msg>Switch from phantomjs to headless chrome<commit_after>/* eslint-env node */
module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: ['Chrome'],
  launch_in_dev: ['Chrome'],
  browser_args: {
    // New format in testem/master, but not in a release yet
    // Chrome: {
    //   ci: ['--headless', '--disable-gpu', '--remote-debugging-port=9222', '--window-size=1440,900'],
    // },
    Chrome: {
      mode: 'ci',
      args: [
        '--headless',
        '--disable-gpu',
        '--remote-debugging-port=9222',
        '--window-size=1440,900',
      ],
    },
  },
};
<|endoftext|>


<commit_before><commit_msg>generate server side datatables package<commit_after><|endoftext|>


<commit_before><commit_msg>Fix bug where point width exponent slider was erroneously hidden in some cases<commit_after><|endoftext|>


<commit_before>// Includes
var http = require('./http.js').func
var cache = require('../cache')

// Args
exports.required = ['group', 'userId']

// Define
function getRankInGroup (group, userId) {
  return function (resolve, reject) {
    http({url: '//www.roblox.com/Game/LuaWebService/HandleSocialRequest.ashx?method=GetGroupRole&playerid=' + userId + '&groupId=' + group})
    .then(function (body) {
      // Efficient
      resolve(parseInt(body.substring(22), 10))
    })
  }
}

exports.func = function (args) {
  var id = args.userId
  return cache.wrap('Rank', id, getRankInGroup(args.group, id))
}
<commit_msg>Update getRankNameInGroup.js<commit_after>// Includes
var http = require('./http.js').func
var cache = require('../cache')

// Args
exports.required = ['group', 'userId']

// Define
function getRankNameInGroup (group, userId) {
  return function (resolve, reject) {
    http({url: '//www.roblox.com/Game/LuaWebService/HandleSocialRequest.ashx?method=GetGroupRole&playerid=' + userId + '&groupId=' + group})
    .then(function (body) {
      // Efficient
      resolve(body.substring(22), 10)
    })
  }
}

exports.func = function (args) {
  var id = args.userId
  return cache.wrap('Rank', id, getRankNameInGroup(args.group, id))
}
<|endoftext|>


<commit_before>// Copyright 2015, EMC, Inc.

'use strict';

var di = require('di');

module.exports = ansibleFactory;

di.annotate(ansibleFactory, new di.Provide('JobUtils.Ansible.Playbook'));
di.annotate(ansibleFactory, new di.Inject(
            'Assert',
            'ChildProcess'
));

function ansibleFactory(assert, ChildProcess) {
    /**
     * @constructor
     */
    function AnsibleTool() {
        this.childProcess = undefined;
    }

    AnsibleTool.prototype.runPlaybook = function(nodeid, playbook, extraArgs) {
        var env = {
            'nodeid': nodeid
        };
        var args = [ '-i', '/opt/onrack/etc/ansible/rackhd.py', '--host', nodeid ];
        if( extraArgs )  {
          args.push("--extra-vars");
          args.push(extraArgs);
        }
        args.push(playbook);

        this.childProcess = new ChildProcess('/usr/bin/ansible-playbook',
                                             args,
                                             env);
        return this.childProcess.run();
    };

    AnsibleTool.prototype.kill = function() {
        if(this.childProcess) {
            this.childProcess.killSafe();
        }
    };

    return AnsibleTool;
}
<commit_msg>Bug Fix<commit_after>// Copyright 2015, EMC, Inc.

'use strict';

var di = require('di');

module.exports = ansibleFactory;

di.annotate(ansibleFactory, new di.Provide('JobUtils.Ansible.Playbook'));
di.annotate(ansibleFactory, new di.Inject(
            'Assert',
            'ChildProcess'
));

function ansibleFactory(assert, ChildProcess) {
    /**
     * @constructor
     */
    function AnsibleTool() {
        this.childProcess = undefined;
    }

    AnsibleTool.prototype.runPlaybook = function(nodeid, playbook, extraArgs) {
        var env = {
            'nodeid': nodeid
        };
        var args = [ '-i', '/opt/onrack/etc/ansible/rackhd.py', '-l', nodeid ];
        if( extraArgs )  {
          args.push("--extra-vars");
          args.push(extraArgs);
        }
        args.push(playbook);

        this.childProcess = new ChildProcess('/usr/bin/ansible-playbook',
                                             args,
                                             env);
        return this.childProcess.run();
    };

    AnsibleTool.prototype.kill = function() {
        if(this.childProcess) {
            this.childProcess.killSafe();
        }
    };

    return AnsibleTool;
}
<|endoftext|>


<commit_before>'use babel';

import { CompositeDisposable } from 'atom';
import path from 'path';
import fs from 'fs-plus';

let oldSortEntries,
  sortType,
  isDescending,
  isCaseSensitive,
  isSortFoldersBeforeFiles;

const getFileExtension = (filename) => {
  return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2);
};

const getFileGroup = (filename) => {
  const groups = filename.split('.');

  return groups.length < 3 ? getFileExtension(filename) : groups[groups.length - 2];
};

const isDir = (obj) => {
  if (obj && obj.constructor) {
    return (obj.constructor.name === 'Directory' || obj.__sort__dir === true);
  }
  else {
    return false;
  }
};

const compareString = (first, second) => {
  if (/[^\x00-\x80]/.test(first + second)) {
    return first.localeCompare(second);
  }

  if (first < second) {
    return -1;
  }
  else if (first > second) {
    return 1;
  }
  else {
    return 0;
  }
};

const compareStats = (key, first, second, firstName, secondName) => {
  const firstValue = first.stats && first.stats[key] ? first.stats[key] : 0;
  const secondValue = second.stats && second.stats[key] ? second.stats[key] : 0;

  if (firstValue === secondValue) {
    return compareString(firstName, secondName);
  }
  else {
    return (firstValue > secondValue ? 1 : -1);
  }
};

const normalizeEntryName = (value) => {
  const normalizedValue = value.name;

  return normalizedValue == null ? value : (isCaseSensitive ? normalizedValue : normalizedValue.toLowerCase());
};

const sort = (first, second, firstName, secondName) => {
  const descending = isDescending ? -1 : 1;

  switch (sortType) {
    default:
    case 0:
    case 1:
      return compareString(firstName, secondName) * descending;

    case 2: {
      const firstExtName = getFileExtension(firstName);
      const secondExtName = getFileExtension(secondName);
      const result = compareString(firstExtName, secondExtName);

      if (result == 0) {
        return compareString(firstName, secondName) * descending;
      }
      else {
        return result * descending;
      }
    }

    case 3:
      return compareStats('size', first, second, firstName, secondName) * descending;

    case 4:
      return compareStats('atime', first, second, firstName, secondName) * descending;

    case 5:
      return compareStats('ctime', first, second, firstName, secondName) * descending;

    case 6:
      return compareStats('mtime', first, second, firstName, secondName) * descending;

    case 7:
      return compareStats('birthtime', first, second, firstName, secondName) * descending;

    case 8: {
      const firstGroupName = getFileGroup(firstName);
      const secondGroupName = getFileGroup(secondName);
      const result = compareString(firstGroupName, secondGroupName);

      if (result == 0) {
        return compareString(firstName, secondName) * descending;
      }
      else {
        return result * descending;
      }
    }
  }
};

const sortEntries = function(combinedEntries) {
  combinedEntries.forEach((name, key) => {
    if (typeof name === 'string') {
      const fullPath = path.join(this.path, name);

      if (this.isPathIgnored(fullPath)) {
        return;
      }

      let stat = fs.lstatSyncNoException(fullPath);

      if (stat.isSymbolicLink && stat.isSymbolicLink()) {
        stat = fs.statSyncNoException(fullPath);
      }

      ['atime', 'birthtime', 'ctime', 'mtime'].forEach((value) => {
        const time = stat[value];

        stat[value] = time ? time.getTime() : 0;
      });

      if (stat.isDirectory && stat.isDirectory()) {
        combinedEntries[key] = {
          __sort__: true,
          __sort__dir: true,
          name: name,
          stats: stat
        };
      }
      else if (stat.isFile && stat.isFile()) {
        combinedEntries[key] = {
          __sort__: true,
          name: name,
          stats: stat
        };
      }
    }
  });

  const result = combinedEntries.sort((first, second) => {
    const firstName = normalizeEntryName(first);
    const secondName = normalizeEntryName(second);

    if (isDir(first) && isSortFoldersBeforeFiles) {
      if (isDir(second)) {
        if (firstName.indexOf('.') === 0 && secondName.indexOf('.') !== 0) {
          return -1;
        }
        else if (firstName.indexOf('.') !== 0 && secondName.indexOf('.') === 0) {
          return 1;
        }
        else {
          return sort(first, second, firstName, secondName);
        }
      }
      else {
        return -1;
      }
    }
    else {
      if (isDir(second) && isSortFoldersBeforeFiles) {
        return 1;
      }
      else {
        if (firstName.indexOf('.') === 0 && secondName.indexOf('.') !== 0) {
          return -1;
        }
        else if (firstName.indexOf('.') !== 0 && secondName.indexOf('.') === 0) {
          return 1;
        }
        else {
          return sort(first, second, firstName, secondName);
        }
      }
    }
  });

  result.forEach((value, key) => {
    if (value.__sort__ === true) {
      result[key] = value.name;
    }
  });

  return result;
};

export default {

  treeView: null,
  _initialized: false,

  activate() {
    this.subscriptions = new CompositeDisposable();

    atom.packages.activatePackage('tree-view').then((pkg) => {
      if (pkg && pkg.mainModule && pkg.mainModule.treeView) {
        this.treeView = pkg.mainModule.treeView;

        if (!this.treeView.roots[0] || !this.treeView.roots[0].directory) {
          atom.project.onDidChangePaths(() => {
            this._initialize();
          });

          return;
        }

        this._initialize();
      }
    }, (reason) => {
      atom.notifications.addWarning('tree-view-sort active failure.', {
        description: reason.message
      });
    });
  },

  deactivate() {
    this.unsetSortEntries();
    this.reload();
    this.subscriptions.dispose();
    this._initialized = false;
  },

  _initialize() {
    if (this._initialized) {
      return;
    }

    sortType = atom.config.get('tree-view-sort.type');
    isDescending = atom.config.get('tree-view-sort.descending');
    isCaseSensitive = atom.config.get('tree-view-sort.caseSensitive');
    isSortFoldersBeforeFiles = atom.config.get('tree-view-sort.sortFoldersBeforeFiles');

    oldSortEntries = this.treeView.roots[0].directory.constructor.prototype.sortEntries;

    if (sortType) {
      this.setSortEntries();
      this.reload();
    }

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.type', ({newValue}) => {
      sortType = newValue;

      if (sortType) {
        this.setSortEntries();
      }
      else {
        this.unsetSortEntries();
      }

      this.reload();
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.descending', ({newValue}) => {
      isDescending = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.caseSensitive', ({newValue}) => {
      isCaseSensitive = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.sortFoldersBeforeFiles', ({newValue}) => {
      isSortFoldersBeforeFiles = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this._initialized = true;
  },

  setSortEntries() {
    this.treeView.roots[0].directory.constructor.prototype.sortEntries = sortEntries;
  },

  unsetSortEntries() {
    this.treeView.roots[0].directory.constructor.prototype.sortEntries = oldSortEntries;
  },

  reload() {
    if (this.treeView) {
      this.treeView.updateRoots();
    }
  }
};
<commit_msg>add command<commit_after>'use babel';

import { CompositeDisposable } from 'atom';
import path from 'path';
import fs from 'fs-plus';

let oldSortEntries,
  sortType,
  oldSortType,
  isDescending,
  isCaseSensitive,
  isSortFoldersBeforeFiles;

const getFileExtension = (filename) => {
  return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2);
};

const getFileGroup = (filename) => {
  const groups = filename.split('.');

  return groups.length < 3 ? getFileExtension(filename) : groups[groups.length - 2];
};

const isDir = (obj) => {
  if (obj && obj.constructor) {
    return (obj.constructor.name === 'Directory' || obj.__sort__dir === true);
  }
  else {
    return false;
  }
};

const compareString = (first, second) => {
  if (/[^\x00-\x80]/.test(first + second)) {
    return first.localeCompare(second);
  }

  if (first < second) {
    return -1;
  }
  else if (first > second) {
    return 1;
  }
  else {
    return 0;
  }
};

const compareStats = (key, first, second, firstName, secondName) => {
  const firstValue = first.stats && first.stats[key] ? first.stats[key] : 0;
  const secondValue = second.stats && second.stats[key] ? second.stats[key] : 0;

  if (firstValue === secondValue) {
    return compareString(firstName, secondName);
  }
  else {
    return (firstValue > secondValue ? 1 : -1);
  }
};

const normalizeEntryName = (value) => {
  const normalizedValue = value.name;

  return normalizedValue == null ? value : (isCaseSensitive ? normalizedValue : normalizedValue.toLowerCase());
};

const sort = (first, second, firstName, secondName) => {
  const descending = isDescending ? -1 : 1;

  switch (sortType) {
    default:
    case 0:
    case 1:
      return compareString(firstName, secondName) * descending;

    case 2: {
      const firstExtName = getFileExtension(firstName);
      const secondExtName = getFileExtension(secondName);
      const result = compareString(firstExtName, secondExtName);

      if (result == 0) {
        return compareString(firstName, secondName) * descending;
      }
      else {
        return result * descending;
      }
    }

    case 3:
      return compareStats('size', first, second, firstName, secondName) * descending;

    case 4:
      return compareStats('atime', first, second, firstName, secondName) * descending;

    case 5:
      return compareStats('ctime', first, second, firstName, secondName) * descending;

    case 6:
      return compareStats('mtime', first, second, firstName, secondName) * descending;

    case 7:
      return compareStats('birthtime', first, second, firstName, secondName) * descending;

    case 8: {
      const firstGroupName = getFileGroup(firstName);
      const secondGroupName = getFileGroup(secondName);
      const result = compareString(firstGroupName, secondGroupName);

      if (result == 0) {
        return compareString(firstName, secondName) * descending;
      }
      else {
        return result * descending;
      }
    }
  }
};

const sortEntries = function(combinedEntries) {
  combinedEntries.forEach((name, key) => {
    if (typeof name === 'string') {
      const fullPath = path.join(this.path, name);

      if (this.isPathIgnored(fullPath)) {
        return;
      }

      let stat = fs.lstatSyncNoException(fullPath);

      if (stat.isSymbolicLink && stat.isSymbolicLink()) {
        stat = fs.statSyncNoException(fullPath);
      }

      ['atime', 'birthtime', 'ctime', 'mtime'].forEach((value) => {
        const time = stat[value];

        stat[value] = time ? time.getTime() : 0;
      });

      if (stat.isDirectory && stat.isDirectory()) {
        combinedEntries[key] = {
          __sort__: true,
          __sort__dir: true,
          name: name,
          stats: stat
        };
      }
      else if (stat.isFile && stat.isFile()) {
        combinedEntries[key] = {
          __sort__: true,
          name: name,
          stats: stat
        };
      }
    }
  });

  const result = combinedEntries.sort((first, second) => {
    const firstName = normalizeEntryName(first);
    const secondName = normalizeEntryName(second);

    if (isDir(first) && isSortFoldersBeforeFiles) {
      if (isDir(second)) {
        if (firstName.indexOf('.') === 0 && secondName.indexOf('.') !== 0) {
          return -1;
        }
        else if (firstName.indexOf('.') !== 0 && secondName.indexOf('.') === 0) {
          return 1;
        }
        else {
          return sort(first, second, firstName, secondName);
        }
      }
      else {
        return -1;
      }
    }
    else {
      if (isDir(second) && isSortFoldersBeforeFiles) {
        return 1;
      }
      else {
        if (firstName.indexOf('.') === 0 && secondName.indexOf('.') !== 0) {
          return -1;
        }
        else if (firstName.indexOf('.') !== 0 && secondName.indexOf('.') === 0) {
          return 1;
        }
        else {
          return sort(first, second, firstName, secondName);
        }
      }
    }
  });

  result.forEach((value, key) => {
    if (value.__sort__ === true) {
      result[key] = value.name;
    }
  });

  return result;
};

export default {

  treeView: null,
  _initialized: false,

  activate() {
    this.subscriptions = new CompositeDisposable();

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'tree-view-sort:toggle': () => {
        const value = atom.config.get('tree-view-sort.type');

        if (value) {
          oldSortType = value;
          atom.config.set('tree-view-sort.type', 0);
        }
        else {
          atom.config.set('tree-view-sort.type', oldSortType);
        }
      }
    }));

    atom.packages.activatePackage('tree-view').then((pkg) => {
      if (pkg && pkg.mainModule && pkg.mainModule.treeView) {
        this.treeView = pkg.mainModule.treeView;

        if (!this.treeView.roots[0] || !this.treeView.roots[0].directory) {
          atom.project.onDidChangePaths(() => {
            this._initialize();
          });

          return;
        }

        this._initialize();
      }
    }, (reason) => {
      atom.notifications.addWarning('tree-view-sort active failure.', {
        description: reason.message
      });
    });
  },

  deactivate() {
    this.unsetSortEntries();
    this.reload();
    this.subscriptions.dispose();
    this._initialized = false;
  },

  _initialize() {
    if (this._initialized) {
      return;
    }

    sortType = atom.config.get('tree-view-sort.type');
    isDescending = atom.config.get('tree-view-sort.descending');
    isCaseSensitive = atom.config.get('tree-view-sort.caseSensitive');
    isSortFoldersBeforeFiles = atom.config.get('tree-view-sort.sortFoldersBeforeFiles');

    oldSortEntries = this.treeView.roots[0].directory.constructor.prototype.sortEntries;

    if (sortType) {
      this.setSortEntries();
      this.reload();
    }

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.type', ({newValue}) => {
      sortType = newValue;

      if (sortType) {
        this.setSortEntries();
      }
      else {
        this.unsetSortEntries();
      }

      this.reload();
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.descending', ({newValue}) => {
      isDescending = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.caseSensitive', ({newValue}) => {
      isCaseSensitive = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this.subscriptions.add(atom.config.onDidChange('tree-view-sort.sortFoldersBeforeFiles', ({newValue}) => {
      isSortFoldersBeforeFiles = newValue;

      if (sortType) {
        this.reload();
      }
    }));

    this._initialized = true;
  },

  setSortEntries() {
    this.treeView.roots[0].directory.constructor.prototype.sortEntries = sortEntries;
  },

  unsetSortEntries() {
    this.treeView.roots[0].directory.constructor.prototype.sortEntries = oldSortEntries;
  },

  reload() {
    if (this.treeView) {
      this.treeView.updateRoots();
    }
  }
};
<|endoftext|>