<commit_before>const puppeteer = require("puppeteer");
const _ = require("highland");
const url = require("url");
const mapStackTrace = require("sourcemapped-stacktrace-node").default;
const path = require("path");
const fs = require("fs");
const {createTracker, augmentTimeoutError} = require("./tracker");

/**
 * @param {{page: Page, options: {skipThirdPartyRequests: true}, basePath: string }} opt
 * @return {Promise<void>}
 */
const skipThirdPartyRequests = async opt => {
  const { page, options, basePath } = opt;
  if (!options.skipThirdPartyRequests) return;
  await page.setRequestInterception(true);
  page.on("request", request => {
    if (request.url().startsWith(basePath)) {
      request.continue();
    } else {
      request.abort();
    }
  });
};

/**
 * @param {{page: Page, options: {sourceMaps: boolean}, route: string, onError: ?function }} opt
 * @return {void}
 */
const enableLogging = opt => {
  const { page, options, route, onError, sourcemapStore } = opt;
  page.on("console", msg => {
    const text = msg.text();
    if (text !== 'JSHandle@object') {
      console.log(`💬  console.log at ${route}:`, text)
    } else {
      Promise.all(msg.args().map(x => x.jsonValue())).then(args =>
        console.log(`💬  console.log at ${route}:`, ...args)
      )
    }
  });
  page.on("error", msg => {
    console.log(`🔥  error at ${route}:`, msg);
    onError && onError();
  });
  page.on("pageerror", e => {
    if (options.sourceMaps) {
      mapStackTrace(e.stack || e.message, {
        isChromeOrEdge: true,
        store: sourcemapStore || {}
      })
        .then(result => {
          // TODO: refactor mapStackTrace: return array not a string, return first row too
          const stackRows = result.split("\n");
          const puppeteerLine =
            stackRows.findIndex(x => x.includes("puppeteer")) ||
            stackRows.length - 1;

          console.log(
            `🔥  pageerror at ${route}: ${(e.stack || e.message).split("\n")[0] +
              "\n"}${stackRows.slice(0, puppeteerLine).join("\n")}`
          );
        })
        .catch(e2 => {
          console.log(`🔥  pageerror at ${route}:`, e);
          console.log(`⚠  warning at ${route} (error in source maps):`, e2.message);
        });
    } else {
      console.log(`🔥  pageerror at ${route}:`, e);
    }
    onError && onError();
  });
  page.on("response", response => {
    if (response.status() >= 400) {
      let route = ''
      try {
        route = response._request.headers().referer.replace(`http://localhost:${options.port}`, "");
      } catch (e) {}
      console.log(`⚠  warning at ${route}: got ${response.status()} HTTP code for ${response.url()}`);
    }
  });
  // page.on("requestfailed", msg =>
  //   console.log(`⚠  ${route} requestfailed:`, msg)
  // );
};

/**
 * @param {{page: Page}} opt
 * @return {Promise<Array<string>>}
 */
const getLinks = async opt => {
  const { page } = opt;
  const anchors = await page.evaluate(() =>
    Array.from(document.querySelectorAll("a")).map(anchor => anchor.href)
  );

  const iframes = await page.evaluate(() =>
    Array.from(document.querySelectorAll("iframe")).map(iframe => iframe.src)
  );
  return anchors.concat(iframes);
};

/**
 * can not use null as default for function because of TS error https://github.com/Microsoft/TypeScript/issues/14889
 *
 * @param {{options: *, basePath: string, beforeFetch: ?(function({ page: Page, route: string }):Promise), afterFetch: ?(function({ page: Page, browser: Browser, route: string }):Promise), onEnd: ?(function():void)}} opt
 * @return {Promise}
 */
const crawl = async opt => {
  const {
    options,
    basePath,
    beforeFetch,
    afterFetch,
    onEnd,
    publicPath,
    sourceDir
  } = opt;
  let shuttingDown = false;
  let streamClosed = false;

  const onSigint = () => {
    if (shuttingDown) {
      process.exit(1);
    } else {
      shuttingDown = true;
      console.log(
        "\nGracefully shutting down. To exit immediately, press ^C again"
      );
    }
  };
  process.on("SIGINT", onSigint);

  const onUnhandledRejection = error => {
    console.log("🔥  UnhandledPromiseRejectionWarning", error);
    shuttingDown = true;
  };
  process.on("unhandledRejection", onUnhandledRejection);

  const queue = _();
  let enqued = 0;
  let processed = 0;
  // use Set instead
  const uniqueUrls = new Set();
  const sourcemapStore = {};

  /**
   * @param {string} path
   * @returns {void}
   */
  const addToQueue = newUrl => {
    const { hostname, search, hash } = url.parse(newUrl);
    newUrl = newUrl.replace(`${search || ""}${hash || ""}`, "");
    if (hostname === "localhost" && !uniqueUrls.has(newUrl) && !streamClosed) {
      uniqueUrls.add(newUrl);
      enqued++;
      queue.write(newUrl);
      if (enqued == 2 && options.crawl) {
        addToQueue(`${basePath}${publicPath}/404.html`);
      }
    }
  };

  const browser = await puppeteer.launch({
    headless: options.headless,
    args: options.puppeteerArgs,
    executablePath: options.puppeteerExecutablePath,
    ignoreHTTPSErrors: options.puppeteerIgnoreHTTPSErrors,
    handleSIGINT: false
  });

  /**
   * @param {string} pageUrl
   * @returns {Promise<string>}
   */
  const fetchPage = async pageUrl => {
    const route = pageUrl.replace(basePath, "");

    let skipExistingFile = false;
    const routePath = route.replace(/\//g, path.sep);
    const { ext } = path.parse(routePath);
    if (ext !== ".html" && ext !== "") {
      const filePath = path.join(sourceDir, routePath);
      skipExistingFile = fs.existsSync(filePath);
    }

    if (!shuttingDown && !skipExistingFile) {
      try {
        const page = await browser.newPage();
        await page.setCacheEnabled(options.puppeteer.cache);
        if (options.viewport) await page.setViewport(options.viewport);
        if (options.skipThirdPartyRequests)
          await skipThirdPartyRequests({ page, options, basePath });
        enableLogging({
          page,
          options,
          route,
          onError: () => {
            shuttingDown = true;
          },
          sourcemapStore
        });
        beforeFetch && beforeFetch({ page, route });
        await page.setUserAgent(options.userAgent);
        const tracker = createTracker(page)
        try {
          await page.goto(pageUrl, { waitUntil: "networkidle0" });
        } catch (e) {
          e.message = augmentTimeoutError(e.message, tracker);
          throw e;
        } finally {
          tracker.dispose();
        }
        if (options.waitFor) await page.waitFor(options.waitFor);
        if (options.crawl) {
          const links = await getLinks({ page });
          links.forEach(addToQueue);
        }
        afterFetch && (await afterFetch({ page, route, browser }));
        await page.close();
        console.log(`✅  crawled ${processed + 1} out of ${enqued} (${route})`);
      } catch (e) {
        if (!shuttingDown) {
          console.log(`🔥  error at ${route}`, e);
        }
        shuttingDown = true;
      }
    } else {
      // this message creates a lot of noise
      // console.log(`🚧  skipping (${processed + 1}/${enqued}) ${route}`);
    }
    processed++;
    if (enqued === processed) {
      streamClosed = true;
      queue.end();
    }
    return pageUrl;
  };

  if (options.include) {
    options.include.map(x => addToQueue(`${basePath}${x}`));
  }

  return new Promise((resolve, reject) => {
    queue
      .map(x => _(fetchPage(x)))
      .mergeWithLimit(options.concurrency)
      .toArray(async () => {
        process.removeListener("SIGINT", onSigint);
        process.removeListener("unhandledRejection", onUnhandledRejection);
        await browser.close();
        onEnd && onEnd();
        if (shuttingDown) return reject("");
        resolve();
      });
  });
};

exports.skipThirdPartyRequests = skipThirdPartyRequests;
exports.enableLogging = enableLogging;
exports.getLinks = getLinks;
exports.crawl = crawl;
<commit_msg>Broken SVG Links<commit_after>const puppeteer = require("puppeteer");
const _ = require("highland");
const url = require("url");
const mapStackTrace = require("sourcemapped-stacktrace-node").default;
const path = require("path");
const fs = require("fs");
const {createTracker, augmentTimeoutError} = require("./tracker");

/**
 * @param {{page: Page, options: {skipThirdPartyRequests: true}, basePath: string }} opt
 * @return {Promise<void>}
 */
const skipThirdPartyRequests = async opt => {
  const { page, options, basePath } = opt;
  if (!options.skipThirdPartyRequests) return;
  await page.setRequestInterception(true);
  page.on("request", request => {
    if (request.url().startsWith(basePath)) {
      request.continue();
    } else {
      request.abort();
    }
  });
};

/**
 * @param {{page: Page, options: {sourceMaps: boolean}, route: string, onError: ?function }} opt
 * @return {void}
 */
const enableLogging = opt => {
  const { page, options, route, onError, sourcemapStore } = opt;
  page.on("console", msg => {
    const text = msg.text();
    if (text !== 'JSHandle@object') {
      console.log(`💬  console.log at ${route}:`, text)
    } else {
      Promise.all(msg.args().map(x => x.jsonValue())).then(args =>
        console.log(`💬  console.log at ${route}:`, ...args)
      )
    }
  });
  page.on("error", msg => {
    console.log(`🔥  error at ${route}:`, msg);
    onError && onError();
  });
  page.on("pageerror", e => {
    if (options.sourceMaps) {
      mapStackTrace(e.stack || e.message, {
        isChromeOrEdge: true,
        store: sourcemapStore || {}
      })
        .then(result => {
          // TODO: refactor mapStackTrace: return array not a string, return first row too
          const stackRows = result.split("\n");
          const puppeteerLine =
            stackRows.findIndex(x => x.includes("puppeteer")) ||
            stackRows.length - 1;

          console.log(
            `🔥  pageerror at ${route}: ${(e.stack || e.message).split("\n")[0] +
              "\n"}${stackRows.slice(0, puppeteerLine).join("\n")}`
          );
        })
        .catch(e2 => {
          console.log(`🔥  pageerror at ${route}:`, e);
          console.log(`⚠  warning at ${route} (error in source maps):`, e2.message);
        });
    } else {
      console.log(`🔥  pageerror at ${route}:`, e);
    }
    onError && onError();
  });
  page.on("response", response => {
    if (response.status() >= 400) {
      let route = ''
      try {
        route = response._request.headers().referer.replace(`http://localhost:${options.port}`, "");
      } catch (e) {}
      console.log(`⚠  warning at ${route}: got ${response.status()} HTTP code for ${response.url()}`);
    }
  });
  // page.on("requestfailed", msg =>
  //   console.log(`⚠  ${route} requestfailed:`, msg)
  // );
};

/**
 * @param {{page: Page}} opt
 * @return {Promise<Array<string>>}
 */
const getLinks = async opt => {
  const { page } = opt;
  const anchors = await page.evaluate(() =>
    Array.from(document.querySelectorAll("a")).map(anchor => {
      if(anchor.href.baseVal){
        return location.origin + anchor.href.baseVal;
      }
      return anchor.href
    })
  );

  const iframes = await page.evaluate(() =>
    Array.from(document.querySelectorAll("iframe")).map(iframe => iframe.src)
  );
  return anchors.concat(iframes);
};

/**
 * can not use null as default for function because of TS error https://github.com/Microsoft/TypeScript/issues/14889
 *
 * @param {{options: *, basePath: string, beforeFetch: ?(function({ page: Page, route: string }):Promise), afterFetch: ?(function({ page: Page, browser: Browser, route: string }):Promise), onEnd: ?(function():void)}} opt
 * @return {Promise}
 */
const crawl = async opt => {
  const {
    options,
    basePath,
    beforeFetch,
    afterFetch,
    onEnd,
    publicPath,
    sourceDir
  } = opt;
  let shuttingDown = false;
  let streamClosed = false;

  const onSigint = () => {
    if (shuttingDown) {
      process.exit(1);
    } else {
      shuttingDown = true;
      console.log(
        "\nGracefully shutting down. To exit immediately, press ^C again"
      );
    }
  };
  process.on("SIGINT", onSigint);

  const onUnhandledRejection = error => {
    console.log("🔥  UnhandledPromiseRejectionWarning", error);
    shuttingDown = true;
  };
  process.on("unhandledRejection", onUnhandledRejection);

  const queue = _();
  let enqued = 0;
  let processed = 0;
  // use Set instead
  const uniqueUrls = new Set();
  const sourcemapStore = {};

  /**
   * @param {string} path
   * @returns {void}
   */
  const addToQueue = newUrl => {
    const { hostname, search, hash } = url.parse(newUrl);
    newUrl = newUrl.replace(`${search || ""}${hash || ""}`, "");
    if (hostname === "localhost" && !uniqueUrls.has(newUrl) && !streamClosed) {
      uniqueUrls.add(newUrl);
      enqued++;
      queue.write(newUrl);
      if (enqued == 2 && options.crawl) {
        addToQueue(`${basePath}${publicPath}/404.html`);
      }
    }
  };

  const browser = await puppeteer.launch({
    headless: options.headless,
    args: options.puppeteerArgs,
    executablePath: options.puppeteerExecutablePath,
    ignoreHTTPSErrors: options.puppeteerIgnoreHTTPSErrors,
    handleSIGINT: false
  });

  /**
   * @param {string} pageUrl
   * @returns {Promise<string>}
   */
  const fetchPage = async pageUrl => {
    const route = pageUrl.replace(basePath, "");

    let skipExistingFile = false;
    const routePath = route.replace(/\//g, path.sep);
    const { ext } = path.parse(routePath);
    if (ext !== ".html" && ext !== "") {
      const filePath = path.join(sourceDir, routePath);
      skipExistingFile = fs.existsSync(filePath);
    }

    if (!shuttingDown && !skipExistingFile) {
      try {
        const page = await browser.newPage();
        await page.setCacheEnabled(options.puppeteer.cache);
        if (options.viewport) await page.setViewport(options.viewport);
        if (options.skipThirdPartyRequests)
          await skipThirdPartyRequests({ page, options, basePath });
        enableLogging({
          page,
          options,
          route,
          onError: () => {
            shuttingDown = true;
          },
          sourcemapStore
        });
        beforeFetch && beforeFetch({ page, route });
        await page.setUserAgent(options.userAgent);
        const tracker = createTracker(page)
        try {
          await page.goto(pageUrl, { waitUntil: "networkidle0" });
        } catch (e) {
          e.message = augmentTimeoutError(e.message, tracker);
          throw e;
        } finally {
          tracker.dispose();
        }
        if (options.waitFor) await page.waitFor(options.waitFor);
        if (options.crawl) {
          const links = await getLinks({ page });
          links.forEach(addToQueue);
        }
        afterFetch && (await afterFetch({ page, route, browser }));
        await page.close();
        console.log(`✅  crawled ${processed + 1} out of ${enqued} (${route})`);
      } catch (e) {
        if (!shuttingDown) {
          console.log(`🔥  error at ${route}`, e);
        }
        shuttingDown = true;
      }
    } else {
      // this message creates a lot of noise
      // console.log(`🚧  skipping (${processed + 1}/${enqued}) ${route}`);
    }
    processed++;
    if (enqued === processed) {
      streamClosed = true;
      queue.end();
    }
    return pageUrl;
  };

  if (options.include) {
    options.include.map(x => addToQueue(`${basePath}${x}`));
  }

  return new Promise((resolve, reject) => {
    queue
      .map(x => _(fetchPage(x)))
      .mergeWithLimit(options.concurrency)
      .toArray(async () => {
        process.removeListener("SIGINT", onSigint);
        process.removeListener("unhandledRejection", onUnhandledRejection);
        await browser.close();
        onEnd && onEnd();
        if (shuttingDown) return reject("");
        resolve();
      });
  });
};

exports.skipThirdPartyRequests = skipThirdPartyRequests;
exports.enableLogging = enableLogging;
exports.getLinks = getLinks;
exports.crawl = crawl;
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var Q = require('q');
var debounce = require('debounce');
var utils = require('./utils');
var child_process = require('child_process');

// Returns a promise.
module.exports = exports = function push(target, watch) {
  var argsAsJson = JSON.stringify([].slice.call(arguments));
  return checkFileHandleLimit()
  .then(function(fileHandleLimit) {
    if (fileHandleLimit < 10000 && watch) {
      return relaunchWithBiggerUlimit(argsAsJson);
    }
    target = !target || Array.isArray(target) ? target : [target];
    var ret = Q.when(target);
    if (!target) {
      ret = extractTargets()
    }
    return ret.then(function(targets) {
      return createSession(targets)
    }).then(function(session) {
      return pushAll(session.clientInfos)
      .then(function() {
        if (watch) {
          return watchFiles(session);
        }
      });
    });
  });
};

function extractTargets() {
  // TODO: Use adbkit for smarter auto-detection.
  return Q.when(['localhost:2424']);
}

function createSession(targets) {
  var PushClient = require('chrome-app-developer-tool-client');

  var deferred = Q.defer();
  var i = 0;
  var ret = {
    platforms: [],
    clientInfos: [],
    appType: null
  };

  var chromeAppPushRoot = null;
  if (fs.existsSync('www/manifest.json')) {
    chromeAppPushRoot = 'www';
  } else if (fs.existsSync('manifest.json')) {
    chromeAppPushRoot = '.';
  }
  ret.appType = chromeAppPushRoot ? 'chrome' : 'cordova';

  var platformMap = Object.create(null);
  function createClient() {
    var target = targets[i++];
    if (!target) {
      ret.platforms = Object.keys(platformMap);
      return ret;
    }
    var newClient = new PushClient(target);
    return newClient.info()
    .then(function(response) {
      var infoJson = response.body;
      var platform = infoJson['platform'];
      platformMap[platform] = true;
      if (ret.appType == 'chrome') {
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession(chromeAppPushRoot),
            watchDir: chromeAppPushRoot
        });
      } else {
        // Vanilla Cordova project.
        var wwwDir = utils.assetDirForPlatform(platform);
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession('.'), // push client figures out to use platforms/
            watchDir: wwwDir
        });
      }
      return createClient();
    }, function(error) {
      if (error.code === 'ECONNREFUSED') {
        console.warn('\nPlease run `adb forward tcp:2424 tcp:2424`, and then try pushing again.');
      } else if (error.code === 'ECONNRESET') {
        console.warn('\nPlease make sure that the Chrome App Developer Tool for Mobile is running on your device.');
      } else {
        console.error(error);
      }
      process.exit();
    });
  }
  return createClient();
}

var pushInProgress = false;
var pushAgainWhenDone = false;
function pushAll(clientInfos) {
  if (pushInProgress) {
    pushAgainWhenDone = true;
    return Q();
  }
  pushInProgress = true;
  var allPromises = clientInfos.map(function(clientInfo) {
    try {
      return clientInfo.pushSession.push();
    } catch (e) {
      if (/Not a Cordova project/.test(e)) {
        console.warn('Please navigate to a Chrome App or Cordova project, and then try pushing again.');
      } else {
        console.error(e);
      }
      process.exit();
    }
  });
  var pushAgain = false;
  return Q.all(allPromises)
  .then(function() {
    if (pushAgainWhenDone) {
      return process.nextTick(function() {
        pushAll(clientInfos).done();
      });
    }
    pushInProgress = false;
    pushAgainWhenDone = false;
  }, function(e) {
    pushInProgress = false;
    pushAgainWhenDone = false;
    throw e;
  });
}

var debouncedPushAll = debounce(function(clientInfos) {
  pushAll(clientInfos).done();
}, 50, false);

function watchFiles(session) {
  var gaze = require('gaze');
  var deferred = Q.defer();

  // TODO: This doesn't work for vanilla cordova apps + multiple platforms.
  var watchDir = session.clientInfos[0].watchDir;
  // Note: gaze doesn't work well with ./ prefix nor with absolute paths
  // (https://github.com/gruntjs/grunt-contrib-watch/issues/166)
  // path.join() is smart enough to remove the ./ prefix.
  gaze(path.join(watchDir, '**', '*'), function(err, watcher) {
    console.log('Watching for changes.');
    watcher.on('all', function(event, filepath) {
      debouncedPushAll(session.clientInfos);
    });
  });
  // TODO: Capture Ctrl-C and resolve the promise.
  return deferred.promise;
}

function checkFileHandleLimit() {
  var deferred = Q.defer();
  if (process.platform != 'win32' && process.env['SHELL']) {
    // gaze opens a lot of file handles, and the default on OS X is too small (EMFILE exceptions).
    // NOTE: This is fixed in node 0.11, and is a problem only on node 0.10.
    child_process.exec('ulimit -S -n', function(error, stdout, stderr) {
      var curLimit = !error && +stdout;
      deferred.resolve(curLimit || Infinity);
    });
  } else {
    deferred.resolve(Infinity);
  }
  return deferred.promise;
}

function relaunchWithBiggerUlimit(argsAsJson) {
  // re-run with the new ulimit
  var deferred = Q.defer();
  var args = ['-c', 'ulimit -S -n 10240; exec "' + process.argv[0] + '" "' + __filename + '" "' + argsAsJson.replace(/"/g, '@') + '"'];
  var child = child_process.spawn(process.env['SHELL'], args, { stdio: 'inherit' });
  child.on('close', function(code) {
    if (code) {
      deferred.reject(code);
    } else {
      deferred.resolve(code);
    }
  });
  return deferred.promise;
}

// Gets called from EMFILE re-launch
if (require.main === module) {
  exports.apply(this, JSON.parse(process.argv[2].replace(/@/g, '"'))).done();
}
<commit_msg>Beef up error message when cca push finds no devices<commit_after>var fs = require('fs');
var path = require('path');
var Q = require('q');
var debounce = require('debounce');
var utils = require('./utils');
var child_process = require('child_process');

// Returns a promise.
module.exports = exports = function push(target, watch) {
  var argsAsJson = JSON.stringify([].slice.call(arguments));
  return checkFileHandleLimit()
  .then(function(fileHandleLimit) {
    if (fileHandleLimit < 10000 && watch) {
      return relaunchWithBiggerUlimit(argsAsJson);
    }
    target = !target || Array.isArray(target) ? target : [target];
    var ret = Q.when(target);
    if (!target) {
      ret = extractTargets()
    }
    return ret.then(function(targets) {
      return createSession(targets)
    }).then(function(session) {
      return pushAll(session.clientInfos)
      .then(function() {
        if (watch) {
          return watchFiles(session);
        }
      });
    });
  });
};

function extractTargets() {
  // TODO: Use adbkit for smarter auto-detection.
  return Q.when(['localhost:2424']);
}

function createSession(targets) {
  var PushClient = require('chrome-app-developer-tool-client');

  var deferred = Q.defer();
  var i = 0;
  var ret = {
    platforms: [],
    clientInfos: [],
    appType: null
  };

  var chromeAppPushRoot = null;
  if (fs.existsSync('www/manifest.json')) {
    chromeAppPushRoot = 'www';
  } else if (fs.existsSync('manifest.json')) {
    chromeAppPushRoot = '.';
  }
  ret.appType = chromeAppPushRoot ? 'chrome' : 'cordova';

  var platformMap = Object.create(null);
  function createClient() {
    var target = targets[i++];
    if (!target) {
      ret.platforms = Object.keys(platformMap);
      return ret;
    }
    var newClient = new PushClient(target);
    return newClient.info()
    .then(function(response) {
      var infoJson = response.body;
      var platform = infoJson['platform'];
      platformMap[platform] = true;
      if (ret.appType == 'chrome') {
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession(chromeAppPushRoot),
            watchDir: chromeAppPushRoot
        });
      } else {
        // Vanilla Cordova project.
        var wwwDir = utils.assetDirForPlatform(platform);
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession('.'), // push client figures out to use platforms/
            watchDir: wwwDir
        });
      }
      return createClient();
    }, function(error) {
      if (error.code === 'ECONNREFUSED') {
        console.warn();
        console.warn('Could not connect to device at ' + target);
        console.warn('For a USB connected Android device, try running: adb forward tcp:2424 tcp:2424');
        console.warn('For a networked device, use --target=DEVICE_IP_ADDRESS');
      } else if (error.code === 'ECONNRESET') {
        console.warn('\nPlease make sure that the Chrome App Developer Tool for Mobile is running on your device.');
      } else {
        console.error(error);
      }
      process.exit();
    });
  }
  return createClient();
}

var pushInProgress = false;
var pushAgainWhenDone = false;
function pushAll(clientInfos) {
  if (pushInProgress) {
    pushAgainWhenDone = true;
    return Q();
  }
  pushInProgress = true;
  var allPromises = clientInfos.map(function(clientInfo) {
    try {
      return clientInfo.pushSession.push();
    } catch (e) {
      if (/Not a Cordova project/.test(e)) {
        console.warn('Please navigate to a Chrome App or Cordova project, and then try pushing again.');
      } else {
        console.error(e);
      }
      process.exit();
    }
  });
  var pushAgain = false;
  return Q.all(allPromises)
  .then(function() {
    if (pushAgainWhenDone) {
      return process.nextTick(function() {
        pushAll(clientInfos).done();
      });
    }
    pushInProgress = false;
    pushAgainWhenDone = false;
  }, function(e) {
    pushInProgress = false;
    pushAgainWhenDone = false;
    throw e;
  });
}

var debouncedPushAll = debounce(function(clientInfos) {
  pushAll(clientInfos).done();
}, 50, false);

function watchFiles(session) {
  var gaze = require('gaze');
  var deferred = Q.defer();

  // TODO: This doesn't work for vanilla cordova apps + multiple platforms.
  var watchDir = session.clientInfos[0].watchDir;
  // Note: gaze doesn't work well with ./ prefix nor with absolute paths
  // (https://github.com/gruntjs/grunt-contrib-watch/issues/166)
  // path.join() is smart enough to remove the ./ prefix.
  gaze(path.join(watchDir, '**', '*'), function(err, watcher) {
    console.log('Watching for changes.');
    watcher.on('all', function(event, filepath) {
      debouncedPushAll(session.clientInfos);
    });
  });
  // TODO: Capture Ctrl-C and resolve the promise.
  return deferred.promise;
}

function checkFileHandleLimit() {
  var deferred = Q.defer();
  if (process.platform != 'win32' && process.env['SHELL']) {
    // gaze opens a lot of file handles, and the default on OS X is too small (EMFILE exceptions).
    // NOTE: This is fixed in node 0.11, and is a problem only on node 0.10.
    child_process.exec('ulimit -S -n', function(error, stdout, stderr) {
      var curLimit = !error && +stdout;
      deferred.resolve(curLimit || Infinity);
    });
  } else {
    deferred.resolve(Infinity);
  }
  return deferred.promise;
}

function relaunchWithBiggerUlimit(argsAsJson) {
  // re-run with the new ulimit
  var deferred = Q.defer();
  var args = ['-c', 'ulimit -S -n 10240; exec "' + process.argv[0] + '" "' + __filename + '" "' + argsAsJson.replace(/"/g, '@') + '"'];
  var child = child_process.spawn(process.env['SHELL'], args, { stdio: 'inherit' });
  child.on('close', function(code) {
    if (code) {
      deferred.reject(code);
    } else {
      deferred.resolve(code);
    }
  });
  return deferred.promise;
}

// Gets called from EMFILE re-launch
if (require.main === module) {
  exports.apply(this, JSON.parse(process.argv[2].replace(/@/g, '"'))).done();
}
<|endoftext|>


<commit_before>'use strict';

const fs            = require('fs');
const path          = require('path');
const streamBuffers = require('stream-buffers');
const AWS           = require('aws-sdk');
const archiver      = require('archiver');
const waterfall     = require('waterfall');
const async         = require('async');
const arn           = require('../../common/arn.js');
const roles         = require('../../common/roles.js');
const policies      = require('../../common/policies.js');
const createHandler = require('../lib/handler.js');

exports.command = 'update';
exports.desc    = 'Uploads the contents of dist to lambda as a new function version';
exports.builder = {
  test: {
    describe:       'Outputs bundled code to build directory and does not contact AWS',
    boolean:        true,
    default:        false,
  },
};

function createCodeBundle(dist, next) {
  let output = new streamBuffers.WritableStreamBuffer();
  let archive = archiver('zip', {
    store: true,
  });
  output.on('finish', () => next(null, output.getContents()));
  archive.on('error', next);
  archive.pipe(output);
  archive.directory(dist + '/', '.');
  archive.finalize();
}

function addCodeParams(params, bufferCode) {
  Object.assign(params, {
    Publish:        true,
  });
}

function addConfigParams(params, role, deadLetterArn, config, settings) {
  config = config || {};
  Object.assign(params, {
    FunctionName:       config.name,
    Description:        config.description || '',
    Handler:            settings.entry || 'index.handler',
    MemorySize:         settings.memory || 128,
    Role:               role,
    Runtime:            settings.runtime || 'nodejs4.3',
    Timeout:            settings.timeout || 15,
    DeadLetterConfig:   deadLetterArn ? { TargetArn: deadLetterArn } : null,
    // VpcConfig: {},
    Environment:        settings.environment ? { Variables: settings.environment } : null,
  });
}

function createFunction(lambda, role, deadLetterArn, config, bufferCode, next) {
  let params = {};
  addConfigParams(params, role, deadLetterArn, config, config.configuration);
  console.log('config params', params);
  addCodeParams(params, bufferCode);
  params.Code = {
    ZipFile:        bufferCode,
  };
  lambda.createFunction(params, next);
}

function updateFunction(lambda, role, deadLetterArn, config, bufferCode, next) {
  let configParams = {};
  addConfigParams(configParams, role, deadLetterArn, config, config.configuration);
  console.log('config params', configParams);
  lambda.updateFunctionConfiguration(configParams, (err, data) => {
    if (err) return next(err);
    let codeParams = { FunctionName: configParams.FunctionName };
    addCodeParams(codeParams, bufferCode);
    codeParams.ZipFile = bufferCode;
    lambda.updateFunctionCode(codeParams, next);
  });
}

function getExistingFunction(lambda, FunctionName, next) {
  let params = { FunctionName };
  lambda.getFunctionConfiguration(params, (err, data) => next(null, err ? false : data));
}

exports.handler = createHandler((argv, done) => {
  global.log.info({ region: global.betty.aws.region }, 'update started');
  global.log.debug({ argv, config: global.config }, 'settings');
  let dist = path.join(process.cwd(), argv.main ? path.dirname(argv.main) : 'dist');
  if (argv.test) {
    createCodeBundle(dist, (err, bufferCode) => {
      if (err) {
        global.log.error({ err }, 'output code bundle failed');
        return done(err);
      }
      let bundleZip = path.join(dist, 'bundle.zip');
      fs.writeFileSync(bundleZip, bufferCode);
    });
    global.log.info({ destination: bundleZip }, 'test bundle created');
    return;
  }
  let lambda = new AWS.Lambda({ region: global.betty.aws.region });
  waterfall({
    role: (state, next) => {
      global.log.debug('starting role');
      roles.createLambdaRole(global.config.name, (err, data, justCreated) => {
        if (err) return next(err);
        global.log.debug({ role: data.Role }, 'got role');
        // HACK: if role was just created it can take a few seconds to become
        //       available to assign to the function.
        //       easier than using the aws api to poll.
        let delay = justCreated ? 5000 : 0;
        setTimeout(next, delay, null, data.Role.Arn);
      });
    },
    attachPolicies: function(state, next) {
      global.log.debug({ assets: global.config.assets, resources: Object.keys(global.config.resources) }, 'attaching policies');
      let inlineAssetPolicies = (global.config.assets || []).map(asset => {
        return (done) => {
          let policyName      = policies.nameFromAsset('asset', asset);
          let policyDocument  = policies.documentFromAsset(asset);
          global.log.trace({ name: policyName, document: policyDocument }, 'attaching inline policy');
          roles.attachInlinePolicy(global.config.name, policyName, policyDocument, done);
        };
      });
      let dependentResourcePolicies = Object.keys(global.config.resources || {}).map(resourceName => {
        return (done) => {
          let policyArn = policies.createManagedPolicyArnForResource(resourceName);
          global.log.trace({ arn: policyArn }, 'attaching managed policy');
          roles.attachManagedPolicy(global.config.name, policyArn, done);
        };
      });
      async.parallel([
        (done) => {
          global.log.trace('attaching default lambda policy');
          roles.attachAwsLambdaBasicExecutionRole(global.config.name, done);
        },
      ].concat(inlineAssetPolicies, dependentResourcePolicies), next);
    },
    publishManagedPolicy: function(state, next) {
      let policyDocument = policies.documentFromAssets(global.config.policy || []);
      global.log.debug({ document: policyDocument }, 'publishing managed policy for downstream');
      policies.createManagedPolicy(global.config.name, policyDocument, next);
    },
    // deadLetterArn: (state, next) => {
    //   if (!argv.config['dead-letter']) return next(null, null);
    //   if (true === argv.config['dead-letter']) {
    //     let parsed = arn.parse(state.role);
    //     next(null, arn.format(Object.assign(parsed, {
    //       service:      'sqs',
    //       region:       global.betty.aws.region,
    //       resource:     `lambda-dlq-${argv.config.name}`,
    //     })));
    //   }
    //   else if (typeof argv.config['dead-letter'] === 'string') {
    //     let parsed = arn.parse(state.role);
    //     next(null, arn.format(Object.assign(parsed, {
    //       service:      'sqs',
    //       region:       global.betty.aws.region,
    //       resource:     argv.config['dead-letter'],
    //     })));
    //   }
    //   else if (0 === argv.config['dead-letter'].indexOf('arn:')) {
    //     next(null, argv.config['dead-letter']);
    //   }
    //   else {
    //     next(new Error('invalid dead letter option'));
    //   }
    // },
    bundle: (state, next) => {
      global.log.debug('starting bundle');
      createCodeBundle(dist, (err, bufferCode) => {
        if (err) {
          global.log.error({ err }, 'code bundle failed');
          return next(err);
        }
        global.log.debug({ size: bufferCode.byteLength }, 'bundle created');
        next(null, bufferCode);
      });
    },
    exists: (state, next) => {
      global.log.debug('checking if function exists');
      getExistingFunction(lambda, global.config.name, next);
    },
    update: (state, next) => {
      if (state.exists) {
        global.log.info('updating existing function');
        updateFunction(lambda, state.role, null, global.config, state.bundle, next);
      }
      else {
        global.log.info('creating new function');
        createFunction(lambda, state.role, null, global.config, state.bundle, next);
      }
    },
  }, (err, state) => {
    if (err) {
      global.log.error(err);
      return done(err);
    }
    global.log.info('update complete');
    global.log.debug(Object.assign({}, state, { bundle: '[redacted]' }), 'final state');
    done(null);
  });
});
<commit_msg>precondition logging<commit_after>'use strict';

const fs            = require('fs');
const path          = require('path');
const streamBuffers = require('stream-buffers');
const AWS           = require('aws-sdk');
const archiver      = require('archiver');
const waterfall     = require('waterfall');
const async         = require('async');
const arn           = require('../../common/arn.js');
const roles         = require('../../common/roles.js');
const policies      = require('../../common/policies.js');
const createHandler = require('../lib/handler.js');

exports.command = 'update';
exports.desc    = 'Uploads the contents of dist to lambda as a new function version';
exports.builder = {
  test: {
    describe:       'Outputs bundled code to build directory and does not contact AWS',
    boolean:        true,
    default:        false,
  },
};

function createCodeBundle(dist, next) {
  let output = new streamBuffers.WritableStreamBuffer();
  let archive = archiver('zip', {
    store: true,
  });
  output.on('finish', () => next(null, output.getContents()));
  archive.on('error', next);
  archive.pipe(output);
  archive.directory(dist + '/', '.');
  archive.finalize();
}

function addCodeParams(params, bufferCode) {
  Object.assign(params, {
    Publish:        true,
  });
}

function addConfigParams(params, role, deadLetterArn, config, settings) {
  config = config || {};
  Object.assign(params, {
    FunctionName:       config.name,
    Description:        config.description || '',
    Handler:            settings.entry || 'index.handler',
    MemorySize:         settings.memory || 128,
    Role:               role,
    Runtime:            settings.runtime || 'nodejs4.3',
    Timeout:            settings.timeout || 15,
    DeadLetterConfig:   deadLetterArn ? { TargetArn: deadLetterArn } : null,
    // VpcConfig: {},
    Environment:        settings.environment ? { Variables: settings.environment } : null,
  });
}

function createFunction(lambda, role, deadLetterArn, config, bufferCode, next) {
  let params = {};
  addConfigParams(params, role, deadLetterArn, config, config.configuration);
  console.log('config params', params);
  addCodeParams(params, bufferCode);
  params.Code = {
    ZipFile:        bufferCode,
  };
  lambda.createFunction(params, next);
}

function updateFunction(lambda, role, deadLetterArn, config, bufferCode, next) {
  let configParams = {};
  addConfigParams(configParams, role, deadLetterArn, config, config.configuration);
  console.log('config params', configParams);
  lambda.updateFunctionConfiguration(configParams, (err, data) => {
    if (err) return next(err);
    let codeParams = { FunctionName: configParams.FunctionName };
    addCodeParams(codeParams, bufferCode);
    codeParams.ZipFile = bufferCode;
    lambda.updateFunctionCode(codeParams, next);
  });
}

function getExistingFunction(lambda, FunctionName, next) {
  let params = { FunctionName };
  lambda.getFunctionConfiguration(params, (err, data) => next(null, err ? false : data));
}

exports.handler = createHandler((argv, done) => {
  global.log.info({ region: global.betty.aws.region }, 'update started');
  global.log.debug({ argv, config: global.config }, 'settings');
  let dist = path.join(process.cwd(), argv.main ? path.dirname(argv.main) : 'dist');
  try {
    let filesInDist = fs.readdirSync(dist);
    if (0 === filesInDist.length) {
      let err = new Error('no files in dist');
      global.log.error({ err, dist }, 'dist not found');
      return done(err);
    }
  }
  catch (err) {
    global.log.warn({ err, dist }, 'error reading dist - did you forget to run betty build first?');
    return done(err);
  }
  if (argv.test) {
    createCodeBundle(dist, (err, bufferCode) => {
      if (err) {
        global.log.error({ err }, 'output code bundle failed');
        return done(err);
      }
      let bundleZip = path.join(dist, 'bundle.zip');
      fs.writeFileSync(bundleZip, bufferCode);
    });
    global.log.info({ destination: bundleZip }, 'test bundle created');
    return;
  }
  let lambda = new AWS.Lambda({ region: global.betty.aws.region });
  waterfall({
    role: (state, next) => {
      global.log.debug('starting role');
      roles.createLambdaRole(global.config.name, (err, data, justCreated) => {
        if (err) return next(err);
        global.log.debug({ role: data.Role }, 'got role');
        // HACK: if role was just created it can take a few seconds to become
        //       available to assign to the function.
        //       easier than using the aws api to poll.
        let delay = justCreated ? 5000 : 0;
        setTimeout(next, delay, null, data.Role.Arn);
      });
    },
    attachPolicies: function(state, next) {
      global.log.debug({ assets: global.config.assets, resources: Object.keys(global.config.resources) }, 'attaching policies');
      let inlineAssetPolicies = (global.config.assets || []).map(asset => {
        return (done) => {
          let policyName      = policies.nameFromAsset('asset', asset);
          let policyDocument  = policies.documentFromAsset(asset);
          global.log.trace({ name: policyName, document: policyDocument }, 'attaching inline policy');
          roles.attachInlinePolicy(global.config.name, policyName, policyDocument, done);
        };
      });
      let dependentResourcePolicies = Object.keys(global.config.resources || {}).map(resourceName => {
        return (done) => {
          let policyArn = policies.createManagedPolicyArnForResource(resourceName);
          global.log.trace({ arn: policyArn }, 'attaching managed policy');
          roles.attachManagedPolicy(global.config.name, policyArn, done);
        };
      });
      async.parallel([
        (done) => {
          global.log.trace('attaching default lambda policy');
          roles.attachAwsLambdaBasicExecutionRole(global.config.name, done);
        },
      ].concat(inlineAssetPolicies, dependentResourcePolicies), next);
    },
    publishManagedPolicy: function(state, next) {
      let policyDocument = policies.documentFromAssets(global.config.policy || []);
      global.log.debug({ document: policyDocument }, 'publishing managed policy for downstream');
      policies.createManagedPolicy(global.config.name, policyDocument, next);
    },
    // deadLetterArn: (state, next) => {
    //   if (!argv.config['dead-letter']) return next(null, null);
    //   if (true === argv.config['dead-letter']) {
    //     let parsed = arn.parse(state.role);
    //     next(null, arn.format(Object.assign(parsed, {
    //       service:      'sqs',
    //       region:       global.betty.aws.region,
    //       resource:     `lambda-dlq-${argv.config.name}`,
    //     })));
    //   }
    //   else if (typeof argv.config['dead-letter'] === 'string') {
    //     let parsed = arn.parse(state.role);
    //     next(null, arn.format(Object.assign(parsed, {
    //       service:      'sqs',
    //       region:       global.betty.aws.region,
    //       resource:     argv.config['dead-letter'],
    //     })));
    //   }
    //   else if (0 === argv.config['dead-letter'].indexOf('arn:')) {
    //     next(null, argv.config['dead-letter']);
    //   }
    //   else {
    //     next(new Error('invalid dead letter option'));
    //   }
    // },
    bundle: (state, next) => {
      global.log.debug('starting bundle');
      createCodeBundle(dist, (err, bufferCode) => {
        if (err) {
          global.log.error({ err }, 'code bundle failed');
          return next(err);
        }
        global.log.debug({ size: bufferCode.byteLength }, 'bundle created');
        next(null, bufferCode);
      });
    },
    exists: (state, next) => {
      global.log.debug('checking if function exists');
      getExistingFunction(lambda, global.config.name, next);
    },
    update: (state, next) => {
      if (state.exists) {
        global.log.info('updating existing function');
        updateFunction(lambda, state.role, null, global.config, state.bundle, next);
      }
      else {
        global.log.info('creating new function');
        createFunction(lambda, state.role, null, global.config, state.bundle, next);
      }
    },
  }, (err, state) => {
    if (err) {
      global.log.error(err);
      return done(err);
    }
    global.log.info('update complete');
    global.log.debug(Object.assign({}, state, { bundle: '[redacted]' }), 'final state');
    done(null);
  });
});
<|endoftext|>


<commit_before>import {CREATE_NETWORK_CLASS, CREATE_NETWORK_MODAL} from "./constants";
import { queryNetworkDatabase } from "./api/grnsight-api";
import { grnState } from "./grnstate";

export const createNetwork = function () {
    const createHTMLforForm = (sources) => {
        let result =  `

Create Network

            Network Source
            <select class=\'network-dropdown\' id=\'network-source\'>
                <option value=\'none\' selected=\'true\' disabled hidden>Select Network Source</option>
                    `;
        for (let source in sources) {
            result += `
                        <option value=\'${source}\'>${sources[source]}</option>
            `;
        }
        result += `</select>

Warning: changing network source will remove all current genes in network

            Select genes
            <input type=\'text\' id=\'network-search-bar\' name=\'network-search-bar\'></input>
            <button id=\'enter-search\' class=\'search-button\'>

            </button>

Added genes go here! Click on a gene to remove it

        <input type=\'submit\' id=\'submit-network\' value=\'Create Network\'></input>

        `;
        return result;
    };
    const createGeneButtons = function () {
        let result =  `

Added genes go below! Click on a gene to remove it.

        `
        for (let gene in grnState.customWorkbook.genes) {
            result += `

                        ${grnState.customWorkbook.genes[gene]}

                        (${gene})

            `
        }

        result += "

"
        return result
    };
    const displayCurrentGenes = function () {
        $("#selected-genes").remove();
        $("#selected-genes-container").append(createGeneButtons());
        for (let gene in grnState.customWorkbook.genes) {
            console.log(gene);
            $(`#${gene}`).on("click", (ev) => {
                ev.stopPropagation();
                $(`#${gene}`).remove();
                delete grnState.customWorkbook.genes[gene];
            });
        }
    };

    const addGene = function() {
        console.log("Begin Add Gene")
        let gene = `${$("#network-search-bar").val()}`;
        console.log(gene)
        // console.log("Gets here")
        // let source = grnState.customWorkbook.source
        // console.log("Gets here 2")
        $("#network-search-bar").val("")
        // console.log("Gets here")
        // console.log(`Gene: ${gene}`);
        // console.log(`Source: ${grnState.customWorkbook.sources[source].source}`);
        // console.log(`TimeStamp: ${grnState.customWorkbook.sources[source].timestamp}`);
        grnState.customWorkbook.genes[gene.toUpperCase()] = gene.toLowerCase()
        // get genes from database
            // queryNetworkDatabase({
            //     type:"NetworkGeneFromSource",
            //     info: {
            //         gene,
            //         source:grnState.customWorkbook.sources[source].source,
            //         timestamp:grnState.customWorkbook.sources[source].timestamp
            //     }
            // }).then(function (response) {
            //     let x = response
            //     console.log(x)
            // }).catch(function (error) {
            //     console.log(error.stack);
            //     console.log(error.name);
            //     console.log(error.message);
            // });
    };

    const updateGenes = function () {
        addGene();
        displayCurrentGenes();
    };

    const displayCreateNetworkModal = function () {
        $("#createNetworkFormContainer").remove();
        // $("#creatNetworkQuestions-container").append(createHTMLforForm(["1", "2", "3"]));
        grnState.customWorkbook = {
            genes : {},
            source : null
        };
    // get sources from database
        queryNetworkDatabase({type:"NetworkSource", info:null}).then(function (response) {
            $("#creatNetworkQuestions-container").append(createHTMLforForm(Object.keys(response.sources)));
            grnState.customWorkbook.sources = response.sources;
            console.log(grnState.customWorkbook)
        }).catch(function (error) {
            console.log(error.stack);
            console.log(error.name);
            console.log(error.message);
        });
        // $('#getNetworkGenesForm').on("submit", ev => {
        //     let gene = `${$("#network-search-bar").val()}`;
        //     let source = grnState.customWorkbook.source
        //     console.log("Gets here");
        //     ev.stopPropagation();
        //     queryNetworkDatabase({
        //         type:"NetworkGeneFromSource",
        //         info: {
        //             gene,
        //             source:grnState.customWorkbook.sources[source].source,
        //             timestamp:grnState.customWorkbook.sources[source].timestamp
        //         }
        //     }).then(function (response) {
        //         let x = response
        //         console.log(x)
        //     }).catch(function (error) {
        //         console.log(error.stack);
        //         console.log(error.name);
        //         console.log(error.message);
        //     });
        //     return false;
        // });
        $(CREATE_NETWORK_MODAL).modal("show");
    };

    const performNetworkCreation = function () {
        return function () {
            displayCreateNetworkModal();
        };
    };

    // $(CREATE_NETWORK_CLASS).one("click", performNetworkCreation());
    $("body").on("click", CREATE_NETWORK_CLASS, performNetworkCreation());
    $("#network-source").on("change", (() => {
        grnState.customWorkbook.source = $("#network-source").val();
        grnState.customWorkbook.genes = {};
        console.log("User changed source!")
        console.log(grnState.customWorkbook)
        ev.stopPropagation();
        displayCurrentGenes();
    })());
    $("#enter-search").on("click", ((ev) => {
        console.log("search button has been clicked")
        ev.stopPropagation();
        updateGenes();
    })(this));
    $("#network-search-bar").on("keydown", ((ev) => {
        if(ev.key === 'Enter') {
            console.log("search bar has been entered")
            ev.preventDefault();
            ev.stopPropagation();
            updateGenes();
        }
    })(this));
};
<commit_msg>fixing console error, hopefully<commit_after>import {CREATE_NETWORK_CLASS, CREATE_NETWORK_MODAL} from "./constants";
import { queryNetworkDatabase } from "./api/grnsight-api";
import { grnState } from "./grnstate";

export const createNetwork = function () {
    const createHTMLforForm = (sources) => {
        let result =  `

Create Network

            Network Source
            <select class=\'network-dropdown\' id=\'network-source\'>
                <option value=\'none\' selected=\'true\' disabled hidden>Select Network Source</option>
                    `;
        for (let source in sources) {
            result += `
                        <option value=\'${source}\'>${sources[source]}</option>
            `;
        }
        result += `</select>

Warning: changing network source will remove all current genes in network

            Select genes
            <input type=\'text\' id=\'network-search-bar\' name=\'network-search-bar\'></input>
            <button id=\'enter-search\' class=\'search-button\'>

            </button>

Added genes go here! Click on a gene to remove it

        <input type=\'submit\' id=\'submit-network\' value=\'Create Network\'></input>

        `;
        return result;
    };
    const createGeneButtons = function () {
        let result =  `

Added genes go below! Click on a gene to remove it.

        `
        for (let gene in grnState.customWorkbook.genes) {
            result += `

                        ${grnState.customWorkbook.genes[gene]}

                        (${gene})

            `
        }

        result += "

"
        return result
    };
    const displayCurrentGenes = function () {
        $("#selected-genes").remove();
        $("#selected-genes-container").append(createGeneButtons());
        for (let gene in grnState.customWorkbook.genes) {
            console.log(gene);
            $(`#${gene}`).on("click", (ev) => {
                ev.stopPropagation();
                $(`#${gene}`).remove();
                delete grnState.customWorkbook.genes[gene];
            });
        }
    };

    const addGene = function() {
        console.log("Begin Add Gene")
        let gene = `${$("#network-search-bar").val()}`;
        console.log(gene)
        // console.log("Gets here")
        // let source = grnState.customWorkbook.source
        // console.log("Gets here 2")
        $("#network-search-bar").val("")
        // console.log("Gets here")
        // console.log(`Gene: ${gene}`);
        // console.log(`Source: ${grnState.customWorkbook.sources[source].source}`);
        // console.log(`TimeStamp: ${grnState.customWorkbook.sources[source].timestamp}`);
        grnState.customWorkbook.genes[gene.toUpperCase()] = gene.toLowerCase()
        // get genes from database
            // queryNetworkDatabase({
            //     type:"NetworkGeneFromSource",
            //     info: {
            //         gene,
            //         source:grnState.customWorkbook.sources[source].source,
            //         timestamp:grnState.customWorkbook.sources[source].timestamp
            //     }
            // }).then(function (response) {
            //     let x = response
            //     console.log(x)
            // }).catch(function (error) {
            //     console.log(error.stack);
            //     console.log(error.name);
            //     console.log(error.message);
            // });
    };

    const updateGenes = function () {
        addGene();
        displayCurrentGenes();
    };

    const displayCreateNetworkModal = function () {
        $("#createNetworkFormContainer").remove();
        // $("#creatNetworkQuestions-container").append(createHTMLforForm(["1", "2", "3"]));
        grnState.customWorkbook = {
            genes : {},
            source : null
        };
    // get sources from database
        queryNetworkDatabase({type:"NetworkSource", info:null}).then(function (response) {
            $("#creatNetworkQuestions-container").append(createHTMLforForm(Object.keys(response.sources)));
            grnState.customWorkbook.sources = response.sources;
            console.log(grnState.customWorkbook)
        }).catch(function (error) {
            console.log(error.stack);
            console.log(error.name);
            console.log(error.message);
        });
        // $('#getNetworkGenesForm').on("submit", ev => {
        //     let gene = `${$("#network-search-bar").val()}`;
        //     let source = grnState.customWorkbook.source
        //     console.log("Gets here");
        //     ev.stopPropagation();
        //     queryNetworkDatabase({
        //         type:"NetworkGeneFromSource",
        //         info: {
        //             gene,
        //             source:grnState.customWorkbook.sources[source].source,
        //             timestamp:grnState.customWorkbook.sources[source].timestamp
        //         }
        //     }).then(function (response) {
        //         let x = response
        //         console.log(x)
        //     }).catch(function (error) {
        //         console.log(error.stack);
        //         console.log(error.name);
        //         console.log(error.message);
        //     });
        //     return false;
        // });
        $(CREATE_NETWORK_MODAL).modal("show");
    };

    const performNetworkCreation = function () {
        return function () {
            displayCreateNetworkModal();
        };
    };

    // $(CREATE_NETWORK_CLASS).one("click", performNetworkCreation());
    $("body").on("click", CREATE_NETWORK_CLASS, performNetworkCreation());
    $("#network-source").on("change", (() => {
        if (grnState.customWorkbook === undefined) grnState.customWorkbook = {source:null, genes: {}}
        grnState.customWorkbook.source = $("#network-source").val();
        grnState.customWorkbook.genes = {};
        console.log("User changed source!")
        console.log(grnState.customWorkbook)
        ev.stopPropagation();
        displayCurrentGenes();
    })());
    $("#enter-search").on("click", ((ev) => {
        console.log("search button has been clicked")
        ev.stopPropagation();
        updateGenes();
    })(this));
    $("#network-search-bar").on("keydown", ((ev) => {
        if(ev.key === 'Enter') {
            console.log("search bar has been entered")
            ev.preventDefault();
            ev.stopPropagation();
            updateGenes();
        }
    })(this));
};
<|endoftext|>


<commit_before>var _ = require('lodash');

var internals = {};

internals.defaults = {
    length: 6,
    letters: true,
    numbers: true
}

internals.letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
internals.numbers = '0123456789';

internals.localStorageKey = 'clientId';

var createClientId = function(options) {
    return
}

var ClientId = exports = module.exports = {

    install: function(options) {
        var clientId, existingClientId = this._store.get(internals.localStorageKey);

        if (!existingClientId) {
            clientId = this._store.set(internals.localStorageKey, this._generateClientId(options));
        }

        return clientId;
    },

    _store: {
        get: function(key) {
            return localStorage.getItem(key);
        },
        set: function(key, value) {
            localStorage.setItem(key, value);
            return value;
        }
    },

    _generateClientId: function(options) {
        options = _.defaults(options || {}, internals.defaults);

        var possible = (options.letters ? internals.letters : '') + (options.numbers ? internals.numbers : '');

        return _.times(options.length, function() {
            return possible.charAt(Math.floor(Math.random() * possible.length));
        }).join('');
    },

    defaults: internals.defaults

};

// exports = module.exports = internals.ClientId = function(options) {
//     options = _.defaults(options || {}, internals.defaults);

//     return _generateClientId(options);
// };

// internals.ClientId.create = function(options) {
//     return internals.ClientId(options);
// };

// internals.ClientId.install = function() {
//     if ( !localStorage.getItem(internals.localStorageKey)) {
//         localStorage.setItem(internals.localStorageKey, internals.ClientId.create());
//     }
// };

// internals.ClientId._store = {
//     get: function() {

//     },

//     set: function() {

//     }
// }

// internals.ClientId.defaults = internals.defaults;

// function _generateClientId(options) {
//     var possible = (options.letters ? internals.letters : '') + (options.numbers ? internals.numbers : '');

//     return _.times(options.length, function() {
//         return possible.charAt(Math.floor(Math.random() * possible.length));
//     }).join('');
// };<commit_msg>Rewrite to fit Hapi style<commit_after>var _ = require('lodash');

var internals = {};

internals.defaults = {
    length: 6,
    letters: true,
    numbers: true
}

internals.letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
internals.numbers = '0123456789';

internals.localStorageKey = 'clientId';

exports = module.exports = internals.ClientId = {};

internals.ClientId.install = function(options) {
    var clientId, existingClientId = this._store.get(internals.localStorageKey);

    if (!existingClientId) {
        clientId = this._store.set(internals.localStorageKey, this._generateClientId(options));
    }

    return clientId;
};

internals.ClientId._store = {
    get: function(key) {
        return localStorage.getItem(key);
    },
    set: function(key, value) {
        localStorage.setItem(key, value);
        return value;
    }
};

internals.ClientId._generateClientId = function(options) {
    options = _.defaults(options || {}, internals.defaults);

    var possible = (options.letters ? internals.letters : '') + (options.numbers ? internals.numbers : '');

    return _.times(options.length, function() {
        return possible.charAt(Math.floor(Math.random() * possible.length));
    }).join('');
};

internals.ClientId.defaults = internals.defaults;<|endoftext|>


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

  function Even(config) {
    this.config = config;
  }

  Even.prototype.setup = function() {
    var leancloud = this.config.leancloud;

    this.navbar();
    this.responsiveTable();

    if (this.config.toc) {
      this.scrollToc();
      this.tocFollow();
    }
    if (this.config.fancybox) {
      this.fancybox();
    }
    if (leancloud.app_id && leancloud.app_key) {
      this.recordReadings();
    }
    if (this.config.pjax) {
      this.pjax();
    }
    if(this.config.latex) {
      this.renderLaTeX();
    }
    this.backToTop();
  };

  Even.prototype.navbar = function () {
    var $nav = $('#mobile-navbar');
    var $navIcon = $('.mobile-navbar-icon');

    var slideout = new Slideout({
      'panel': document.getElementById('mobile-panel'),
      'menu': document.getElementById('mobile-menu'),
      'padding': 180,
      'tolerance': 70
    });
    slideout.disableTouch();

    $navIcon.click(function () {
      slideout.toggle();
    });

    slideout.on('beforeopen', function () {
      $nav.addClass('fixed-open');
      $navIcon.addClass('icon-click').removeClass('icon-out');
    });

    slideout.on('beforeclose', function () {
      $nav.removeClass('fixed-open');
      $navIcon.addClass('icon-out').removeClass('icon-click');
    });

    $('#mobile-panel').on('touchend', function () {
      slideout.isOpen() && $navIcon.click();
    });
  };

  Even.prototype.responsiveTable = function () {
    var tables = $('.post-content > table')
    tables.wrap('
')
  };

  Even.prototype.scrollToc = function () {
    var SPACING = 20;
    var $toc = $('.post-toc');
    var $footer = $('.post-footer');

    if ($toc.length) {
      var minScrollTop = $toc.offset().top - SPACING;
      var maxScrollTop = $footer.offset().top - $toc.height() - SPACING;

      var tocState = {
        start: {
          'position': 'absolute',
          'top': minScrollTop
        },
        process: {
          'position': 'fixed',
          'top': SPACING
        },
        end: {
          'position': 'absolute',
          'top': maxScrollTop
        }
      }

      $(window).scroll(function () {
        var scrollTop = $(window).scrollTop();

        if (scrollTop < minScrollTop) {
          $toc.css(tocState.start);
        } else if (scrollTop > maxScrollTop) {
          $toc.css(tocState.end);
        } else {
          $toc.css(tocState.process);
        }
      })
    }
  };

  Even.prototype.tocFollow = function () {
    var HEADERFIX = 30;
    var $toclink = $('.toc-link'),
      $headerlink = $('.headerlink');

    $(window).scroll(function () {
      var headerlinkTop = $.map($headerlink, function (link) {
        return $(window).scrollTop() + $(link).offset().top;
      });
      var scrollTop = $(window).scrollTop();

      for (var i = 0; i < $toclink.length; i++) {
        var isLastOne = i + 1 === $toclink.length,
          currentTop = headerlinkTop[i] - HEADERFIX,
          nextTop = isLastOne ? Infinity : headerlinkTop[i + 1] - HEADERFIX;

        if (currentTop < scrollTop && scrollTop <= nextTop) {
          $($toclink[i]).addClass('active');
        } else {
          $($toclink[i]).removeClass('active');
        }
      }
    });
  };

  Even.prototype.fancybox = function () {
    if ($.fancybox) {
      $('.post').each(function () {
        $(this).find('img').each(function () {
          var href = 'href="' + this.src + '"';
          var title = 'title="' + this.alt + '"';
          $(this).wrap('');
        });
      });

      $('.fancybox').fancybox({
        openEffect: 'elastic',
        closeEffect: 'elastic'
      });
    }
  };

  Even.prototype.recordReadings = function () {
    if (typeof AV !== 'object') return;

    var $visits = $('.post-visits');
    var Counter = AV.Object.extend('Counter');
    if ($visits.length === 1) {
      addCounter(Counter);
    } else {
      showTime(Counter);
    }

    function updateVisits(dom, time) {
      var readText = dom.text().replace(/(\d+)/i, time)
      dom.text(readText);
    }

    function addCounter(Counter) {
      var query = new AV.Query(Counter);

      var url = $visits.data('url').trim();
      var title = $visits.data('title').trim();

      query.equalTo('url', url);
      query.find().then(function (results) {
        if (results.length > 0) {
          var counter = results[0];
          counter.save(null, {
            fetchWhenSave: true
          }).then(function (counter) {
            counter.increment('time', 1);
            return counter.save();
          }).then(function (counter) {
            updateVisits($visits, counter.get('time'));
          });
        } else {
          var newcounter = new Counter();
          newcounter.set('title', title);
          newcounter.set('url', url);
          newcounter.set('time', 1);

          var acl = new AV.ACL();
          acl.setWriteAccess('*', true)
          acl.setReadAccess('*', true)
          newcounter.setACL(acl)

          newcounter.save().then(function () {
            updateVisits($visits, newcounter.get('time'));
          });
        }
      }, function (error) {
        // eslint-disable-next-line
        console.log('Error:' + error.code + ' ' + error.message);
      });
    }

    function showTime(Counter) {
      $visits.each(function () {
        var $this = $(this);
        var query = new AV.Query(Counter);
        var url = $this.data('url').trim();

        query.equalTo('url', url);
        query.find().then(function (results) {
          if (results.length === 0) {
            updateVisits($this, 0);
          } else {
            var counter = results[0];
            updateVisits($this, counter.get('time'));
          }
        }, function (error) {
          // eslint-disable-next-line
          console.log('Error:' + error.code + ' ' + error.message);
        });
      })
    }
  };

  Even.prototype.pjax = function () {
    if (location.hostname === 'localhost' || this.hasPjax) return;
    this.hasPjax = true;
    this._fancybox = $.fancybox;
    this._fancyboxProto = $.prototype.fancybox;

    var that = this;
    $(document).pjax('a', 'body', { fragment: 'body' });
    $(document).on('pjax:send', function () {
      NProgress.start();
      $('body').addClass('hide-top');
    });
    $(document).on('pjax:complete', function () {
      NProgress.done();
      $('body').removeClass('hide-top');
      $.fancybox = that._fancybox;
      $.prototype.fancybox = that._fancyboxProto;
      that.setup();
    });
  };

  Even.prototype.backToTop = function () {
    var $backToTop = $('#back-to-top');

    $(window).scroll(function () {
      if ($(window).scrollTop() > 100) {
        $backToTop.fadeIn(1000);
      } else {
        $backToTop.fadeOut(1000);
      }
    });

    $backToTop.click(function () {
      $('body,html').animate({ scrollTop: 0 });
    });
  };

  Even.prototype.renderLaTeX = function () {
    var loopID = setInterval(function () {
      if(window.MathJax) {
        var jax = window.MathJax;
        jax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'], ['\\(', '\\)']] }});
        jax.Hub.Queue(['Typeset', jax.Hub, $(document.body)[0]]);
        clearInterval(loopID);
      }
    }, 500);
  }

  var config = window.config;
  var even = new Even(config);
  even.setup();
}(window))
<commit_msg>update: enhanced readability<commit_after>(function (window) {
  'use strict';

  function Even(config) {
    this.config = config;
  }

  Even.prototype.setup = function() {
    var leancloud = this.config.leancloud;

    this.navbar();
    this.responsiveTable();

    if (this.config.toc) {
      this.scrollToc();
      this.tocFollow();
    }
    if (this.config.fancybox) {
      this.fancybox();
    }
    if (leancloud.app_id && leancloud.app_key) {
      this.recordReadings();
    }
    if (this.config.pjax) {
      this.pjax();
    }
    if(this.config.latex) {
      this.renderLaTeX();
    }
    this.backToTop();
  };

  Even.prototype.navbar = function () {
    var $nav = $('#mobile-navbar');
    var $navIcon = $('.mobile-navbar-icon');

    var slideout = new Slideout({
      'panel': document.getElementById('mobile-panel'),
      'menu': document.getElementById('mobile-menu'),
      'padding': 180,
      'tolerance': 70
    });
    slideout.disableTouch();

    $navIcon.click(function () {
      slideout.toggle();
    });

    slideout.on('beforeopen', function () {
      $nav.addClass('fixed-open');
      $navIcon.addClass('icon-click').removeClass('icon-out');
    });

    slideout.on('beforeclose', function () {
      $nav.removeClass('fixed-open');
      $navIcon.addClass('icon-out').removeClass('icon-click');
    });

    $('#mobile-panel').on('touchend', function () {
      slideout.isOpen() && $navIcon.click();
    });
  };

  Even.prototype.responsiveTable = function () {
    var tables = $('.post-content > table')
    tables.wrap('
')
  };

  Even.prototype.scrollToc = function () {
    var SPACING = 20;
    var $toc = $('.post-toc');
    var $footer = $('.post-footer');

    if ($toc.length) {
      var minScrollTop = $toc.offset().top - SPACING;
      var maxScrollTop = $footer.offset().top - $toc.height() - SPACING;

      var tocState = {
        start: {
          'position': 'absolute',
          'top': minScrollTop
        },
        process: {
          'position': 'fixed',
          'top': SPACING
        },
        end: {
          'position': 'absolute',
          'top': maxScrollTop
        }
      }

      $(window).scroll(function () {
        var scrollTop = $(window).scrollTop();

        if (scrollTop < minScrollTop) {
          $toc.css(tocState.start);
        } else if (scrollTop > maxScrollTop) {
          $toc.css(tocState.end);
        } else {
          $toc.css(tocState.process);
        }
      })
    }
  };

  Even.prototype.tocFollow = function () {
    var HEADERFIX = 30;
    var $toclink = $('.toc-link'),
      $headerlink = $('.headerlink');

    $(window).scroll(function () {
      var scrollTop = $(window).scrollTop();
      var headerlinkTop = $.map($headerlink, function (link) {
        return scrollTop + $(link).offset().top;
      });

      for (var i = 0; i < $toclink.length; i++) {
        var isLastOne = i + 1 === $toclink.length,
          currentTop = headerlinkTop[i] - HEADERFIX,
          nextTop = isLastOne ? Infinity : headerlinkTop[i + 1] - HEADERFIX;

        if (currentTop < scrollTop && scrollTop <= nextTop) {
          $($toclink[i]).addClass('active');
        } else {
          $($toclink[i]).removeClass('active');
        }
      }
    });
  };

  Even.prototype.fancybox = function () {
    if ($.fancybox) {
      $('.post').each(function () {
        $(this).find('img').each(function () {
          var href = 'href="' + this.src + '"';
          var title = 'title="' + this.alt + '"';
          $(this).wrap('');
        });
      });

      $('.fancybox').fancybox({
        openEffect: 'elastic',
        closeEffect: 'elastic'
      });
    }
  };

  Even.prototype.recordReadings = function () {
    if (typeof AV !== 'object') return;

    var $visits = $('.post-visits');
    var Counter = AV.Object.extend('Counter');
    if ($visits.length === 1) {
      addCounter(Counter);
    } else {
      showTime(Counter);
    }

    function updateVisits(dom, time) {
      var readText = dom.text().replace(/(\d+)/i, time)
      dom.text(readText);
    }

    function addCounter(Counter) {
      var query = new AV.Query(Counter);

      var url = $visits.data('url').trim();
      var title = $visits.data('title').trim();

      query.equalTo('url', url);
      query.find().then(function (results) {
        if (results.length > 0) {
          var counter = results[0];
          counter.save(null, {
            fetchWhenSave: true
          }).then(function (counter) {
            counter.increment('time', 1);
            return counter.save();
          }).then(function (counter) {
            updateVisits($visits, counter.get('time'));
          });
        } else {
          var newcounter = new Counter();
          newcounter.set('title', title);
          newcounter.set('url', url);
          newcounter.set('time', 1);

          var acl = new AV.ACL();
          acl.setWriteAccess('*', true)
          acl.setReadAccess('*', true)
          newcounter.setACL(acl)

          newcounter.save().then(function () {
            updateVisits($visits, newcounter.get('time'));
          });
        }
      }, function (error) {
        // eslint-disable-next-line
        console.log('Error:' + error.code + ' ' + error.message);
      });
    }

    function showTime(Counter) {
      $visits.each(function () {
        var $this = $(this);
        var query = new AV.Query(Counter);
        var url = $this.data('url').trim();

        query.equalTo('url', url);
        query.find().then(function (results) {
          if (results.length === 0) {
            updateVisits($this, 0);
          } else {
            var counter = results[0];
            updateVisits($this, counter.get('time'));
          }
        }, function (error) {
          // eslint-disable-next-line
          console.log('Error:' + error.code + ' ' + error.message);
        });
      })
    }
  };

  Even.prototype.pjax = function () {
    if (location.hostname === 'localhost' || this.hasPjax) return;
    this.hasPjax = true;
    this._fancybox = $.fancybox;
    this._fancyboxProto = $.prototype.fancybox;

    var that = this;
    $(document).pjax('a', 'body', { fragment: 'body' });
    $(document).on('pjax:send', function () {
      NProgress.start();
      $('body').addClass('hide-top');
    });
    $(document).on('pjax:complete', function () {
      NProgress.done();
      $('body').removeClass('hide-top');
      $.fancybox = that._fancybox;
      $.prototype.fancybox = that._fancyboxProto;
      that.setup();
    });
  };

  Even.prototype.backToTop = function () {
    var $backToTop = $('#back-to-top');

    $(window).scroll(function () {
      if ($(window).scrollTop() > 100) {
        $backToTop.fadeIn(1000);
      } else {
        $backToTop.fadeOut(1000);
      }
    });

    $backToTop.click(function () {
      $('body,html').animate({ scrollTop: 0 });
    });
  };

  Even.prototype.renderLaTeX = function () {
    var loopID = setInterval(function () {
      if(window.MathJax) {
        var jax = window.MathJax;
        jax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'], ['\\(', '\\)']] }});
        jax.Hub.Queue(['Typeset', jax.Hub, $(document.body)[0]]);
        clearInterval(loopID);
      }
    }, 500);
  }

  var config = window.config;
  var even = new Even(config);
  even.setup();
}(window))
<|endoftext|>


<commit_before>var duplicate = false;
jQuery( document ).ready( function()
{
	showHideUserGroup();

	checkValueIsExist( "name", "validateProgramStage.action", {id:getFieldValue('programId'), programStageId:getFieldValue('id')});

	jQuery("#availableList").dhisAjaxSelect({
		source: "../dhis-web-commons-ajax-json/getDataElements.action?domain=patient",
		iterator: "dataElements",
		connectedTo: 'selectedDataElementsValidator',
		handler: function(item) {
			var option = jQuery("<option />");
			option.text( item.name );
			option.attr( "value", item.id );

			if( item.optionSet == "true"){
				option.attr( "valuetype", "optionset" );
			}
			else{
				option.attr( "valuetype", item.valueType );
			}

			var flag = false;
			jQuery("#selectedList").find("tr").each( function( k, selectedItem ){
				if(selectedItem.id == item.id )
				{
					flag = true;
					return;
				}
			});

			if(!flag) return option;
		}
	});
});
<commit_msg>Fix bug where non-existing function was being called<commit_after>var duplicate = false;
jQuery( document ).ready( function()
{
	checkValueIsExist( "name", "validateProgramStage.action", {id:getFieldValue('programId'), programStageId:getFieldValue('id')});

	jQuery("#availableList").dhisAjaxSelect({
		source: "../dhis-web-commons-ajax-json/getDataElements.action?domain=patient",
		iterator: "dataElements",
		connectedTo: 'selectedDataElementsValidator',
		handler: function(item) {
			var option = jQuery("<option />");
			option.text( item.name );
			option.attr( "value", item.id );

			if( item.optionSet == "true"){
				option.attr( "valuetype", "optionset" );
			}
			else{
				option.attr( "valuetype", item.valueType );
			}

			var flag = false;
			jQuery("#selectedList").find("tr").each( function( k, selectedItem ){
				if(selectedItem.id == item.id )
				{
					flag = true;
					return;
				}
			});

			if(!flag) return option;
		}
	});
});
<|endoftext|>


<commit_before>function load_songs(textarea) {
    var encoded_uri = textarea.value;
    var decoded = decodeURIComponent(encoded_uri);
    var without_protocol = decoded.replace("irealb://", "");
    var unsplitted = without_protocol.split("==0=0===");
    for(i in unsplitted) {
        song = unsplitted[i].split("=");
        title = song[0];
        author = song[1];
        localStorage[title + " (" + author + ")"] = unsplitted[i]
    }
}
function swap(splitted, i, j) {
    tmp = splitted[i];
    splitted[i] = splitted[j];
    splitted[j] = tmp;
}
function mirror_swap(str, start, size) {
    var splitted = str.split('');
    var count = Math.floor(size / 2);
    for(var i = 0; i < count; i++) {
        swap(splitted, start + i, size + start - i);
    }
    return splitted.join("");
}
function unwarble(warbled) {
    var unwarbled = warbled.replace('1r34LbKcu7', '');
    for(var i = 0; i + 51 < unwarbled.length; i += 50) {
        unwarbled = mirror_swap(mirror_swap(mirror_swap(unwarbled, i + 10, 29), i + 5, 39), i, 49)
    }
    return unwarbled.replace(/XyQ/g, "   ").replace(/Kcl/g, "| x").replace(/LZ/g, "|");
}
function get_sheet(unwarbled) {
    unwarbled = unwarbled.replace(/\*([ABC])/g, "$1");
    unwarbled = unwarbled.replace(/\[/g, " ");
    unwarbled = unwarbled.replace(/T(.)(.)/g, "$1$1");
    unwarbled = unwarbled.replace(/\^/g, "Δ");
    var splitted = unwarbled.split('');
    var open_div = "
";
    var close_div = "
";
    var open_span = "";
    var close_span = "";
    var out = open_div + open_span;
    var bars = 0;
    for(i = 0; i < splitted.length; i++) {
        var c = splitted[i];
        var add = "";
        if(c == "|") {
            c = close_span;
            bars += 1;
            if(bars < 4)
            {
                c += open_span
            }
        }
        else { if(c == "x") { c = "%"; } }
        if(bars == 4 || c == '}' || c == ']') {
            bars = 0;
            add = close_div + open_div + open_span;
        }
        out += c + add;
    }
    return out + close_span + close_div;
}
function line_to_mma_chords(line) {
    var chords = line.split(" ");
    if(chords.length == 2) {
        chords = [chords[0], "/", chords[1]];
    }
    return chords.join(" ");
}
function play_mma(mma) {
  var worker = new Worker("//rawgit.com/yazgoo/pypyjs-mma/master/worker.js")
  worker.postMessage([mma]);
  console.log('Message posted to worker');
  worker.onmessage = function(e) {
    console.log('Message received from worker');
    console.log(btoa(e.data));
    data = e.data
      console.log("playing " + data);
    play(data);
  }
}
function play_song(unwarbled) {
    var previous = "";
    unwarbled = unwarbled.replace(/T../, '?Groove Rumba\n')
        .replace(/\{/g, "\n?Repeat\n").replace(/}/g, "\n?RepeatEnd\n")
        .replace(/\*./g, "").replace(/N1/g, "\n?RepeatEnding\\2\n").replace("][", "")
        .replace("[", "\n")
        .replace(/N2/g, "").replace("Z", "").replace(/s/g, " ").replace(/,/g, " ")
        .replace(/-/g, "m").replace(/\^/g, "M").replace(/h/g, "dim")
        .replace(/\|/g, "\n").replace(/\]\[/g, "\n").replace(/\[/, "\n")
        .replace(/l/g, "\n")
    splitted = unwarbled.split("\n");
    var previous = "";
    k = 0;
    for(var i = 0; i < splitted.length; i++) {
        var line = splitted[i];
        if(line.length == 0 || line[0] == '?') previous += line.replace(/\?/g, "")
        else {
            previous += "" + k + " " + line_to_mma_chords(line);
            k += 1;
        }
        previous += "\n";
    }
    console.log(previous);
    play_mma(previous);
}
function show_song(title) {
    var song = localStorage[title];
    localStorage["last_song"] = song;
    var splitted = song.split("=");
    var title = splitted[0];
    var author = splitted[1];
    var unwarbled = unwarble(splitted[6]);
    set_content(""+title+" ("+author+")"
            + "<input type=button value='>' onclick=\"play_song('"+unwarbled+"')\"/>

"
            + get_sheet(unwarbled));
}
function show_songs_list(div) {
    div.innerHTML = "";
    for(var i = 0; i < 100;/*localStorage.length*/ i++) {
        var title = localStorage.key(i);
        div.innerHTML += "" + title  + "
";
    }
}
function set_content(str) {
    var content = document.getElementById("content");
    content.innerHTML = str;
}
function show_imports() {
    set_content("<input type=text onchange='load_songs(this)'/>");
}
function show_about() {
    set_content('Mooche is free software (as in freedom).
'
            +'This means it guarantees 4 fundamentals rights:
'
            +'
'
            +'
Freedom 0: The freedom to run the program for any purpose.
'
            +'
Freedom 1: The freedom to study how the program works, and change it to make it do what you wish.
'
            +'
Freedom 2: The freedom to redistribute and make copies so you can help your neighbor.
'
            +'
Freedom 3: The freedom to improve the program, and release your improvements (and modified versions in general) to the public, so that the whole community benefits.
'
            +'
'
            +'')
}
function show_songs() {
    show_songs_list(document.getElementById('content'));
}
function show_songs_or_last_song() {
    if(localStorage["last_song"] != null) {
        show_song("last_song");
    }
    else {
        show_songs();
    }
}

<commit_msg>using swing as default groove<commit_after>function load_songs(textarea) {
    var encoded_uri = textarea.value;
    var decoded = decodeURIComponent(encoded_uri);
    var without_protocol = decoded.replace("irealb://", "");
    var unsplitted = without_protocol.split("==0=0===");
    for(i in unsplitted) {
        song = unsplitted[i].split("=");
        title = song[0];
        author = song[1];
        localStorage[title + " (" + author + ")"] = unsplitted[i]
    }
}
function swap(splitted, i, j) {
    tmp = splitted[i];
    splitted[i] = splitted[j];
    splitted[j] = tmp;
}
function mirror_swap(str, start, size) {
    var splitted = str.split('');
    var count = Math.floor(size / 2);
    for(var i = 0; i < count; i++) {
        swap(splitted, start + i, size + start - i);
    }
    return splitted.join("");
}
function unwarble(warbled) {
    var unwarbled = warbled.replace('1r34LbKcu7', '');
    for(var i = 0; i + 51 < unwarbled.length; i += 50) {
        unwarbled = mirror_swap(mirror_swap(mirror_swap(unwarbled, i + 10, 29), i + 5, 39), i, 49)
    }
    return unwarbled.replace(/XyQ/g, "   ").replace(/Kcl/g, "| x").replace(/LZ/g, "|");
}
function get_sheet(unwarbled) {
    unwarbled = unwarbled.replace(/\*([ABC])/g, "$1");
    unwarbled = unwarbled.replace(/\[/g, " ");
    unwarbled = unwarbled.replace(/T(.)(.)/g, "$1$1");
    unwarbled = unwarbled.replace(/\^/g, "Δ");
    var splitted = unwarbled.split('');
    var open_div = "
";
    var close_div = "
";
    var open_span = "";
    var close_span = "";
    var out = open_div + open_span;
    var bars = 0;
    for(i = 0; i < splitted.length; i++) {
        var c = splitted[i];
        var add = "";
        if(c == "|") {
            c = close_span;
            bars += 1;
            if(bars < 4)
            {
                c += open_span
            }
        }
        else { if(c == "x") { c = "%"; } }
        if(bars == 4 || c == '}' || c == ']') {
            bars = 0;
            add = close_div + open_div + open_span;
        }
        out += c + add;
    }
    return out + close_span + close_div;
}
function line_to_mma_chords(line) {
    var chords = line.split(" ");
    if(chords.length == 2) {
        chords = [chords[0], "/", chords[1]];
    }
    return chords.join(" ");
}
function play_mma(mma) {
  var worker = new Worker("//rawgit.com/yazgoo/pypyjs-mma/master/worker.js")
  worker.postMessage([mma]);
  console.log('Message posted to worker');
  worker.onmessage = function(e) {
    console.log('Message received from worker');
    console.log(btoa(e.data));
    data = e.data
      console.log("playing " + data);
    play(data);
  }
}
function play_song(unwarbled) {
    var previous = "";
    unwarbled = unwarbled.replace(/T../, '?Groove Swing\n')
        .replace(/\{/g, "\n?Repeat\n").replace(/}/g, "\n?RepeatEnd\n")
        .replace(/\*./g, "").replace(/N1/g, "\n?RepeatEnding\\2\n").replace("][", "")
        .replace("[", "\n")
        .replace(/N2/g, "").replace("Z", "").replace(/s/g, " ").replace(/,/g, " ")
        .replace(/-/g, "m").replace(/\^/g, "M").replace(/h/g, "dim")
        .replace(/\|/g, "\n").replace(/\]\[/g, "\n").replace(/\[/, "\n")
        .replace(/l/g, "\n")
    splitted = unwarbled.split("\n");
    var previous = "";
    k = 0;
    for(var i = 0; i < splitted.length; i++) {
        var line = splitted[i];
        if(line.length == 0 || line[0] == '?') previous += line.replace(/\?/g, "")
        else {
            previous += "" + k + " " + line_to_mma_chords(line);
            k += 1;
        }
        previous += "\n";
    }
    console.log(previous);
    play_mma(previous);
}
function show_song(title) {
    var song = localStorage[title];
    localStorage["last_song"] = song;
    var splitted = song.split("=");
    var title = splitted[0];
    var author = splitted[1];
    var unwarbled = unwarble(splitted[6]);
    set_content(""+title+" ("+author+")"
            + "<input type=button value='>' onclick=\"play_song('"+unwarbled+"')\"/>

"
            + get_sheet(unwarbled));
}
function show_songs_list(div) {
    div.innerHTML = "";
    for(var i = 0; i < 100;/*localStorage.length*/ i++) {
        var title = localStorage.key(i);
        div.innerHTML += "" + title  + "
";
    }
}
function set_content(str) {
    var content = document.getElementById("content");
    content.innerHTML = str;
}
function show_imports() {
    set_content("<input type=text onchange='load_songs(this)'/>");
}
function show_about() {
    set_content('Mooche is free software (as in freedom).
'
            +'This means it guarantees 4 fundamentals rights:
'
            +'
'
            +'
Freedom 0: The freedom to run the program for any purpose.
'
            +'
Freedom 1: The freedom to study how the program works, and change it to make it do what you wish.
'
            +'
Freedom 2: The freedom to redistribute and make copies so you can help your neighbor.
'
            +'
Freedom 3: The freedom to improve the program, and release your improvements (and modified versions in general) to the public, so that the whole community benefits.
'
            +'
'
            +'')
}
function show_songs() {
    show_songs_list(document.getElementById('content'));
}
function show_songs_or_last_song() {
    if(localStorage["last_song"] != null) {
        show_song("last_song");
    }
    else {
        show_songs();
    }
}

<|endoftext|>


<commit_before>const { remote } = require('electron');
const fs = require('fs');
const path = require('path');
const execa = require('execa');
const Config = require('./Config');

const { competition, resultFileDirectory } = remote.getCurrentWindow();

class MatchRunner {
  constructor() {
    this.runningProcesses = [];
  }

  runMatch({
    isBatch = false,
    switchedSides = false,
    liveEngineStdout = false,
  } = {}) {
    return new Promise((resolve, reject) => {
      const config = switchedSides ? this.configSwitched : this.config;

      const resultFilePath = path.resolve(resultFileDirectory, `${competition.id}-${isBatch ? 'batch' : 'single'}-resultfile.json`);
      config.wrapper.resultFile = resultFilePath;

      const proc = execa('java', ['-jar', competition.paths.matchWrapper, JSON.stringify(config)]);

      proc.then((result) => {
          const resultFile = JSON.parse(fs.readFileSync(resultFilePath).toString());

          resultFile.game = JSON.parse(resultFile.game);
          resultFile.details = JSON.parse(resultFile.details);

          const output = {
            resultFile,
            stdout: result.stdout,
          };

          if (competition.hasSeed) {
            output.seed = result.stdout.match(/RANDOM SEED IS: ([0-9a-f-]+)/)[1];
          }

          resolve(output);
        })
        .catch((error) => {
          reject({
            error: new Error(`The match wrapper exited with ${(error.code !== null ? `code ${error.code}` : `signal ${error.signal}`)}`),
            stdout: error.stdout
          });
        })
        .then(() => this.runningProcesses.splice(this.runningProcesses.indexOf(proc), 1));

      this.runningProcesses.push(proc);

      if (liveEngineStdout) {
        const $engineTab = $('.log.segment[data-tab="engine-stdout"]');
        const $engineDimmer = $engineTab.find('.dimmer');
        const $engineStdout = $engineTab.find('pre');

        proc.stdout.on('data', (data) => {
          data = data.toString().trim();

          if (data !== '') {
            $engineDimmer.removeClass('active');

            const text = $engineStdout.text();
            $engineStdout.text((text + '\n' + data).trim());

            $engineStdout.scrollTop($engineStdout[0].scrollHeight);
          }
        });
      }

      proc.stderr.on('data', (data) => {
        data = data.toString().trim();
        if (data !== '') console.log(data);
      });
    });
  }

  updateConfig() {
    const config = Config.getConfig(true);

    config.wrapper.debug = false;
    config.match.engine.command = ['java', '-jar', competition.paths.engine];

    this.config = config;

    this.configSwitched = JSON.parse(JSON.stringify(config));
    this.configSwitched.match.bots = this.configSwitched.match.bots.reverse();
  }

  exit() {
    this.runningProcesses.forEach(p => p.kill());
  }
}

module.exports = MatchRunner;
<commit_msg>Reformatting<commit_after>const { remote } = require('electron');
const fs = require('fs');
const path = require('path');
const execa = require('execa');
const Config = require('./Config');

const { competition, resultFileDirectory } = remote.getCurrentWindow();

class MatchRunner {
  constructor() {
    this.runningProcesses = [];
  }

  runMatch({
    isBatch = false,
    switchedSides = false,
    liveEngineStdout = false,
  } = {}) {
    return new Promise((resolve, reject) => {
      const config = switchedSides ? this.configSwitched : this.config;

      const resultFilePath = path.resolve(resultFileDirectory, `${competition.id}-${isBatch ? 'batch' : 'single'}-resultfile.json`);
      config.wrapper.resultFile = resultFilePath;

      const proc = execa('java', ['-jar', competition.paths.matchWrapper, JSON.stringify(config)]);

      proc.then((result) => {
        const resultFile = JSON.parse(fs.readFileSync(resultFilePath).toString());

        resultFile.game = JSON.parse(resultFile.game);
        resultFile.details = JSON.parse(resultFile.details);

        const output = {
          resultFile,
          stdout: result.stdout,
        };

        if (competition.hasSeed) {
          output.seed = result.stdout.match(/RANDOM SEED IS: ([0-9a-f-]+)/)[1];
        }

        resolve(output);
      })
      .catch((error) => {
        reject({
          error: new Error(`The match wrapper exited with ${(error.code !== null ? `code ${error.code}` : `signal ${error.signal}`)}`),
          stdout: error.stdout
        });
      })
      .then(() => this.runningProcesses.splice(this.runningProcesses.indexOf(proc), 1));

      this.runningProcesses.push(proc);

      if (liveEngineStdout) {
        const $engineTab = $('.log.segment[data-tab="engine-stdout"]');
        const $engineDimmer = $engineTab.find('.dimmer');
        const $engineStdout = $engineTab.find('pre');

        proc.stdout.on('data', (data) => {
          data = data.toString().trim();

          if (data !== '') {
            $engineDimmer.removeClass('active');

            const text = $engineStdout.text();
            $engineStdout.text((text + '\n' + data).trim());

            $engineStdout.scrollTop($engineStdout[0].scrollHeight);
          }
        });
      }

      proc.stderr.on('data', (data) => {
        data = data.toString().trim();
        if (data !== '') console.log(data);
      });
    });
  }

  updateConfig() {
    const config = Config.getConfig(true);

    config.wrapper.debug = false;
    config.match.engine.command = ['java', '-jar', competition.paths.engine];

    this.config = config;

    this.configSwitched = JSON.parse(JSON.stringify(config));
    this.configSwitched.match.bots = this.configSwitched.match.bots.reverse();
  }

  exit() {
    this.runningProcesses.forEach(p => p.kill());
  }
}

module.exports = MatchRunner;
<|endoftext|>