<commit_before>/**
 * index.js
 */
"use strict";
{
  /* api */
  const {Input, Output} = require("./modules/native-message");
  const {
    convUriToFilePath, createDir, createFile, getFileNameFromFilePath,
    getFileTimestamp, isExecutable, isFile, removeDir, removeDirSync, readFile,
  } = require("./modules/file-util");
  const {execFile} = require("child_process");
  const os = require("os");
  const path = require("path");
  const process = require("process");

  /* constants */
  const {
    EDITOR_CONFIG_GET, EDITOR_CONFIG_RES, HOST, LABEL, LOCAL_FILE_VIEW,
    PROCESS_CHILD, TMP_FILES, TMP_FILES_PB, TMP_FILES_PB_REMOVE,
    TMP_FILE_CREATE, TMP_FILE_DATA_PORT, TMP_FILE_GET, TMP_FILE_RES,
  } = require("./modules/constant");
  const APP = `${process.pid}`;
  const CHAR = "utf8";
  const CMD_ARGS = "cmdArgs";
  const DIR_TMP = [os.tmpdir(), LABEL, APP];
  const DIR_TMP_FILES = [...DIR_TMP, TMP_FILES];
  const DIR_TMP_FILES_PB = [...DIR_TMP, TMP_FILES_PB];
  const EDITOR_PATH = "editorPath";
  const FILE_AFTER_ARGS = "fileAfterCmdArgs";

  /* variables */
  const vars = {
    [CMD_ARGS]: [],
    [EDITOR_PATH]: "",
    [FILE_AFTER_ARGS]: false,
  };

  /**
   * throw error
   * @param {!Object} e - Error
   * @throws - Error
   */
  const throwErr = e => {
    throw e;
  };

  /**
   * is string
   * @param {*} o - object to check
   * @returns {boolean} - result
   */
  const isString = o => typeof o === "string" || o instanceof String;

  /**
   * correct the argument
   * @param {string} arg - argument
   * @returns {string} - argument
   */
  const correctArg = arg => {
    if (/^\s*(?:".*"|'.*')\s*$/.test(arg)) {
      arg = arg.trim();
      /^".*\\["\\].*"$/.test(arg) &&
        (arg = arg.replace(/\\"/g, "\"").replace(/\\\\/g, "\\"));
      arg = arg.replace(/^['"]/, "").replace(/["']$/, "");
    } else {
      /^.*\\.*$/.test(arg) && (arg = arg.replace(/\\(?!\\)/g, ""));
      /".*"|'.*'/.test(arg) &&
        (arg = arg.replace(/"([^"]+)*"|'([^']+)*'/g, (m, c1, c2) => c1 || c2));
    }
    return arg;
  };

  /**
   * concat arguments array
   * @param {...(string|Array)} args - arguments
   * @returns {Array} - arguments array
   */
  const concatArgs = (...args) => {
    const reCmd = /(?:^|\s)(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*')(?=\s|$)|(?:\\ |[^\s])+(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*')(?:(?:\\ |[^\s])+(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*'))*(?:\\ |[^\s])*|(?:[^"'\s\\]|\\[^\s]|\\ )+/g;
    const arr = args.map(arg => {
      isString(arg) && (arg = arg.match(reCmd));
      return Array.isArray(arg) && arg.map(correctArg) || [];
    });
    return arr.length && arr.reduce((a, b) => a.concat(b)) || [];
  };

  /* child process */
  /**
   * spawn child process
   * @param {string} file - file path
   * @returns {Object} - Promise.<Object>, ?ChildProcess
   */
  const spawnChildProcess = file => new Promise(resolve => {
    const app = vars[EDITOR_PATH];
    const pos = vars[FILE_AFTER_ARGS] || false;
    let args = vars[CMD_ARGS] || [], proc;
    if (isFile(file) && isExecutable(app)) {
      const argA = pos && args || [file.replace(/\\/g, "\\\\")];
      const argB = pos && [file.replace(/\\/g, "\\\\")] || args;
      const opt = {
        cwd: null,
        encoding: CHAR,
        env: process.env,
      };
      args = concatArgs(argA, argB);
      proc = execFile(app, args, opt, (e, stdout, stderr) => {
        const output = new Output();
        if (e) {
          e = output.encode(e);
          e && process.stderr.write(e);
        }
        if (stderr) {
          stderr = output.encode({
            [HOST]: {
              message: `${stderr}: ${app}`,
              pid: APP,
              status: `${PROCESS_CHILD}_stderr`,
            },
          });
          stderr && process.stdout.write(stderr);
        }
        if (stdout) {
          stdout = output.encode({
            [HOST]: {
              message: `${stdout}: ${app}`,
              pid: APP,
              status: `${PROCESS_CHILD}_stdout`,
            },
          });
          stdout && process.stdout.write(stdout);
        }
      });
    }
    resolve(proc || null);
  });

  /* output */
  /**
   * write stdout
   * @param {*} msg - message
   * @returns {Object} - Promise.<?boolean>
   */
  const writeStdout = msg => new Promise(resolve => {
    msg = (new Output()).encode(msg);
    resolve(msg && process.stdout.write(msg) || null);
  });

  /**
   * port app status
   * @returns {Object} - Promise.<?boolean>
   */
  const portAppStatus = () => writeStdout({
    [HOST]: {
      message: EDITOR_CONFIG_GET,
      pid: APP,
      status: "ready",
    },
  });

  /**
   * port editor config
   * @param {string} data - editor config
   * @param {string} editorConfig - editor config file path
   * @returns {Object} - Promise.<?boolean>
   */
  const portEditorConfig = (data, editorConfig) => new Promise(resolve => {
    let msg;
    try {
      data = data && JSON.parse(data);
      if (data) {
        const {editorPath} = data;
        const editorName = getFileNameFromFilePath(editorPath);
        const executable = isExecutable(editorPath);
        const items = Object.keys(data);
        if (items.length) {
          for (const item of items) {
            vars[item] = data[item];
          }
        }
        msg = {
          [EDITOR_CONFIG_RES]: {
            editorConfig, editorName, editorPath, executable,
          },
        };
      }
    } catch (e) {
      msg = {
        [HOST]: {
          message: `${e}: ${editorConfig}`,
          pid: APP,
          status: "error",
        },
      };
    }
    resolve(msg || null);
  }).then(writeStdout);

  /**
   * port file data
   * @param {string} filePath - file path
   * @param {Object} data - file data
   * @returns {Object} - Promise.<?boolean>
   */
  const portFileData = (filePath, data = {}) => new Promise(resolve => {
    let msg;
    if (isString(filePath)) {
      data.filePath = filePath;
      msg = {
        [TMP_FILE_DATA_PORT]: {filePath, data},
      };
    }
    resolve(msg || null);
  }).then(writeStdout);

  /**
   * port temporary file
   * @param {Object} obj - temporary file data object
   * @returns {Object} - Promise.<?boolean>
   */
  const portTmpFile = (obj = {}) => new Promise(resolve => {
    const msg = Object.keys(obj).length && {
      [TMP_FILE_RES]: obj,
    };
    resolve(msg || null);
  }).then(writeStdout);

  /* temporary files */
  /**
   * remove private temporary files
   * @param {boolean} bool - remove
   * @returns {Object} - ?Promise.<void>
   */
  const removePrivateTmpFiles = bool =>
    !!bool && removeDir(path.join(...DIR_TMP_FILES_PB)).then(() =>
      createDir(DIR_TMP_FILES_PB)
    ) || null;

  /**
   * create temporary file
   * @param {Object} obj - temporary file data object
   * @returns {Object} - ?Promise.<Object> temporary file data
   */
  const createTmpFile = (obj = {}) => new Promise(resolve => {
    const {data, value} = obj;
    let func;
    if (data) {
      const {dir, fileName, host, tabId, windowId} = data;
      const arr = dir && windowId && tabId && host &&
                  [...DIR_TMP, dir, windowId, tabId, host];
      func = arr && fileName && createDir(arr).then(dPath =>
        dPath === path.join(...arr) &&
          createFile(path.join(dPath, fileName), value)
      ).then(filePath => filePath && {filePath, data} || null);
    }
    resolve(func || null);
  });

  /**
   * append file timestamp
   * @param {Object} data - temporary file data
   * @returns {Object} - Promise.<Object>, temporary file data
   */
  const appendTimestamp = (data = {}) => new Promise(resolve => {
    const {filePath} = data;
    const timestamp = filePath && getFileTimestamp(filePath);
    data.timestamp = timestamp || 0;
    resolve(data);
  });

  /**
   * get temporary file
   * @param {Object} obj - temporary file data
   * @returns {Object} - Promise.<Object>
   */
  const getTmpFile = (obj = {}) => {
    const {filePath} = obj;
    const arr = [];
    if (filePath) {
      arr.push(appendTimestamp(obj));
      arr.push(readFile(filePath));
    }
    return Promise.all(arr).then(a => {
      let o;
      if (a.length) {
        const [data, value] = a;
        o = {data, value};
      }
      return o || null;
    });
  };

  /* local files */
  /**
   * get editor config
   * @param {string} filePath - editor config file path
   * @returns {Object} - Promise.<*>
   */
  const getEditorConfig = filePath => new Promise(resolve => {
    let func;
    filePath = isString(filePath) && filePath.length && filePath ||
               path.resolve(path.join(".", "editorconfig.json"));
    if (isFile(filePath)) {
      func = readFile(filePath).then(data => portEditorConfig(data, filePath));
    } else {
      const msg = {
        [HOST]: {
          message: `${filePath} is not a file.`,
          pid: APP,
          status: "warn",
        },
        [EDITOR_CONFIG_RES]: null,
      };
      func = writeStdout(msg);
    }
    resolve(func || null);
  });

  /**
   * view local file
   * @param {string} uri - local file uri
   * @returns {Object} - Promise.<Object> ChildProcess
   */
  const viewLocalFile = uri => convUriToFilePath(uri).then(spawnChildProcess);

  /* handlers */
  /**
   * handle created temporary file
   * @param {Object} obj - temporary file data
   * @returns {Object} - Promise.<Array.<*>>
   */
  const handleCreatedTmpFile = (obj = {}) => {
    const {filePath, data} = obj;
    const arr = [];
    if (filePath) {
      arr.push(spawnChildProcess(filePath));
      arr.push(portFileData(filePath, data));
    }
    return Promise.all(arr);
  };

  /**
   * handle message
   * @param {*} msg - message
   * @returns {Object} - Promise.<Array<*>>
   */
  const handleMsg = msg => {
    const func = [];
    const items = msg && Object.keys(msg);
    if (items && items.length) {
      for (const item of items) {
        const obj = msg[item];
        switch (item) {
          case EDITOR_CONFIG_GET:
            func.push(getEditorConfig(obj));
            break;
          case LOCAL_FILE_VIEW:
            func.push(viewLocalFile(obj));
            break;
          case TMP_FILE_CREATE:
            func.push(createTmpFile(obj).then(handleCreatedTmpFile));
            break;
          case TMP_FILE_GET:
            func.push(getTmpFile(obj).then(portTmpFile));
            break;
          case TMP_FILES_PB_REMOVE:
            func.push(removePrivateTmpFiles(obj));
            break;
          default:
        }
      }
    }
    return Promise.all(func).catch(throwErr);
  };

  /* input */
  const input = new Input();

  /**
   * read stdin
   * @param {string|Buffer} chunk - chunk
   * @returns {void}
   */
  const readStdin = chunk => input.decode(chunk, handleMsg);

  /* exit */
  /**
   * handle exit
   * @param {number} code - exit code
   * @returns {void}
   */
  const handleExit = code => {
    const msg = (new Output()).encode({
      [HOST]: {
        message: `exit ${code || 0}`,
        pid: APP,
        status: "exit",
      },
    });
    removeDirSync(path.join(...DIR_TMP));
    msg && process.stdout.write(msg);
  };

  /**
   * handle unhandled rejection
   * @param {*} e - Error or any
   * @returns {void}
   */
  const unhandledReject = e => {
    e = (new Output()).encode({
      [HOST]: {
        message: e,
        pid: APP,
        status: "error",
      },
    });
    e && process.stdout.write(e);
  };

  /* process */
  process.on("exit", handleExit);
  process.on("uncaughtException", throwErr);
  process.on("unhandledRejection", unhandledReject);
  process.stdin.on("data", readStdin);

  /* startup */
  Promise.all([
    createDir(DIR_TMP_FILES),
    createDir(DIR_TMP_FILES_PB),
  ]).then(portAppStatus).catch(throwErr);
}
<commit_msg>Refactor rejection handling<commit_after>/**
 * index.js
 */
"use strict";
{
  /* api */
  const {Input, Output} = require("./modules/native-message");
  const {
    convUriToFilePath, createDir, createFile, getFileNameFromFilePath,
    getFileTimestamp, isExecutable, isFile, removeDir, removeDirSync, readFile,
  } = require("./modules/file-util");
  const {execFile} = require("child_process");
  const os = require("os");
  const path = require("path");
  const process = require("process");

  /* constants */
  const {
    EDITOR_CONFIG_GET, EDITOR_CONFIG_RES, HOST, LABEL, LOCAL_FILE_VIEW,
    PROCESS_CHILD, TMP_FILES, TMP_FILES_PB, TMP_FILES_PB_REMOVE,
    TMP_FILE_CREATE, TMP_FILE_DATA_PORT, TMP_FILE_GET, TMP_FILE_RES,
  } = require("./modules/constant");
  const APP = `${process.pid}`;
  const CHAR = "utf8";
  const CMD_ARGS = "cmdArgs";
  const DIR_TMP = [os.tmpdir(), LABEL, APP];
  const DIR_TMP_FILES = [...DIR_TMP, TMP_FILES];
  const DIR_TMP_FILES_PB = [...DIR_TMP, TMP_FILES_PB];
  const EDITOR_PATH = "editorPath";
  const FILE_AFTER_ARGS = "fileAfterCmdArgs";

  /* variables */
  const vars = {
    [CMD_ARGS]: [],
    [EDITOR_PATH]: "",
    [FILE_AFTER_ARGS]: false,
  };

  /**
   * throw error
   * @param {!Object} e - Error
   * @throws - Error
   */
  const throwErr = e => {
    throw e;
  };

  /**
   * handle rejection
   * @param {*} e - Error or any
   * @returns {void}
   */
  const handleReject = e => {
    e = (new Output()).encode({
      [HOST]: {
        message: e,
        pid: APP,
        status: "error",
      },
    });
    e && process.stdout.write(e);
  };

  /**
   * is string
   * @param {*} o - object to check
   * @returns {boolean} - result
   */
  const isString = o => typeof o === "string" || o instanceof String;

  /**
   * correct the argument
   * @param {string} arg - argument
   * @returns {string} - argument
   */
  const correctArg = arg => {
    if (/^\s*(?:".*"|'.*')\s*$/.test(arg)) {
      arg = arg.trim();
      /^".*\\["\\].*"$/.test(arg) &&
        (arg = arg.replace(/\\"/g, "\"").replace(/\\\\/g, "\\"));
      arg = arg.replace(/^['"]/, "").replace(/["']$/, "");
    } else {
      /^.*\\.*$/.test(arg) && (arg = arg.replace(/\\(?!\\)/g, ""));
      /".*"|'.*'/.test(arg) &&
        (arg = arg.replace(/"([^"]+)*"|'([^']+)*'/g, (m, c1, c2) => c1 || c2));
    }
    return arg;
  };

  /**
   * concat arguments array
   * @param {...(string|Array)} args - arguments
   * @returns {Array} - arguments array
   */
  const concatArgs = (...args) => {
    const reCmd = /(?:^|\s)(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*')(?=\s|$)|(?:\\ |[^\s])+(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*')(?:(?:\\ |[^\s])+(?:"(?:[^"\\]|\\[^"]|\\")*"|'(?:[^'\\]|\\[^']|\\')*'))*(?:\\ |[^\s])*|(?:[^"'\s\\]|\\[^\s]|\\ )+/g;
    const arr = args.map(arg => {
      isString(arg) && (arg = arg.match(reCmd));
      return Array.isArray(arg) && arg.map(correctArg) || [];
    });
    return arr.length && arr.reduce((a, b) => a.concat(b)) || [];
  };

  /* child process */
  /**
   * spawn child process
   * @param {string} file - file path
   * @returns {Object} - Promise.<Object>, ?ChildProcess
   */
  const spawnChildProcess = file => new Promise(resolve => {
    const app = vars[EDITOR_PATH];
    const pos = vars[FILE_AFTER_ARGS] || false;
    let args = vars[CMD_ARGS] || [], proc;
    if (isFile(file) && isExecutable(app)) {
      const argA = pos && args || [file.replace(/\\/g, "\\\\")];
      const argB = pos && [file.replace(/\\/g, "\\\\")] || args;
      const opt = {
        cwd: null,
        encoding: CHAR,
        env: process.env,
      };
      args = concatArgs(argA, argB);
      proc = execFile(app, args, opt, (e, stdout, stderr) => {
        const output = new Output();
        if (e) {
          e = output.encode(e);
          e && process.stderr.write(e);
        }
        if (stderr) {
          stderr = output.encode({
            [HOST]: {
              message: `${stderr}: ${app}`,
              pid: APP,
              status: `${PROCESS_CHILD}_stderr`,
            },
          });
          stderr && process.stdout.write(stderr);
        }
        if (stdout) {
          stdout = output.encode({
            [HOST]: {
              message: `${stdout}: ${app}`,
              pid: APP,
              status: `${PROCESS_CHILD}_stdout`,
            },
          });
          stdout && process.stdout.write(stdout);
        }
      });
    }
    resolve(proc || null);
  });

  /* output */
  /**
   * write stdout
   * @param {*} msg - message
   * @returns {Object} - Promise.<?boolean>
   */
  const writeStdout = msg => new Promise(resolve => {
    msg = (new Output()).encode(msg);
    resolve(msg && process.stdout.write(msg) || null);
  });

  /**
   * port app status
   * @returns {Object} - Promise.<?boolean>
   */
  const portAppStatus = () => writeStdout({
    [HOST]: {
      message: EDITOR_CONFIG_GET,
      pid: APP,
      status: "ready",
    },
  });

  /**
   * port editor config
   * @param {string} data - editor config
   * @param {string} editorConfig - editor config file path
   * @returns {Object} - Promise.<?boolean>
   */
  const portEditorConfig = (data, editorConfig) => new Promise(resolve => {
    let msg;
    try {
      data = data && JSON.parse(data);
      if (data) {
        const {editorPath} = data;
        const editorName = getFileNameFromFilePath(editorPath);
        const executable = isExecutable(editorPath);
        const items = Object.keys(data);
        if (items.length) {
          for (const item of items) {
            vars[item] = data[item];
          }
        }
        msg = {
          [EDITOR_CONFIG_RES]: {
            editorConfig, editorName, editorPath, executable,
          },
        };
      }
    } catch (e) {
      msg = {
        [HOST]: {
          message: `${e}: ${editorConfig}`,
          pid: APP,
          status: "error",
        },
      };
    }
    resolve(msg || null);
  }).then(writeStdout);

  /**
   * port file data
   * @param {string} filePath - file path
   * @param {Object} data - file data
   * @returns {Object} - Promise.<?boolean>
   */
  const portFileData = (filePath, data = {}) => new Promise(resolve => {
    let msg;
    if (isString(filePath)) {
      data.filePath = filePath;
      msg = {
        [TMP_FILE_DATA_PORT]: {filePath, data},
      };
    }
    resolve(msg || null);
  }).then(writeStdout);

  /**
   * port temporary file
   * @param {Object} obj - temporary file data object
   * @returns {Object} - Promise.<?boolean>
   */
  const portTmpFile = (obj = {}) => new Promise(resolve => {
    const msg = Object.keys(obj).length && {
      [TMP_FILE_RES]: obj,
    };
    resolve(msg || null);
  }).then(writeStdout);

  /* temporary files */
  /**
   * remove private temporary files
   * @param {boolean} bool - remove
   * @returns {Object} - ?Promise.<void>
   */
  const removePrivateTmpFiles = bool =>
    !!bool && removeDir(path.join(...DIR_TMP_FILES_PB)).then(() =>
      createDir(DIR_TMP_FILES_PB)
    ) || null;

  /**
   * create temporary file
   * @param {Object} obj - temporary file data object
   * @returns {Object} - ?Promise.<Object> temporary file data
   */
  const createTmpFile = (obj = {}) => new Promise(resolve => {
    const {data, value} = obj;
    let func;
    if (data) {
      const {dir, fileName, host, tabId, windowId} = data;
      const arr = dir && windowId && tabId && host &&
                  [...DIR_TMP, dir, windowId, tabId, host];
      func = arr && fileName && createDir(arr).then(dPath =>
        dPath === path.join(...arr) &&
          createFile(path.join(dPath, fileName), value)
      ).then(filePath => filePath && {filePath, data} || null);
    }
    resolve(func || null);
  });

  /**
   * append file timestamp
   * @param {Object} data - temporary file data
   * @returns {Object} - Promise.<Object>, temporary file data
   */
  const appendTimestamp = (data = {}) => new Promise(resolve => {
    const {filePath} = data;
    const timestamp = filePath && getFileTimestamp(filePath);
    data.timestamp = timestamp || 0;
    resolve(data);
  });

  /**
   * get temporary file
   * @param {Object} obj - temporary file data
   * @returns {Object} - Promise.<Object>
   */
  const getTmpFile = (obj = {}) => {
    const {filePath} = obj;
    const arr = [];
    if (filePath) {
      arr.push(appendTimestamp(obj));
      arr.push(readFile(filePath));
    }
    return Promise.all(arr).then(a => {
      let o;
      if (a.length) {
        const [data, value] = a;
        o = {data, value};
      }
      return o || null;
    });
  };

  /* local files */
  /**
   * get editor config
   * @param {string} filePath - editor config file path
   * @returns {Object} - Promise.<*>
   */
  const getEditorConfig = filePath => new Promise(resolve => {
    let func;
    filePath = isString(filePath) && filePath.length && filePath ||
               path.resolve(path.join(".", "editorconfig.json"));
    if (isFile(filePath)) {
      func = readFile(filePath).then(data => portEditorConfig(data, filePath));
    } else {
      const msg = {
        [HOST]: {
          message: `${filePath} is not a file.`,
          pid: APP,
          status: "warn",
        },
        [EDITOR_CONFIG_RES]: null,
      };
      func = writeStdout(msg);
    }
    resolve(func || null);
  });

  /**
   * view local file
   * @param {string} uri - local file uri
   * @returns {Object} - Promise.<Object> ChildProcess
   */
  const viewLocalFile = uri => convUriToFilePath(uri).then(spawnChildProcess);

  /* handlers */
  /**
   * handle created temporary file
   * @param {Object} obj - temporary file data
   * @returns {Object} - Promise.<Array.<*>>
   */
  const handleCreatedTmpFile = (obj = {}) => {
    const {filePath, data} = obj;
    const arr = [];
    if (filePath) {
      arr.push(spawnChildProcess(filePath));
      arr.push(portFileData(filePath, data));
    }
    return Promise.all(arr);
  };

  /**
   * handle message
   * @param {*} msg - message
   * @returns {Object} - Promise.<Array<*>>
   */
  const handleMsg = msg => {
    const func = [];
    const items = msg && Object.keys(msg);
    if (items && items.length) {
      for (const item of items) {
        const obj = msg[item];
        switch (item) {
          case EDITOR_CONFIG_GET:
            func.push(getEditorConfig(obj));
            break;
          case LOCAL_FILE_VIEW:
            func.push(viewLocalFile(obj));
            break;
          case TMP_FILE_CREATE:
            func.push(createTmpFile(obj).then(handleCreatedTmpFile));
            break;
          case TMP_FILE_GET:
            func.push(getTmpFile(obj).then(portTmpFile));
            break;
          case TMP_FILES_PB_REMOVE:
            func.push(removePrivateTmpFiles(obj));
            break;
          default:
        }
      }
    }
    return Promise.all(func).catch(handleReject);
  };

  /* input */
  const input = new Input();

  /**
   * read stdin
   * @param {string|Buffer} chunk - chunk
   * @returns {void}
   */
  const readStdin = chunk => input.decode(chunk, handleMsg);

  /* exit */
  /**
   * handle exit
   * @param {number} code - exit code
   * @returns {void}
   */
  const handleExit = code => {
    const msg = (new Output()).encode({
      [HOST]: {
        message: `exit ${code || 0}`,
        pid: APP,
        status: "exit",
      },
    });
    removeDirSync(path.join(...DIR_TMP));
    msg && process.stdout.write(msg);
  };

  /* process */
  process.on("exit", handleExit);
  process.on("uncaughtException", throwErr);
  process.on("unhandleRejection", handleReject);
  process.stdin.on("data", readStdin);

  /* startup */
  Promise.all([
    createDir(DIR_TMP_FILES),
    createDir(DIR_TMP_FILES_PB),
  ]).then(portAppStatus).catch(handleReject);
}
<|endoftext|>


<commit_before>'use strict';

import diagnostics from 'diagnostics';
import resolve from 'resolve';
import path from 'path';
import fs from 'fs';

const debug = diagnostics('sass-import-modules');

/**
 * Append extension to file if required.
 *
 * @param {String} file File path.
 * @param {String} ext File extension.
 * @returns {String} file.
 * @api private
 */
function extension(file, ext) {
  if (!~file.indexOf(ext)) {
    file += ext;
  }

  return file;
}

/**
 * Resolve the file in node_modules.
 *
 * @param {String} file File path.
 * @param {String} base Current directory.
 * @param {String} ext File extension.
 * @param {Function} next Completion callback.
 * @returns {void}
 * @api private
 */
function node(file, base, ext, next)  {
  debug('Resolving file from node_modules: %s', file);
  base = path.dirname(base);

  return void resolve(extension(file, ext), { basedir: base }, (error, result) => {
    if (result) {
      return next(null, result);
    }

    resolve(file, { basedir: base }, next);
  });
}

/**
 * Resolve the file locally.
 *
 * @param {String} file File path.
 * @param {String} base Current directory.
 * @param {String} ext File extension.
 * @param {Function} next Completion callback.
 * @returns {void}
 * @api private
 */
function local(file, base, ext, next) {
  debug('Resolving file locally: %s', file);
  file = extension(path.join(path.dirname(base), file), ext);

  return void fs.stat(file, function exists(error, stat) {
    if (error || !stat) {
      return next(error);
    }

    next(null, file);
  });
}

/**
 * Return the file path to node-sass.
 *
 * @param {String} file Absolute path to file.
 * @param {Function} done Completion callback.
 * @returns {void}
 * @api private
 */
function provide(file, done) {
  return void done({ file });
}

/**
 * Setup an importer for node-sass.
 *
 * @param {Object} options Optional configuration.
 * @returns {Function} Importer.
 * @api public
 */
export function importer({ ext = '.scss' } = {}) {
  const cache = new Map();

  if (ext.charAt(0) !== '.') {
    ext = '.' + ext;
  }

  /**
   * Importer for SASS.
   *
   * @param {String} url File to resolve.
   * @param {String} prev Last resolved file.
   * @param {Function} done Completion callback.
   * @returns {void} Return early.
   * @api private
   */
  return function resolve(url, prev, done) {
    if (cache.has(url)) {
      debug('Resolving from cache: %s', url);
      return void provide(cache.get(url), done);
    }

    //
    // 1. Find the file relative to the previous discovered file.
    // 2. Find the file or module in node_modules.
    //
    debug('Resolving: %s', url);
    (function run(stack, error) {
      /**
       * Completion callback.
       *
       * @param {Error} err Error returned from resolver.
       * @param {String} file Full path to file.
       * @returns {Void} return early.
       * @api private
       */
      function next(err, file) {
        error = error || err;

        //
        // Resolved to a file on disk, return the file early.
        //
        if (file) {
          cache.set(url, file);
          return void provide(file, done);
        }

        //
        // All resolvers ran, no results found, return error.
        //
        if (error && !stack.length) {
          throw error;
        }

        //
        // Iterate over the stack.
        //
        return void run(stack, err, next);
      }

      stack.shift()(url, prev, ext, next);
    })([local, node]);
  }
};<commit_msg>[fix] provide more elaborate error<commit_after>'use strict';

import diagnostics from 'diagnostics';
import resolve from 'resolve';
import path from 'path';
import fs from 'fs';

const debug = diagnostics('sass-import-modules');

/**
 * Append extension to file if required.
 *
 * @param {String} file File path.
 * @param {String} ext File extension.
 * @returns {String} file.
 * @api private
 */
function extension(file, ext) {
  if (!~file.indexOf(ext)) {
    file += ext;
  }

  return file;
}

/**
 * Resolve the file in node_modules.
 *
 * @param {String} file File path.
 * @param {String} base Current directory.
 * @param {String} ext File extension.
 * @param {Function} next Completion callback.
 * @returns {void}
 * @api private
 */
function node(file, base, ext, next)  {
  debug('Resolving file from node_modules: %s', file);
  base = path.dirname(base);

  return void resolve(extension(file, ext), { basedir: base }, (error, result) => {
    if (result) {
      return next(null, result);
    }

    resolve(file, { basedir: base }, next);
  });
}

/**
 * Resolve the file locally.
 *
 * @param {String} file File path.
 * @param {String} base Current directory.
 * @param {String} ext File extension.
 * @param {Function} next Completion callback.
 * @returns {void}
 * @api private
 */
function local(file, base, ext, next) {
  debug('Resolving file locally: %s', file);
  file = extension(path.join(path.dirname(base), file), ext);

  return void fs.stat(file, function exists(error, stat) {
    if (error || !stat) {
      return next(error);
    }

    next(null, file);
  });
}

/**
 * Return the file path to node-sass.
 *
 * @param {String} file Absolute path to file.
 * @param {Function} done Completion callback.
 * @returns {void}
 * @api private
 */
function provide(file, done) {
  return void done({ file });
}

/**
 * Setup an importer for node-sass.
 *
 * @param {Object} options Optional configuration.
 * @returns {Function} Importer.
 * @api public
 */
export function importer({ ext = '.scss' } = {}) {
  const cache = new Map();

  if (ext.charAt(0) !== '.') {
    ext = '.' + ext;
  }

  /**
   * Importer for SASS.
   *
   * @param {String} url File to resolve.
   * @param {String} prev Last resolved file.
   * @param {Function} done Completion callback.
   * @returns {void} Return early.
   * @api private
   */
  return function resolve(url, prev, done) {
    if (cache.has(url)) {
      debug('Resolving from cache: %s', url);
      return void provide(cache.get(url), done);
    }

    //
    // 1. Find the file relative to the previous discovered file.
    // 2. Find the file or module in node_modules.
    //
    debug('Resolving: %s', url);
    (function run(stack, error) {
      /**
       * Completion callback.
       *
       * @param {Error} err Error returned from resolver.
       * @param {String} file Full path to file.
       * @returns {Void} return early.
       * @api private
       */
      function next(err, file) {
        error = error || err;

        //
        // Resolved to a file on disk, return the file early.
        //
        if (file) {
          cache.set(url, file);
          return void provide(file, done);
        }

        //
        // All resolvers ran, no results found, return error.
        //
        if (error && !stack.length) {
          throw new Error(`Could not find file: ${url} from parent ${prev}`);
        }

        //
        // Iterate over the stack.
        //
        return void run(stack, err, next);
      }

      stack.shift()(url, prev, ext, next);
    })([local, node]);
  }
};<|endoftext|>


<commit_before>var Neurotin = require('./lib/neurotin')
var bot = new Neurotin.Bot();

// Add Middleware to Neurotin
bot.middleware.receive.use(function(utterance, context, next) {
    // Default values for if this is the first time
    // communicating with the bot
    var defaults = {
      messageCount: 0,
      wordCount: 0
    }

    // Merge current context with the defaults.
    context.user = Object.assign(defaults, context.user)
    var text = utterance.text

    // Increment the message count and
    // calculate the new number of words the user has sent
    //
    var messageCount = context.user.messageCount + 1;
    var words = text.split(" ");
    var wordCount = context.user.wordCount + words.length;

    // Merge the new statistics into the context
    // and return it back to the bot
    context.user = Object.assign(context.user, {
      messageCount: messageCount,
      wordCount: wordCount
    })

    next();
});

bot.hears(['\/stats'], ['message_received'], function(utterance, context) {

    // Send the total number of messages to the
    // user
    utterance.reply("Total Message Count: " + context.user.messageCount)

    // Send the total number of words to the
    // user
    utterance.reply("Total Word Count: " + context.user.wordCount)
});

bot.hears([/.+/], ['message_received'], function(utterance, context) {
  utterance.reply(utterance.text);
});

bot.hears(['hey'], ['message_received'], function(utterance, context) {
  utterance.reply(utterance.text);
});

bot.spawn()
<commit_msg>Removes old code.<commit_after>var Neurotin = require('./lib/neurotin')
var bot = new Neurotin.Bot();

// Add Middleware to Neurotin
bot.middleware.receive.use(function(utterance, context, next) {
    // Default values for if this is the first time
    // communicating with the bot
    var defaults = {
      messageCount: 0,
      wordCount: 0
    }

    // Merge current context with the defaults.
    context.user = Object.assign(defaults, context.user)
    var text = utterance.text

    // Increment the message count and
    // calculate the new number of words the user has sent
    //
    var messageCount = context.user.messageCount + 1;
    var words = text.split(" ");
    var wordCount = context.user.wordCount + words.length;

    // Merge the new statistics into the context
    // and return it back to the bot
    context.user = Object.assign(context.user, {
      messageCount: messageCount,
      wordCount: wordCount
    })

    next();
});

bot.hears(['\/stats'], ['message_received'], function(utterance, context) {

    // Send the total number of messages to the
    // user
    utterance.reply("Total Message Count: " + context.user.messageCount)

    // Send the total number of words to the
    // user
    utterance.reply("Total Word Count: " + context.user.wordCount)
});

bot.hears([/.+/], ['message_received'], function(utterance, context) {
  utterance.reply(utterance.text);
});

bot.spawn()
<|endoftext|>


<commit_before>/*
Before using this lib for testing in Deb/Ubuntu, do : sudo service network-manager stop

1. Enable/Disable WIFI
2. List out all the wifi networks available
3. Connect with any of the networks with appropriate creds
4. Make a WIFI hotspot to share the internet connection

http://substack.net/wireless_from_the_command_line_in_linux
https://packages.debian.org/wheezy/net/iw
http://wireless.kernel.org/en/users/Documentation/iw

http://w1.fi/hostapd/
http://wireless.kernel.org/en/users/Documentation/hostapd

http://linuxcommando.blogspot.in/2013/10/how-to-connect-to-wpawpa2-wifi-network.html
http://superuser.com/questions/615664/creating-wifi-access-point-on-a-single-interface-in-linux

TODO : Node 0.12 has synchronous child processes and list its advantages and stuff
*/

var cp 		= require('child_process'),
	exec 	= cp.exec,
	spawn 	= cp.spawn,
	fs 		= require('fs'),
	extend  = require('util')._extend;

module.exports = Wifi;

//Utils
var utils = require('./utils'),
	update_dhclient 		= utils.update_dhclient,
	update_wpa_supplicant	= utils.update_wpa_supplicant,
	parse_ssid_list 		= utils.parse_ssid_list,
	parse_link_status		= utils.parse_link_status,
	MAC_REGEX 				= utils.MAC_REGEX,
	WPA_SUPPLICANT 			= utils.WPA_SUPPLICANT;

function Wifi(options){
	var options = extend({}, options);
	this.interface = options.interface || 'wlan0';
	this.driver    = options.driver || 'wext';
	this.current   = null;

	this.status(function(err,conn){
		if(!err && conn.connected) {
			this.current = conn['SSID'];
		}
	})
}

Wifi.prototype.iface = function(interface,cb){
	var ctx = this;
	//Check if interface is present
	exec('iwconfig',function(err,sout,serr){

		if(err) cb(err,serr);
		else {
			if(sout.search(interface) > -1) {
				//TODO: search matches substring and name maybe incomplete
				//Interface found, set the interface
				ctx.interface = interface;
				cb(null,true);
			}
			else cb(new Error('Interface with that name is not found'),null);
		}
	});
}

Wifi.prototype.enable = function(interface,cb){
	var cmd;
	if(!cb) cb = interface;
	else if (this.interface != interface) this.iface(interface);

	cmd = 'ifconfig '+this.interface+' up';
	exec(cmd,function(err,sout,serr){
		if(err) {
			cb(err,null);
			return;
		}
		cb(null,true)
	})
}

Wifi.prototype.disalbe = function(interface,cb){
	var cmd;
	if(!cb) cb = interface;
	else if (this.interface != interface) this.iface(interface);

	cmd = 'ifconfig '+this.interface+' down';
	exec(cmd,function(err,sout,serr){
		if(err) {
			cb(err,null);
			return;
		}
		cb(null,true)
	})
}

Wifi.prototype.config = function(){
	//To change mac,ip,subnet etc of an interface
}

Wifi.prototype.scan = function(cb){
	if(!cb) throw new Error('Callback needed');
	var accessPoints,
		result;
	exec('iw dev wlan0 scan',function(err,sout,serr){
		if(err) cb(err,null)
		else {
			accessPoints 	= sout.split(/\nBSS/);
			cb(null,parse_ssid_list(accessPoints));
		}
	})
}

Wifi.prototype.connect = function(ssid,passphrase,cb){
	if(!ssid) throw new Error('connect needs an ssid and a callback, min 2 args reqd');
	var isSecured = false,interface = this.interface,ctx = this;
	if(!cb) cb = passphrase;
	else isSecured = true;
	//TODO : Check if the ssid is actually present and find its auth type
	if(isSecured) {
		//Kill previous instances of wpa_supplicant if any
		this.disconnect(function(err,disconnected){
			//Create wpa_supplicant.conf if it doesnt exist
			if(!err & disconnected) {
				update_wpa_supplicant(ssid,passphrase,function(err,updated){
					if(!err && updated) {

						out = fs.openSync('./out.log', 'a'),
						ctx.current = spawn('wpa_supplicant'
											,["-D"+ctx.driver, "-i"+ctx.interface,"-c"+WPA_SUPPLICANT,"-B"]
											,{/*detached : true, */ stdio : ['ignore',out,out]}
											);
						//To prevent the parent(node) to wait for wpa_supplicant to exit.
						ctx.current.unref();
						//Extract mac , run dhclient
						update_dhclient(interface,function(err,updated){
							if(!err && updated) {
								ctx.status(interface,cb);
							}
							else cb(err,null)
						})
					}
					else cb(err,null);
				})
			}
			else cb(err,null)
		})
	}

	else {
		exec('iw dev '+interface+' connect -w '+ssid,function(err,sout,serr){
			if(err) {
				if(serr.search('Network is down') > -1) {
					//If networks is down, enable it and continue
					ctx.enable(interface,function(err,enabled){
						if(!err && enabled) ctx.connect(ssid,cb);
						else cb(err,null);
					})
				}
				else if (serr.search('Operation already in progress') > -1) {
					ctx.disconnect(function(err,disconnected){
						if(!err && disconnected) ctx.connect(ssid,cb);
						else cb(err,null)
					})
				}
				else cb(new Error(serr),null);
				return;
			}

			if(sout.search('connected to') > -1) {
				//Connected
				var mac = MAC_REGEX.exec(sout)[0];
				update_dhclient(interface,function(err,updated){
					if(!err && updated) {
						ctx.status(interface,cb);
					}
					else cb(err,null);
				})

			}
			else cb(new Error(sout),null); // TODO, should err be null and {connected : false } ?
		})
	}
}

Wifi.prototype.disconnect = function(cb){
	var ctx = this;
	exec('killall wpa_supplicant',function(err,sout,serr){
		if(err) {
			if(err.message.search('no process found') > -1) {
				exec('iw dev '+ctx.interface+ ' disconnect',function(err,sout,serr){
					if(err) {
						//TODO
					}
					cb(null,true);
				})
			}
			else cb(serr,null);
		}
		else {
			setTimeout(function(){ ctx.enable(cb);}, 200)
			ctx.current = null;
		}
	})
}

Wifi.prototype.status = function(interface,cb){
	var cmd;
	if(!cb) cb = interface
	else if (interface && this.interface != interface) this.iface(interface);
	cmd = 'iw dev '+this.interface+' link';
	exec(cmd,function(err,sout,serr){
		if(err){
			cb(err,null);
			return;
		}

		if(/Connected to/.test(sout)){
			//Connected to a ap
			var result = parse_link_status(sout);
			result['connected'] = true;
			cb(null,result);
		}
		else if(/Not connected./.test(sout)){
			//Not connected to any ap
			cb(null,{connected : false});
		}
		else {
			//Command execution problem
			cb(new Error('Problem executing command "iw dev %interface% link"'),null);
		}
	})
}

Wifi.prototype.hotspot = function(ssid,passphrase){
		//Invote the ap-hotspot functionality

}
<commit_msg>add hotspot<commit_after>/*
Before using this lib for testing in Deb/Ubuntu, do : sudo service network-manager stop

1. Enable/Disable WIFI
2. List out all the wifi networks available
3. Connect with any of the networks with appropriate creds
4. Make a WIFI hotspot to share the internet connection

http://substack.net/wireless_from_the_command_line_in_linux
https://packages.debian.org/wheezy/net/iw
http://wireless.kernel.org/en/users/Documentation/iw

http://w1.fi/hostapd/
http://wireless.kernel.org/en/users/Documentation/hostapd

http://linuxcommando.blogspot.in/2013/10/how-to-connect-to-wpawpa2-wifi-network.html
http://superuser.com/questions/615664/creating-wifi-access-point-on-a-single-interface-in-linux

TODO : Node 0.12 has synchronous child processes and list its advantages and stuff
*/

var cp 		= require('child_process'),
	exec 	= cp.exec,
	spawn 	= cp.spawn,
	fs 		= require('fs'),
	extend  = require('util')._extend;

module.exports = Wifi;

//Utils
var utils = require('./utils'),
	update_dhclient 		= utils.update_dhclient,
	update_wpa_supplicant	= utils.update_wpa_supplicant,
	parse_ssid_list 		= utils.parse_ssid_list,
	parse_link_status		= utils.parse_link_status,
	MAC_REGEX 				= utils.MAC_REGEX,
	WPA_SUPPLICANT 			= utils.WPA_SUPPLICANT;

var hotspot = require('./hotspot');

function Wifi(options){
	var options = extend({}, options);
	this.interface = options.interface || 'wlan0';
	this.driver    = options.driver || 'wext';
	this.current   = null;

	this.status(function(err,conn){
		if(!err && conn.connected) {
			this.current = conn['SSID'];
		}
	})
}

Wifi.prototype.iface = function(interface,cb){
	var ctx = this;
	//Check if interface is present
	exec('iwconfig',function(err,sout,serr){

		if(err) cb(err,serr);
		else {
			if(sout.search(interface) > -1) {
				//TODO: search matches substring and name maybe incomplete
				//Interface found, set the interface
				ctx.interface = interface;
				cb(null,true);
			}
			else cb(new Error('Interface with that name is not found'),null);
		}
	});
}

Wifi.prototype.enable = function(interface,cb){
	var cmd;
	if(!cb) cb = interface;
	else if (this.interface != interface) this.iface(interface);

	cmd = 'ifconfig '+this.interface+' up';
	exec(cmd,function(err,sout,serr){
		if(err) {
			cb(err,null);
			return;
		}
		cb(null,true)
	})
}

Wifi.prototype.disalbe = function(interface,cb){
	var cmd;
	if(!cb) cb = interface;
	else if (this.interface != interface) this.iface(interface);

	cmd = 'ifconfig '+this.interface+' down';
	exec(cmd,function(err,sout,serr){
		if(err) {
			cb(err,null);
			return;
		}
		cb(null,true)
	})
}

Wifi.prototype.config = function(){
	//To change mac,ip,subnet etc of an interface
}

Wifi.prototype.scan = function(cb){
	if(!cb) throw new Error('Callback needed');
	var accessPoints,
		result;
	exec('iw dev wlan0 scan',function(err,sout,serr){
		if(err) cb(err,null)
		else {
			accessPoints 	= sout.split(/\nBSS/);
			cb(null,parse_ssid_list(accessPoints));
		}
	})
}

Wifi.prototype.connect = function(ssid,passphrase,cb){
	if(!ssid) throw new Error('connect needs an ssid and a callback, min 2 args reqd');
	var isSecured = false,interface = this.interface,ctx = this;
	if(!cb) cb = passphrase;
	else isSecured = true;
	//TODO : Check if the ssid is actually present and find its auth type
	if(isSecured) {
		//Kill previous instances of wpa_supplicant if any
		this.disconnect(function(err,disconnected){
			//Create wpa_supplicant.conf if it doesnt exist
			if(!err & disconnected) {
				update_wpa_supplicant(ssid,passphrase,function(err,updated){
					if(!err && updated) {

						out = fs.openSync('./out.log', 'a'),
						ctx.current = spawn('wpa_supplicant'
											,["-D"+ctx.driver, "-i"+ctx.interface,"-c"+WPA_SUPPLICANT,"-B"]
											,{/*detached : true, */ stdio : ['ignore',out,out]}
											);
						//To prevent the parent(node) to wait for wpa_supplicant to exit.
						ctx.current.unref();
						//Extract mac , run dhclient
						update_dhclient(interface,function(err,updated){
							if(!err && updated) {
								ctx.status(interface,cb);
							}
							else cb(err,null)
						})
					}
					else cb(err,null);
				})
			}
			else cb(err,null)
		})
	}

	else {
		exec('iw dev '+interface+' connect -w '+ssid,function(err,sout,serr){
			if(err) {
				if(serr.search('Network is down') > -1) {
					//If networks is down, enable it and continue
					ctx.enable(interface,function(err,enabled){
						if(!err && enabled) ctx.connect(ssid,cb);
						else cb(err,null);
					})
				}
				else if (serr.search('Operation already in progress') > -1) {
					ctx.disconnect(function(err,disconnected){
						if(!err && disconnected) ctx.connect(ssid,cb);
						else cb(err,null)
					})
				}
				else cb(new Error(serr),null);
				return;
			}

			if(sout.search('connected to') > -1) {
				//Connected
				var mac = MAC_REGEX.exec(sout)[0];
				update_dhclient(interface,function(err,updated){
					if(!err && updated) {
						ctx.status(interface,cb);
					}
					else cb(err,null);
				})

			}
			else cb(new Error(sout),null); // TODO, should err be null and {connected : false } ?
		})
	}
}

Wifi.prototype.disconnect = function(cb){
	var ctx = this;
	exec('killall wpa_supplicant',function(err,sout,serr){
		if(err) {
			if(err.message.search('no process found') > -1) {
				exec('iw dev '+ctx.interface+ ' disconnect',function(err,sout,serr){
					if(err) {
						//TODO
					}
					cb(null,true);
				})
			}
			else cb(serr,null);
		}
		else {
			setTimeout(function(){ ctx.enable(cb);}, 200)
			ctx.current = null;
		}
	})
}

Wifi.prototype.status = function(interface,cb){
	var cmd;
	if(!cb) cb = interface
	else if (interface && this.interface != interface) this.iface(interface);
	cmd = 'iw dev '+this.interface+' link';
	exec(cmd,function(err,sout,serr){
		if(err){
			cb(err,null);
			return;
		}

		if(/Connected to/.test(sout)){
			//Connected to a ap
			var result = parse_link_status(sout);
			result['connected'] = true;
			cb(null,result);
		}
		else if(/Not connected./.test(sout)){
			//Not connected to any ap
			cb(null,{connected : false});
		}
		else {
			//Command execution problem
			cb(new Error('Problem executing command "iw dev %interface% link"'),null);
		}
	})
}

Wifi.prototype.hotspot = function(ssid,passphrase,iface){
		//Invote the ap-hotspot functionality
		if(!iface) iface = 'wlan0';
		hotspot.start(ssid,passphrase,iface);
}
<|endoftext|>


<commit_before>var octonode = require('octonode'),
    url = require('url'),
    querystring = require('querystring'),
    curry = require('curry'),
    async = require('async'),
    minimatch = require('minimatch'),
    parseLinks = require('parse-link-header'),
    extend = require('extend'),
    stats = require('./lib/stats'),
    sort = require('./lib/sort');

module.exports = {
  client: client,
  stats: stats,
  expand: expand
};

function client() {
  var client = octonode.client.apply(octonode, arguments),
      get = client.get.bind(client);

  client.get = curry(function(uri, params, done) {
    var data = expand(uri, params);
    return get(data.uri, data.params, done);
  });

  client.getAll = curry(function(uri, params, done) {
    params.page = 1;
    var data = [],
        last = '?',
        next = function() {
          log('get: %s (page %d of %s)', uri, params.page, last, JSON.stringify(params));
          return client.get(uri, params, handler);
        },
        handler = function(error, status, page, headers) {
          if (error) {
            return done(error);
          } else if (!Array.isArray(page)) {
            return done('expected array; got ' + typeof page);
          }

          if (!page.length) {
            log('nothing in this page:', params.page);
            return done(null, data);
          }
          data = data.concat(page);
          var links = parseLinks(headers.link);
          if (links && links.next) {
            last = links.last ? links.last.page : '?';
            params.page = +links.next.page;
            return next();
          } else {
            return done(null, data);
          }
        };

    return next();
  });

  client.matchRepos = curry(function(repos, options, done) {
    var include = options.include;

    if (typeof repos === 'string') {
      var path = repos;
      if (path.charAt(0) === '/') {
        path = path.substr(1);
      }
      var bits = path.split('/');
      switch (bits.length) {
        case 1:
          path = 'users/' + path;
          break;
        case 2:
          break;
        case 3:
          path = bits.slice(0, -1).join('/');
          include = bits[2];
          break;
      }
      repos = client.getAll('/' + path + '/repos', {per_page: 100});
    }

    var test = (include && include !== '*')
      ? function(repo) {
        log("minimatch('%s', '%s')", repo.name, include);
        return minimatch(repo.name, include);
      }
      : function() { return true; };

    if (options.exclude) {
      var exclude = options.exclude,
          _test = test;
      test = function(repo) {
        return _test(repo) && !minimatch(repo.name, exclude);
      };
    }

    switch (typeof repos) {
      case 'function':
        return async.waterfall([
          repos,
          function (repos, next) {
            log('matching %d repos against', repos.length, options);
            repos.sort(function(a, b) {
              return sort.ascending(a.name, b.name);
            });
            var filtered = repos.filter(test);
            log('got %d matches: %s', filtered.length, filtered.map(function(d) { return d.name; }).join(', '));
            next(null, filtered);
          }
        ], done);

      case 'object':
        return done(null, repos.filter(test));
    }
  });

  client.stats = stats;

  client.aggregate = curry(function(type, options, args, repos, done) {
    var agg = client.stats[type];
    if (!agg) {
      return done('no such aggregate statistic: ' + type);
    }
    var limit = 10; // +options.parallel || 1;
    log('getting %s stats for %d repo(s)...', type, repos.length);

    async.mapLimit(repos, limit, function(repo, next) {
      log('getting %s stats for %s/%s', type, repo.owner.login, repo.name);
      agg.fetch(client, repo, args, function(error, stats) {
        if (error) return done(error);
        if (!repo.stats) repo.stats = {};
        repo.stats[type] = stats;
        next(null, repo);
      });
    }, function(error) {
      if (error) return done(error);
      var reduce = client.stats[type].reduce;
      return done(null, reduce ? reduce(repos, args) : repos);
    });
  });

  client.debug = false;

  function log() {
    if (!client.debug) return;
    console.warn.apply(console, arguments);
  }

  client.log = log;

  return client;
}

function expand(uri, params) {
  params = extend({}, params);
  for (var key in params) {
    if (!params[key]) delete params[key];
  }
  uri = uri.replace(/:(\w+)/g, function(_, key) {
    var value = params[key];
    delete params[key];
    return value;
  });
  return {uri: uri, params: params};
}
<commit_msg>add .version, nix .expand in exports<commit_after>var octonode = require('octonode'),
    url = require('url'),
    querystring = require('querystring'),
    curry = require('curry'),
    async = require('async'),
    minimatch = require('minimatch'),
    parseLinks = require('parse-link-header'),
    extend = require('extend'),
    stats = require('./lib/stats'),
    sort = require('./lib/sort');

module.exports = {
  version: require('./package.json').version,
  client: client,
  stats: stats
};

function client() {
  var client = octonode.client.apply(octonode, arguments),
      get = client.get.bind(client);

  client.get = curry(function(uri, params, done) {
    var data = expand(uri, params);
    return get(data.uri, data.params, done);
  });

  client.getAll = curry(function(uri, params, done) {
    params.page = 1;
    var data = [],
        last = '?',
        next = function() {
          log('get: %s (page %d of %s)', uri, params.page, last, JSON.stringify(params));
          return client.get(uri, params, handler);
        },
        handler = function(error, status, page, headers) {
          if (error) {
            return done(error);
          } else if (!Array.isArray(page)) {
            return done('expected array; got ' + typeof page);
          }

          if (!page.length) {
            log('nothing in this page:', params.page);
            return done(null, data);
          }
          data = data.concat(page);
          var links = parseLinks(headers.link);
          if (links && links.next) {
            last = links.last ? links.last.page : '?';
            params.page = +links.next.page;
            return next();
          } else {
            return done(null, data);
          }
        };

    return next();
  });

  client.matchRepos = curry(function(repos, options, done) {
    var include = options.include;

    if (typeof repos === 'string') {
      var path = repos;
      if (path.charAt(0) === '/') {
        path = path.substr(1);
      }
      var bits = path.split('/');
      switch (bits.length) {
        case 1:
          path = 'users/' + path;
          break;
        case 2:
          break;
        case 3:
          path = bits.slice(0, -1).join('/');
          include = bits[2];
          break;
      }
      repos = client.getAll('/' + path + '/repos', {per_page: 100});
    }

    var test = (include && include !== '*')
      ? function(repo) {
        log("minimatch('%s', '%s')", repo.name, include);
        return minimatch(repo.name, include);
      }
      : function() { return true; };

    if (options.exclude) {
      var exclude = options.exclude,
          _test = test;
      test = function(repo) {
        return _test(repo) && !minimatch(repo.name, exclude);
      };
    }

    switch (typeof repos) {
      case 'function':
        return async.waterfall([
          repos,
          function (repos, next) {
            log('matching %d repos against', repos.length, options);
            repos.sort(function(a, b) {
              return sort.ascending(a.name, b.name);
            });
            var filtered = repos.filter(test);
            log('got %d matches: %s', filtered.length, filtered.map(function(d) { return d.name; }).join(', '));
            next(null, filtered);
          }
        ], done);

      case 'object':
        return done(null, repos.filter(test));
    }
  });

  client.stats = stats;

  client.aggregate = curry(function(type, options, args, repos, done) {
    var agg = client.stats[type];
    if (!agg) {
      return done('no such aggregate statistic: ' + type);
    }
    var limit = 10; // +options.parallel || 1;
    log('getting %s stats for %d repo(s)...', type, repos.length);

    async.mapLimit(repos, limit, function(repo, next) {
      log('getting %s stats for %s/%s', type, repo.owner.login, repo.name);
      agg.fetch(client, repo, args, function(error, stats) {
        if (error) return done(error);
        if (!repo.stats) repo.stats = {};
        repo.stats[type] = stats;
        next(null, repo);
      });
    }, function(error) {
      if (error) return done(error);
      var reduce = client.stats[type].reduce;
      return done(null, reduce ? reduce(repos, args) : repos);
    });
  });

  client.debug = false;

  function log() {
    if (!client.debug) return;
    console.warn.apply(console, arguments);
  }

  client.log = log;

  return client;
}

function expand(uri, params) {
  params = extend({}, params);
  for (var key in params) {
    if (!params[key]) delete params[key];
  }
  uri = uri.replace(/:(\w+)/g, function(_, key) {
    var value = params[key];
    delete params[key];
    return value;
  });
  return {uri: uri, params: params};
}
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		if (options && options.progressInterval) {
			console.log('custom progress interval:', options.progressInterval);
			this.progressInterval = options.progressInterval;
		} else {
			this.progressInterval = 100;
		}

		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
		this.overridePosition = position*1000000;
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		return new Promise( (resolve, reject) => {
			if (typeof(this.overridePosition) == 'number') {
				resolve(this.overridePosition);
				this.overridePosition = null;
			} else {
				exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
					if (error) reject();
					let position = parseInt(stdout) / 1000; // microseconds to milliseconds
					resolve(position);
				});
			}
		});
	}

	getIsPlaying () {
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) reject();
				if (stdout.indexOf('Playing') > -1) {
					resolve(true);
				} else {
					resolve(false);
				}
			});
		});
	}

	getDuration () {
		return new Promise( (resolve, reject) => {
			if (this.duration) {
				resolve(this.duration);
			} else {
				exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
					if (error) reject();

					let duration = parseInt(stdout) / 1000; // microseconds to milliseconds
					resolve(duration);
					this.duration = duration; // cache last known duration
				});
			}
		});
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			this.getIsPlaying()
				 .then( (isPlaying) => {
					 if (isPlaying) {
						 this.getCurrentPosition()
						 	.then( (position) => {
								this.getDuration()
									.then( (duration) => {
										callback({ position: position, duration: duration });
									});
							});
					 } else {
						 callback({ 'playing': false });
					 }
				 })
				 .catch( () => {
					 console.error('error getting isPlaying status');
					 callback({ 'status': 'error', 'playing': false });
				 });
		}, this.progressInterval);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<commit_msg>Default to 1000ms for progress interval<commit_after>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		if (options && options.progressInterval) {
			console.log('custom progress interval:', options.progressInterval);
			this.progressInterval = options.progressInterval;
		} else {
			this.progressInterval = 1000;
		}

		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
		this.overridePosition = position*1000000;
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		return new Promise( (resolve, reject) => {
			if (typeof(this.overridePosition) == 'number') {
				resolve(this.overridePosition);
				this.overridePosition = null;
			} else {
				exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
					if (error) reject();
					let position = parseInt(stdout) / 1000; // microseconds to milliseconds
					resolve(position);
				});
			}
		});
	}

	getIsPlaying () {
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) reject();
				if (stdout.indexOf('Playing') > -1) {
					resolve(true);
				} else {
					resolve(false);
				}
			});
		});
	}

	getDuration () {
		return new Promise( (resolve, reject) => {
			if (this.duration) {
				resolve(this.duration);
			} else {
				exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
					if (error) reject();

					let duration = parseInt(stdout) / 1000; // microseconds to milliseconds
					resolve(duration);
					this.duration = duration; // cache last known duration
				});
			}
		});
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			this.getIsPlaying()
				 .then( (isPlaying) => {
					 if (isPlaying) {
						 this.getCurrentPosition()
						 	.then( (position) => {
								this.getDuration()
									.then( (duration) => {
										callback({ position: position, duration: duration });
									});
							});
					 } else {
						 callback({ 'playing': false });
					 }
				 })
				 .catch( () => {
					 console.error('error getting isPlaying status');
					 callback({ 'status': 'error', 'playing': false });
				 });
		}, this.progressInterval);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<|endoftext|>


<commit_before>require('es6-set/implement');

var findIndex = require('find-index');

function getSelectedValue(options) {
  return options.values[
    findIndex(options.radioNodes, function(node) {
      return node.checked;
    })
  ];
}

module.exports = function (args) {
  var view = args.view;
  var model = args.model;
  // TODO: Support `args.logger`.

  var checkedOptionSnapshot;
  function updateCheckedOption(newValue) {
    if (newValue !== checkedOptionSnapshot) {
      model.patches.emit('apply', {value: newValue});
    }

    checkedOptionSnapshot = newValue;
  }

  function updateFromOptions(options) {
    return updateCheckedOption(getSelectedValue(options));
  }

  // Rescan options and emit a patch if necessary:
  // * when options are added, removed or changed,
  var optionsSnapshot = {};
  view.options.when('update', function(options) {
    updateFromOptions(options);
    optionsSnapshot = options;
  });

  // * upon a `change` event on the container – when something has been
  // selected.
  view.containerElement.on('change', function() {
    updateFromOptions(optionsSnapshot);
  });

  // Update the selected option when the `value` attribute has been updated.
  model.updates.when('value', function(data) {
    // TODO: Can we assume that event messages are safe?

    // Fail silently:
    // * if there are no options loaded yet.
    if (!optionsSnapshot.radioNodes || !optionsSnapshot.values) return;

    // * if there is no option provided for the value.
    var option = optionsSnapshot.radioNodes[
      optionsSnapshot.values.indexOf(data.attributes.value)
    ];
    if (!option) return;
      // TODO: Should we really fail silently?

    // Else check the respective option.
    option.checked = true;
  });
};
<commit_msg>Implement the new behavior of the “value” plugin [#6798]<commit_after>require('es6-set/implement');

var findIndex = require('find-index');

function getSelectedValue(options) {
  return options.values[
    findIndex(options.radioNodes, function(node) {
      return node.checked;
    })
  ];
}

module.exports = function (args) {
  var view = args.view;
  var model = args.model;
  // TODO: Support `args.logger`.

  var checkedOptionSnapshot;
  function updateCheckedOption(newValue) {
    if (newValue !== checkedOptionSnapshot) {
      model.patches.emit('apply', {value: newValue});
    }

    checkedOptionSnapshot = newValue;
  }

  function updateFromOptions(options) {
    return updateCheckedOption(getSelectedValue(options));
  }

  // Rescan options and emit a patch if necessary:
  // * when options are added, removed or changed,
  var optionsSnapshot = {};
  view.options.when('update', function(options) {
    updateFromOptions(options);
    optionsSnapshot = options;
  });

  // * upon a `change` event on the container – when something has been
  // selected.
  view.containerElement.on('change', function() {
    updateFromOptions(optionsSnapshot);
  });

  // Update the selected option when the `value` attribute has been updated.
  model.updates.when('value', function(state) {
    // TODO: Can we assume that event messages are safe?
    view.selection.emit('update', {
      newValue: (state.attributes.value || null)
    });
  });
};
<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var superagent = require('superagent');
var qs = require('qs');
var extend = require('extend');
var methods = [
    "checkout",
    "connect",
    "copy",
    "delete",
    "get",
    "head",
    "lock",
    "m-search",
    "merge",
    "mkactivity",
    "mkcol",
    "move",
    "notify",
    "options",
    "patch",
    "post",
    "propfind",
    "proppatch",
    "purge",
    "put",
    "report",
    "search",
    "subscribe",
    "trace",
    "unlock",
    "unsubscribe"
].map(function (method) {
    return method.toUpperCase();
});

exports = module.exports = promisingagent;
exports.Promise = Promise;
exports.superagent = superagent;
var Request = promisingagent.Request = superagent.Request;
exports.querySerializer = qs.stringify;
var serialize = exports.bodySerializer = superagent.serialize;
serialize['application/x-www-form-urlencoded'] = qs.stringify;

Request.prototype.end = (function(origEnd) {
    return function (fn) {
        var self = this;
        this.promise = this.promise || new Promise(function (resolve, reject) {
            origEnd.call(self, function (err, response) {
                if (err && !err.status) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
        if (typeof fn === 'function') {
            this.promise.nodeify(fn);
        }
        return this.promise;
    };
}(Request.prototype.end));

// delegate promise methods so you can do something like promisingagent(url).then(...)
// also delegate some handy utility methods from bluebird
'then spread catch caught finnaly lastly bind tap call get return throw reflect'.split(' ').forEach(function (m) {
    Request.prototype[m] = function () {
        var promise = this.promise || this.end();
        return promise[m].apply(promise, arguments);
    }
});

function promisingagent() {
    var method, url, query;
    var args = Array.prototype.slice.call(arguments);
    var strs = [];
    for (var i = 0; i < args.length;) {
        if (typeof args[i] === 'string') {
            var part = args.splice(i, 1)[0]
            if (!method && methods.indexOf(part) > -1) {
                method = part;
            } else {
                strs.push(part);
            }
        } else {
            i += 1;
        }
    }
    url = strs.join('');
    var opts = extend.apply(null, [true, method ? {method: method} : {}].concat(args));
    method = (opts.method||'').toUpperCase() || 'GET';
    url = url || opts.url;
    if (opts.query) {
        query = exports.querySerializer(opts.query);
        url += ~url.indexOf('?')
            ? '&' + query
            : '?' + query;
    }
    var request = new Request(method, url);
    if (method !== 'GET' && method !== 'HEAD') {
        request.type(opts.type || 'form');
    }
    if (opts.body) {
        request.send(opts.body);
    }
    if (opts.headers) {
        Object.keys(opts.headers).forEach(function (key) {
            request.set(key.toLowerCase(), opts.headers[key]);
        });
    }
    return request;
}

function addMethods(fn) {
    methods.forEach(function (method) {
        var ml = method.toLowerCase();
        fn[method] = fn[ml] = fn.bind(null, method);
        if (method === 'DELETE') {
            fn.del = fn.DEL = fn['delete'];
        }
    });
}
addMethods(promisingagent);

promisingagent.extend = function extend () {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(null);
    var fn = this.bind.apply(this, args);
    addMethods(fn);
    fn.extend = promisingagent.extend;
    return fn;
};
<commit_msg>headers value could be function<commit_after>'use strict';

var Promise = require('bluebird');
var superagent = require('superagent');
var qs = require('qs');
var extend = require('extend');
var methods = [
    "checkout",
    "connect",
    "copy",
    "delete",
    "get",
    "head",
    "lock",
    "m-search",
    "merge",
    "mkactivity",
    "mkcol",
    "move",
    "notify",
    "options",
    "patch",
    "post",
    "propfind",
    "proppatch",
    "purge",
    "put",
    "report",
    "search",
    "subscribe",
    "trace",
    "unlock",
    "unsubscribe"
].map(function (method) {
    return method.toUpperCase();
});

exports = module.exports = promisingagent;
exports.Promise = Promise;
exports.superagent = superagent;
var Request = promisingagent.Request = superagent.Request;
exports.querySerializer = qs.stringify;
var serialize = exports.bodySerializer = superagent.serialize;
serialize['application/x-www-form-urlencoded'] = qs.stringify;

Request.prototype.end = (function(origEnd) {
    return function (fn) {
        var self = this;
        this.promise = this.promise || new Promise(function (resolve, reject) {
            origEnd.call(self, function (err, response) {
                if (err && !err.status) {
                    reject(err);
                } else {
                    resolve(response);
                }
            });
        });
        if (typeof fn === 'function') {
            this.promise.nodeify(fn);
        }
        return this.promise;
    };
}(Request.prototype.end));

// delegate promise methods so you can do something like promisingagent(url).then(...)
// also delegate some handy utility methods from bluebird
'then spread catch caught finnaly lastly bind tap call get return throw reflect'.split(' ').forEach(function (m) {
    Request.prototype[m] = function () {
        var promise = this.promise || this.end();
        return promise[m].apply(promise, arguments);
    }
});

function promisingagent() {
    var method, url, query;
    var args = Array.prototype.slice.call(arguments);
    var strs = [];
    for (var i = 0; i < args.length;) {
        if (typeof args[i] === 'string') {
            var part = args.splice(i, 1)[0]
            if (!method && methods.indexOf(part) > -1) {
                method = part;
            } else {
                strs.push(part);
            }
        } else {
            i += 1;
        }
    }
    url = strs.join('');
    var opts = extend.apply(null, [true, method ? {method: method} : {}].concat(args));
    method = (opts.method||'').toUpperCase() || 'GET';
    url = url || opts.url;
    if (opts.query) {
        query = exports.querySerializer(opts.query);
        url += ~url.indexOf('?')
            ? '&' + query
            : '?' + query;
    }
    var request = new Request(method, url);
    if (method !== 'GET' && method !== 'HEAD') {
        request.type(opts.type || 'form');
    }
    if (opts.body) {
        request.send(opts.body);
    }
    if (opts.headers) {
        Object.keys(opts.headers).forEach(function (key) {
            var v = opts.headers[key];
            if (typeof v === 'function') {
                v = v.call(request);
            }
            if (typeof v === 'string') {
                request.set(key.toLowerCase(), v);
            }
        });
    }
    return request;
}

function addMethods(fn) {
    methods.forEach(function (method) {
        var ml = method.toLowerCase();
        fn[method] = fn[ml] = fn.bind(null, method);
        if (method === 'DELETE') {
            fn.del = fn.DEL = fn['delete'];
        }
    });
}
addMethods(promisingagent);

promisingagent.extend = function extend () {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(null);
    var fn = this.bind.apply(this, args);
    addMethods(fn);
    fn.extend = promisingagent.extend;
    return fn;
};
<|endoftext|>


<commit_before>const express = require('express');
const admin = require("firebase-admin"),
    serviceAccount = require("./private/serviceAccountKey.json"),
    path = require('path'),
    bodyParser = require('body-parser');
const app = express();

function defaultContentTypeMiddleware(req, res, next) {
    req.headers['content-type'] = 'application/json';
    next();
}

app.use(defaultContentTypeMiddleware);
app.use(bodyParser.json());

app.set('port', (process.env.PORT || 4444));

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://fcmpush-31f7a.firebaseio.com"
});

const dataBaseRef = admin.database().ref("fireheat/");

app.get('/serverData', function (req, res) {
    console.log(req.query);
    var brandID = "" + req.query.brandID;
    var device = "" + req.query.device;
    var domain = encodeURIComponent(req.query.domain).replace(/[.$\[\]\/#]/g, ',');
    var path = encodeURIComponent(req.query.path).replace(/[.$\[\]\/#]/g, ',');
    if (brandID && domain && path && device) {
        dataBaseRef.child(brandID + "/" + domain + "/" + path + "/" + device).once('value').then(function (dataSnap) {
            var data = dataSnap.val();
            if (data) {
                res.status(200).json(data);
            } else {
                res.status(204).end();
            }
        })
    } else {
        res.status(204).end();
    }

})

app.get('/getUrl', function (req, res) {
    var brandID = "" + req.query.brandID;
    if (brandID) {
        dataBaseRef.child(brandID).child('url').once('value').then(function (dataSnap) {
            var data = dataSnap.val();
            if (data) {
                res.status(200).json(data);
            } else {
                res.status(204).end();
            }
        })
    } else {
        res.status(204).end();
    }
})

app.get('/view/:name', function (req, res) {

    var options = {
        root: __dirname + '/',
        headers: {
            'x-timestamp': Date.now(),
            'x-sent': true
        }
    };

    var fileName = req.params.name;
    res.sendFile(fileName, options, function (err) {
        if (err) {
            console.log(err);
        } else {
            console.log('Sent:', fileName);
        }
    });
});

app.get('/', function (req, res) {
    console.log('hahah');
    res.send('under development');
})

app.post('/', function (req, res) {
    if (typeof req.body === 'object') {
        var brandId = "" + req.body.brandID;
        var domain = req.body.domain.replace(/[.$\[\]\/#]/g, ',');
        var path = req.body.path.replace(/[.$\[\]\/#]/g, ',');
        var device;
        var dataToPush = {
            activeTime: req.body.activeTime,
            pageheight: req.body.pageheight,
            pagewidth: req.body.pagewidth,
            data: JSON.stringify(req.body.points)
        }
    }

    if (req.body.pagewidth < 576) {
        device = 'mobile';
    }
    if (req.body.pagewidth > 576 && req.body.pagewidth < 992) {
        device = 'tablet';
    }
    if (req.body.pagewidth > 992) {
        device = 'desktop';
    }
    if (brandId && domain && path) {
        dataBaseRef.child(brandId).child(domain).child(path).child(device).push(dataToPush).then(function (res) {
            console.log('data saved');
        }).catch(function (err) {
            console.log(err);
        })
        dataBaseRef.child(brandId).child('url').child(domain).child(path).update({
            a: 1
        });
    }
    res.set({
        'Access-Control-Allow-Origin':'*'
    });
    res.send('under development');
});

app.listen(app.get('port'), function () {
    console.log('app at port:- ' + app.get('port'));
});<commit_msg> added Access-Control-Allow-Origin::'*' for post request to '/'<commit_after>const express = require('express');
const admin = require("firebase-admin"),
    serviceAccount = require("./private/serviceAccountKey.json"),
    path = require('path'),
    bodyParser = require('body-parser');
const app = express();

function defaultContentTypeMiddleware(req, res, next) {
    req.headers['content-type'] = 'application/json';
    next();
}

app.use(defaultContentTypeMiddleware);
app.use(bodyParser.json());

app.set('port', (process.env.PORT || 4444));

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://fcmpush-31f7a.firebaseio.com"
});

const dataBaseRef = admin.database().ref("fireheat/");

app.get('/serverData', function (req, res) {
    console.log(req.query);
    var brandID = "" + req.query.brandID;
    var device = "" + req.query.device;
    var domain = encodeURIComponent(req.query.domain).replace(/[.$\[\]\/#]/g, ',');
    var path = encodeURIComponent(req.query.path).replace(/[.$\[\]\/#]/g, ',');
    if (brandID && domain && path && device) {
        dataBaseRef.child(brandID + "/" + domain + "/" + path + "/" + device).once('value').then(function (dataSnap) {
            var data = dataSnap.val();
            if (data) {
                res.status(200).json(data);
            } else {
                res.status(204).end();
            }
        })
    } else {
        res.status(204).end();
    }

})

app.get('/getUrl', function (req, res) {
    var brandID = "" + req.query.brandID;
    if (brandID) {
        dataBaseRef.child(brandID).child('url').once('value').then(function (dataSnap) {
            var data = dataSnap.val();
            if (data) {
                res.status(200).json(data);
            } else {
                res.status(204).end();
            }
        })
    } else {
        res.status(204).end();
    }
})

app.get('/view/:name', function (req, res) {

    var options = {
        root: __dirname + '/',
        headers: {
            'x-timestamp': Date.now(),
            'x-sent': true
        }
    };

    var fileName = req.params.name;
    res.sendFile(fileName, options, function (err) {
        if (err) {
            console.log(err);
        } else {
            console.log('Sent:', fileName);
        }
    });
});

app.get('/', function (req, res) {
    console.log('hahah');
    res.send('under development');
})

app.post('/', function (req, res) {
    if (typeof req.body === 'object') {
        var brandId = "" + req.body.brandID;
        var domain = req.body.domain.replace(/[.$\[\]\/#]/g, ',');
        var path = req.body.path.replace(/[.$\[\]\/#]/g, ',');
        var device;
        var dataToPush = {
            activeTime: req.body.activeTime,
            pageheight: req.body.pageheight,
            pagewidth: req.body.pagewidth,
            data: JSON.stringify(req.body.points)
        }
    }

    if (req.body.pagewidth < 576) {
        device = 'mobile';
    }
    if (req.body.pagewidth > 576 && req.body.pagewidth < 992) {
        device = 'tablet';
    }
    if (req.body.pagewidth > 992) {
        device = 'desktop';
    }
    if (brandId && domain && path) {
        dataBaseRef.child(brandId).child(domain).child(path).child(device).push(dataToPush).then(function (res) {
            console.log('data saved');
        }).catch(function (err) {
            console.log(err);
        })
        dataBaseRef.child(brandId).child('url').child(domain).child(path).update({
            a: 1
        });
    }
    res.set({
        'Access-Control-Allow-Origin': '*'
    });
    res.send('under development');
});

app.listen(app.get('port'), function () {
    console.log('app at port:- ' + app.get('port'));
});<|endoftext|>


<commit_before>export { default as List } from './components/list/';
export { default as Button } from './components/button/';
export { default as Flex } from './components/flex/';
export { default as WhiteSpace } from './components/white-space/';
export { default as WingBlank } from './components/wing-blank/';
<commit_msg>add card & tag to index.js<commit_after>export { default as Button } from './components/button/';
export { default as Card } from './components/card/';
export { default as List } from './components/list/';
export { default as Flex } from './components/flex/';
export { default as Tag } from './components/tag/';
export { default as WhiteSpace } from './components/white-space/';
export { default as WingBlank } from './components/wing-blank/';
<|endoftext|>