<commit_before>var Docker = require('dockerode'),
    validator = require('validator'),
    fs = require('fs'),
    path = require('path'),
    utils = require('./utils');

var invalidDockerEndpoint   = new Error('Please specify a valid Docker endpoint.'),
    invalidDockerRepository = new Error('Please specify a valid Docker repository.'),
    invalidDockerCertsPath  = new Error('Please specify a valid Docker certs path.'),
    missingKeyCertificate   = new Error('key.pem is missing.'),
    missingCertCertificate  = new Error('cert.pem is missing.'),
    missingCaCertificate    = new Error('ca.pem is missing.'),
    dockerAPINotResponding  = new Error('Docker API not responding.');

function validate(args, callback) {
    if (!validator.isURL(args.endpoint, { protocols: ['http', 'https'] })) {
        return callback(null, invalidDockerEndpoint);
    }
    if (!validator.isAlphanumeric(args.repository)) {
        return callback(null, invalidDockerRepository);
    }

    var certs = null;

    if (validator.isURL(args.endpoint, { protocols: ['https'] })) {
        if (!fs.existsSync(args.certs)) {
            return callback(null, invalidDockerCertsPath);
        }
        certs = this.getCertsFilePath(args.certs);

        if (!fs.existsSync(certs.key)) {
            return callback(null, missingKeyCertificate);
        }
        if (!fs.existsSync(certs.cert)) {
            return callback(null, missingCertCertificate);
        }
        if (!fs.existsSync(certs.ca)) {
            return callback(null, missingCaCertificate);
        }
    }

    var client = this.getClient(args.endpoint, args.certs, args.repository);

    client.ping(function (err) {
        if (err) return callback(null, dockerAPINotResponding);
        callback(client, null);
    });
}

function getClient(endpoint, certs, repository) {
    var dockerHost = utils.formatDockerHost(endpoint, certs),
        client     = new Docker(dockerHost);

    client.repository = repository;
    return client;
}

function getCertsFilePath(certsPath) {
    return {
        key: path.resolve(certsPath, 'key.pem'),
        cert: path.resolve(certsPath, 'cert.pem'),
        ca: path.resolve(certsPath, 'ca.pem')
    };
}

module.exports = {
    invalidDockerEndpoint: invalidDockerEndpoint,
    invalidDockerRepository: invalidDockerRepository,
    invalidDockerCertsPath: invalidDockerCertsPath,
    missingKeyCertificate: missingKeyCertificate,
    missingCertCertificate: missingCertCertificate,
    missingCaCertificate: missingCaCertificate,
    dockerAPINotResponding: dockerAPINotResponding,
    validate: validate,
    getClient: getClient,
    getCertsFilePath: getCertsFilePath
}
<commit_msg>rename docker error not responding<commit_after>var Docker = require('dockerode'),
    validator = require('validator'),
    fs = require('fs'),
    path = require('path'),
    utils = require('./utils');

var invalidDockerEndpoint   = new Error('Please specify a valid Docker endpoint.'),
    invalidDockerRepository = new Error('Please specify a valid Docker repository.'),
    invalidDockerCertsPath  = new Error('Please specify a valid Docker certs path.'),
    missingKeyCertificate   = new Error('key.pem is missing.'),
    missingCertCertificate  = new Error('cert.pem is missing.'),
    missingCaCertificate    = new Error('ca.pem is missing.'),
    notResponding           = new Error('Docker API not responding.');

function validate(args, callback) {
    if (!validator.isURL(args.endpoint, { protocols: ['http', 'https'] })) {
        return callback(null, invalidDockerEndpoint);
    }
    if (!validator.isAlphanumeric(args.repository)) {
        return callback(null, invalidDockerRepository);
    }

    var certs = null;

    if (validator.isURL(args.endpoint, { protocols: ['https'] })) {
        if (!fs.existsSync(args.certs)) {
            return callback(null, invalidDockerCertsPath);
        }
        certs = this.getCertsFilePath(args.certs);

        if (!fs.existsSync(certs.key)) {
            return callback(null, missingKeyCertificate);
        }
        if (!fs.existsSync(certs.cert)) {
            return callback(null, missingCertCertificate);
        }
        if (!fs.existsSync(certs.ca)) {
            return callback(null, missingCaCertificate);
        }
    }

    var client = this.getClient(args.endpoint, args.certs, args.repository);

    client.ping(function (err) {
        if (err) return callback(null, notResponding);
        callback(client, null);
    });
}

function getClient(endpoint, certs, repository) {
    var dockerHost = utils.formatDockerHost(endpoint, certs),
        client     = new Docker(dockerHost);

    client.repository = repository;
    return client;
}

function getCertsFilePath(certsPath) {
    return {
        key: path.resolve(certsPath, 'key.pem'),
        cert: path.resolve(certsPath, 'cert.pem'),
        ca: path.resolve(certsPath, 'ca.pem')
    };
}

module.exports = {
    invalidDockerEndpoint: invalidDockerEndpoint,
    invalidDockerRepository: invalidDockerRepository,
    invalidDockerCertsPath: invalidDockerCertsPath,
    missingKeyCertificate: missingKeyCertificate,
    missingCertCertificate: missingCertCertificate,
    missingCaCertificate: missingCaCertificate,
    notResponding: notResponding,
    validate: validate,
    getClient: getClient,
    getCertsFilePath: getCertsFilePath
}
<|endoftext|>


<commit_before>/* eslint max-len: 0, import/no-dynamic-require: 0, global-require: 0 */
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const importCwd = require('import-cwd');
const debug = require('debug');
const globby = require('globby');
const minimatch = require('minimatch');

const isCI = !!process.env.CI;

const pkg = importCwd('./package.json');
const findPkgs = g => globby.sync(`${g}/package.json`);
const reducePkgs = (acc, curr) => acc.concat(curr.map(c => c.slice(0, -13)));
const lerna = importCwd.silent('./lerna.json');
const workspaces = (pkg.workspaces || []).map(findPkgs).reduce(reducePkgs, []);
const lernaPackages = ((lerna && lerna.packages) || [])
  .map(findPkgs)
  .reduce(reducePkgs, []);
const packagesPath = [...workspaces, ...lernaPackages];
let packages = [];
const packagesMap = new Map();
packagesPath.forEach((root) => {
  const { name } = importCwd(`./${root}/package.json`);
  packages = [...packages, name];
  packagesMap.set(name, root);
});

const DEFAULT_TEST_EXT_PATTERN = '*.{spec,test}.{js,jsx,ts,tsx}';
const DEFAULT_TEST_GLOB_PATTERN = `**/${DEFAULT_TEST_EXT_PATTERN}`;

const DEFAULT_SRC_EXT_PATTERN = '*.{js,ts}';
const DEFAULT_SRC_GLOB_PATTERN = `**/${DEFAULT_SRC_EXT_PATTERN}`;
const DEFAULT_SRC_EXCLUDE_PATTERN = [
  '**/coverage/**',
  '**/scripts/**',
  '**/docs/**',
  '**/tools/**',
  '**/__*__/**',
  '**/test/**',
  '**/mocks/**',
  '**/dist/**',
  `**/${DEFAULT_TEST_EXT_PATTERN}`,
  '**/*.config.*',
];
const TEST_GLOB = [
  ...(packagesPath.length
    ? packagesPath.map(p => `${p}/${DEFAULT_TEST_GLOB_PATTERN}`)
    : [DEFAULT_TEST_GLOB_PATTERN]),
  '!**/node_modules/**',
  '!./node_modules/**',
];
const SRC_GLOB = [
  ...(packagesPath.length
    ? packagesPath.map(p => `${p}/${DEFAULT_SRC_GLOB_PATTERN}`)
    : [DEFAULT_SRC_GLOB_PATTERN]),
  '!**/node_modules/**',
  '!./node_modules/**',
];
const WATCH_GLOB = [...TEST_GLOB, ...SRC_GLOB];

const DEFAULT_TRANSFORM_EXCLUDE_PATTERN = [
  '**/node_modules/**',
  './node_modules/**',
  '**/coverage/**',
  '**/external/**',
  '**/autogenerated/**',
  '**/*.{html,css,json,txt,ttf,woff,svg,ico}',
  '**/*require*.js',
  '**/*sinon*.js',
  '**/*chai*.js',
];
const DEFAULT_INSTRUMENT_EXCLUDE_PATTERN = [
  ...DEFAULT_TRANSFORM_EXCLUDE_PATTERN,
  DEFAULT_TEST_EXT_PATTERN,
  DEFAULT_TEST_GLOB_PATTERN,
];

const utils = {
  packages,
  packagesPath,
  packagesMap,
  workspaces,
  lernaPackages,
  DEFAULT_TEST_EXT_PATTERN,
  DEFAULT_TEST_GLOB_PATTERN,
  DEFAULT_SRC_GLOB_PATTERN,
  DEFAULT_SRC_EXCLUDE_PATTERN,
  TEST_GLOB,
  SRC_GLOB,
  WATCH_GLOB,
  DEFAULT_TRANSFORM_EXCLUDE_PATTERN,
  DEFAULT_INSTRUMENT_EXCLUDE_PATTERN,
  isSourceMap(f) {
    return !fs.existsSync(f) && f.endsWith('.map');
  },
  isTypescript(f) {
    return f.endsWith('.ts');
  },
  getExt(f) {
    const parts = f.split('.');
    return parts.pop();
  },
  getPathWithExt(f, ext) {
    const parts = f.split('.');
    parts.pop();
    return `${parts.join('.')}.${ext}`;
  },
  ensureFilePath(js) {
    const exists = fs.existsSync(js);
    if (!exists && js.endsWith('.js')) {
      const ts = utils.getPathWithExt(js, 'ts');
      if (!fs.existsSync(ts)) {
        return '';
      }
      return ts;
    }
    return exists ? js : '';
  },
  clearLine() {
    if (isCI) {
      return;
    }
    readline.clearLine(process.stderr, 0);
    readline.cursorTo(process.stderr, 0, null);
  },
  writeLine(prefix, msg) {
    if (isCI) {
      return;
    }
    this.clearLine();
    process.stderr.write(
      `${prefix} ${msg.length > 60 ? '...' : ''}${msg.slice(-59)}`,
    );
  },
  safeGetModule(name) {
    let found = importCwd.silent(name);
    if (!found) {
      try {
        found = require(name);
      } catch (err) {
        found = null;
      }
    }
    return found;
  },
  coerceBabel(opt) {
    if (opt.enable && opt.core && typeof opt.core === 'string') {
      opt.babel = importCwd(opt.core);
    } else if (opt.enable && !opt.core) {
      let core = utils.safeGetModule('@babel/core');
      if (!core) {
        core = utils.safeGetModule('babel-core');
        if (!core) {
          throw new Error('Can not get babel core module');
        }
      }
      opt.babel = core;
    }
    if (opt.enable && typeof opt.babelPluginIstanbul === 'string') {
      const babelPluginIstanbul = utils.safeGetModule(opt.babelPluginIstanbul);
      opt.babelPluginIstanbul = babelPluginIstanbul
        ? babelPluginIstanbul.default
        : null;
    }
    if (opt.enable && typeof opt.typescript === 'string') {
      opt.typescript = utils.safeGetModule(opt.typescript);
    }
    return opt;
  },
  getCurrentFilenameStackInfo(testFiles) {
    // Magically figure out the current test from the stack trace (callsites not working with sourcemaps)
    const s = new Error().stack
      .split('\n')
      .slice(1)
      .map(c => c.split(/\(([^)]+)\)/)[1])
      .filter(c => c !== undefined)
      .map((c) => {
        const parts = c.split(':');
        const columnno = parts.pop();
        const lineno = parts.pop();
        const filename = path.resolve(parts.join(':'));
        return [filename, lineno, columnno, c];
      })
      .filter(([filename]) => testFiles.indexOf(filename) !== -1);
    if (!s.length) {
      throw new Error('Can not find test file');
    }
    return s.shift();
  },
  safeDeleteCache(f) {
    if (require.cache[f]) {
      delete require.cache[f];
    }
    if (require.cache[f] && require.cache[f].parent) {
      let i = require.cache[f].parent.children.length;
      while (i--) {
        if (require.cache[f].parent.children[i].id === f) {
          require.cache[f].parent.children.splice(i, 1);
        }
      }
    }
  },
  safeRequireCache(f) {
    try {
      require(f);
      return require.cache[f];
    } catch (_) {
      // console.error(_)
    }
    return { children: [] };
  },
  matchDependency(found, testName) {
    let use = found;
    if (found.length > 1) {
      const matchName = found.filter(
        id => path
          .basename(id)
          .split('.')
          .shift() === testName,
      );
      if (matchName.length === 1) {
        use = matchName;
      } else {
        use = found.splice(0, 1);
      }
    }
    return use;
  },
  getDependencies(files, file) {
    const name = path
      .basename(file)
      .split('.')
      .shift();
    const mod = this.safeRequireCache(file);
    const found = mod.children
      .filter(m => files.indexOf(m.id) !== -1)
      .map(m => m.id);
    return this.matchDependency(found, name);
  },
  getAllDependencies(files, file) {
    let all = [];
    const deps = this.getDependencies(files, file);
    const walk = (currentDeps) => {
      all = all.concat(currentDeps);
      currentDeps.forEach((d) => {
        const childDeps = this.getDependencies(files, d);
        walk(childDeps, files, d);
      });
    };
    walk(deps, files, file);
    return all;
  },
  createDebug(p) {
    return debug(`@after-work.js:${p}`);
  },
  filter(arr, initialValue) {
    return arr.reduce(
      (acc, curr) => acc.filter(file => minimatch(file, curr)),
      initialValue,
    );
  },
  isMatchingExtPattern(filePath, extPattern) {
    const base = path.basename(filePath);
    return minimatch(base, extPattern);
  },
  isTestFile(filePath, { testExt = DEFAULT_TEST_EXT_PATTERN }) {
    return utils.isMatchingExtPattern(filePath, testExt);
  },
  isSrcFile(
    filePath,
    { testExt = DEFAULT_TEST_EXT_PATTERN, srcExt = DEFAULT_SRC_EXT_PATTERN },
  ) {
    return (
      !utils.isTestFile(filePath, testExt)
      && utils.isMatchingExtPattern(filePath, srcExt)
    );
  },
};

module.exports = utils;
<commit_msg>fix: exclude `scripts` by default (#446)<commit_after>/* eslint max-len: 0, import/no-dynamic-require: 0, global-require: 0 */
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const importCwd = require('import-cwd');
const debug = require('debug');
const globby = require('globby');
const minimatch = require('minimatch');

const isCI = !!process.env.CI;

const pkg = importCwd('./package.json');
const findPkgs = g => globby.sync(`${g}/package.json`);
const reducePkgs = (acc, curr) => acc.concat(curr.map(c => c.slice(0, -13)));
const lerna = importCwd.silent('./lerna.json');
const workspaces = (pkg.workspaces || []).map(findPkgs).reduce(reducePkgs, []);
const lernaPackages = ((lerna && lerna.packages) || [])
  .map(findPkgs)
  .reduce(reducePkgs, []);
const packagesPath = [...workspaces, ...lernaPackages];
let packages = [];
const packagesMap = new Map();
packagesPath.forEach((root) => {
  const { name } = importCwd(`./${root}/package.json`);
  packages = [...packages, name];
  packagesMap.set(name, root);
});

const DEFAULT_TEST_EXT_PATTERN = '*.{spec,test}.{js,jsx,ts,tsx}';
const DEFAULT_TEST_GLOB_PATTERN = `**/${DEFAULT_TEST_EXT_PATTERN}`;

const DEFAULT_SRC_EXT_PATTERN = '*.{js,ts}';
const DEFAULT_SRC_GLOB_PATTERN = `**/${DEFAULT_SRC_EXT_PATTERN}`;
const DEFAULT_SRC_EXCLUDE_PATTERN = [
  '**/coverage/**',
  '**/scripts/**',
  '**/docs/**',
  '**/tools/**',
  '**/__*__/**',
  '**/test/**',
  '**/mocks/**',
  '**/dist/**',
  `**/${DEFAULT_TEST_EXT_PATTERN}`,
  '**/*.config.*',
];
const TEST_GLOB = [
  ...(packagesPath.length
    ? packagesPath.map(p => `${p}/${DEFAULT_TEST_GLOB_PATTERN}`)
    : [DEFAULT_TEST_GLOB_PATTERN]),
  '!**/node_modules/**',
  '!./node_modules/**',
];
const SRC_GLOB = [
  ...(packagesPath.length
    ? packagesPath.map(p => `${p}/${DEFAULT_SRC_GLOB_PATTERN}`)
    : [DEFAULT_SRC_GLOB_PATTERN]),
  '!**/node_modules/**',
  '!./node_modules/**',
];
const WATCH_GLOB = [...TEST_GLOB, ...SRC_GLOB];

const DEFAULT_TRANSFORM_EXCLUDE_PATTERN = [
  '**/node_modules/**',
  './node_modules/**',
  '**/scripts/**',
  '**/coverage/**',
  '**/external/**',
  '**/autogenerated/**',
  '**/*.{html,css,json,txt,ttf,woff,svg,ico}',
  '**/*require*.js',
  '**/*sinon*.js',
  '**/*chai*.js',
];
const DEFAULT_INSTRUMENT_EXCLUDE_PATTERN = [
  ...DEFAULT_TRANSFORM_EXCLUDE_PATTERN,
  DEFAULT_TEST_EXT_PATTERN,
  DEFAULT_TEST_GLOB_PATTERN,
];

const utils = {
  packages,
  packagesPath,
  packagesMap,
  workspaces,
  lernaPackages,
  DEFAULT_TEST_EXT_PATTERN,
  DEFAULT_TEST_GLOB_PATTERN,
  DEFAULT_SRC_GLOB_PATTERN,
  DEFAULT_SRC_EXCLUDE_PATTERN,
  TEST_GLOB,
  SRC_GLOB,
  WATCH_GLOB,
  DEFAULT_TRANSFORM_EXCLUDE_PATTERN,
  DEFAULT_INSTRUMENT_EXCLUDE_PATTERN,
  isSourceMap(f) {
    return !fs.existsSync(f) && f.endsWith('.map');
  },
  isTypescript(f) {
    return f.endsWith('.ts');
  },
  getExt(f) {
    const parts = f.split('.');
    return parts.pop();
  },
  getPathWithExt(f, ext) {
    const parts = f.split('.');
    parts.pop();
    return `${parts.join('.')}.${ext}`;
  },
  ensureFilePath(js) {
    const exists = fs.existsSync(js);
    if (!exists && js.endsWith('.js')) {
      const ts = utils.getPathWithExt(js, 'ts');
      if (!fs.existsSync(ts)) {
        return '';
      }
      return ts;
    }
    return exists ? js : '';
  },
  clearLine() {
    if (isCI) {
      return;
    }
    readline.clearLine(process.stderr, 0);
    readline.cursorTo(process.stderr, 0, null);
  },
  writeLine(prefix, msg) {
    if (isCI) {
      return;
    }
    this.clearLine();
    process.stderr.write(
      `${prefix} ${msg.length > 60 ? '...' : ''}${msg.slice(-59)}`,
    );
  },
  safeGetModule(name) {
    let found = importCwd.silent(name);
    if (!found) {
      try {
        found = require(name);
      } catch (err) {
        found = null;
      }
    }
    return found;
  },
  coerceBabel(opt) {
    if (opt.enable && opt.core && typeof opt.core === 'string') {
      opt.babel = importCwd(opt.core);
    } else if (opt.enable && !opt.core) {
      let core = utils.safeGetModule('@babel/core');
      if (!core) {
        core = utils.safeGetModule('babel-core');
        if (!core) {
          throw new Error('Can not get babel core module');
        }
      }
      opt.babel = core;
    }
    if (opt.enable && typeof opt.babelPluginIstanbul === 'string') {
      const babelPluginIstanbul = utils.safeGetModule(opt.babelPluginIstanbul);
      opt.babelPluginIstanbul = babelPluginIstanbul
        ? babelPluginIstanbul.default
        : null;
    }
    if (opt.enable && typeof opt.typescript === 'string') {
      opt.typescript = utils.safeGetModule(opt.typescript);
    }
    return opt;
  },
  getCurrentFilenameStackInfo(testFiles) {
    // Magically figure out the current test from the stack trace (callsites not working with sourcemaps)
    const s = new Error().stack
      .split('\n')
      .slice(1)
      .map(c => c.split(/\(([^)]+)\)/)[1])
      .filter(c => c !== undefined)
      .map((c) => {
        const parts = c.split(':');
        const columnno = parts.pop();
        const lineno = parts.pop();
        const filename = path.resolve(parts.join(':'));
        return [filename, lineno, columnno, c];
      })
      .filter(([filename]) => testFiles.indexOf(filename) !== -1);
    if (!s.length) {
      throw new Error('Can not find test file');
    }
    return s.shift();
  },
  safeDeleteCache(f) {
    if (require.cache[f]) {
      delete require.cache[f];
    }
    if (require.cache[f] && require.cache[f].parent) {
      let i = require.cache[f].parent.children.length;
      while (i--) {
        if (require.cache[f].parent.children[i].id === f) {
          require.cache[f].parent.children.splice(i, 1);
        }
      }
    }
  },
  safeRequireCache(f) {
    try {
      require(f);
      return require.cache[f];
    } catch (_) {
      // console.error(_)
    }
    return { children: [] };
  },
  matchDependency(found, testName) {
    let use = found;
    if (found.length > 1) {
      const matchName = found.filter(
        id => path
          .basename(id)
          .split('.')
          .shift() === testName,
      );
      if (matchName.length === 1) {
        use = matchName;
      } else {
        use = found.splice(0, 1);
      }
    }
    return use;
  },
  getDependencies(files, file) {
    const name = path
      .basename(file)
      .split('.')
      .shift();
    const mod = this.safeRequireCache(file);
    const found = mod.children
      .filter(m => files.indexOf(m.id) !== -1)
      .map(m => m.id);
    return this.matchDependency(found, name);
  },
  getAllDependencies(files, file) {
    let all = [];
    const deps = this.getDependencies(files, file);
    const walk = (currentDeps) => {
      all = all.concat(currentDeps);
      currentDeps.forEach((d) => {
        const childDeps = this.getDependencies(files, d);
        walk(childDeps, files, d);
      });
    };
    walk(deps, files, file);
    return all;
  },
  createDebug(p) {
    return debug(`@after-work.js:${p}`);
  },
  filter(arr, initialValue) {
    return arr.reduce(
      (acc, curr) => acc.filter(file => minimatch(file, curr)),
      initialValue,
    );
  },
  isMatchingExtPattern(filePath, extPattern) {
    const base = path.basename(filePath);
    return minimatch(base, extPattern);
  },
  isTestFile(filePath, { testExt = DEFAULT_TEST_EXT_PATTERN }) {
    return utils.isMatchingExtPattern(filePath, testExt);
  },
  isSrcFile(
    filePath,
    { testExt = DEFAULT_TEST_EXT_PATTERN, srcExt = DEFAULT_SRC_EXT_PATTERN },
  ) {
    return (
      !utils.isTestFile(filePath, testExt)
      && utils.isMatchingExtPattern(filePath, srcExt)
    );
  },
};

module.exports = utils;
<|endoftext|>


<commit_before>/*jslint browser: true*/
var cull = cull || {};
cull.dom = cull.dom || {};
var partial = cull.fn.partial;
var _refute = cull._refute;
var _assert = cull._assert;

//"use locals";
var el;

var isContent = function (content) {
    return content !== null && typeof content !== "undefined" &&
        (typeof content.nodeType !== "undefined" ||
         typeof content === "string" ||
         cull.isSeq(content));
};

function setProp(properties, element) {
    var name, mapper;
    properties = properties || {};

    for (name in properties) {
        if (properties.hasOwnProperty(name)) {
            mapper = el.propmap[name];
            if (mapper) {
                mapper(element, properties[name]);
            } else {
                element[name] = properties[name];
            }
        }
    }
}

function append(content, element) {
    _assert(isContent(content),
            "Content should be one or a list of [string, DOM element]");
    content = cull.toSeq(content);
    var i, l;
    for (i = 0, l = content.length; i < l; ++i) {
        if (typeof content[i] === "string") {
            element.appendChild(document.createTextNode(content[i]));
        } else {
            element.appendChild(content[i]);
        }
    }
}

function content(children, element) {
    _assert(element && typeof element.innerHTML !== "undefined",
            "content() needs element");
    element.innerHTML = "";
    append(children, element);
}

el = function (tagName, attrProps, content) {
    _refute(arguments.length > 3,
           "Content should be one or a list of [string, DOM element]");
    if (!content && isContent(attrProps)) {
        content = attrProps;
        attrProps = {};
    }
    _refute(attrProps && attrProps.tagName,
           "Cannot set attribute property tagName. Use a list when " +
           "adding multiple content elements.");
    var element = document.createElement(tagName);
    setProp(attrProps, element);
    append(content || [], element);
    return element;
};

el.toString = function () {
    return "cull.dom.el()";
};

el.propmap = {
    style: function (el, styles) {
        var property;
        for (property in styles) {
            if (styles.hasOwnProperty(property)) {
                el.style[property] = styles[property];
            }
        }
    }
};

cull.doall(function (tagName) {
    el[tagName] = partial(el, tagName);
}, ["a", "br", "div", "fieldset", "form", "h2", "h3", "h4", "h5",
    "img", "input", "label", "li", "p", "span", "strong", "textarea",
    "ul", "span", "select", "option", "ol"]);

el.setProp = setProp;
el.append = append;
el.content = content;
cull.dom.el = el;
<commit_msg>Add iframe to predefined elements.<commit_after>/*jslint browser: true*/
var cull = cull || {};
cull.dom = cull.dom || {};
var partial = cull.fn.partial;
var _refute = cull._refute;
var _assert = cull._assert;
var doall = cull.doall;

//"use locals";
var el;

var isContent = function (content) {
    return content !== null && typeof content !== "undefined" &&
        (typeof content.nodeType !== "undefined" ||
         typeof content === "string" ||
         cull.isSeq(content));
};

function setProp(properties, element) {
    var name, mapper;
    properties = properties || {};

    for (name in properties) {
        if (properties.hasOwnProperty(name)) {
            mapper = el.propmap[name];
            if (mapper) {
                mapper(element, properties[name]);
            } else {
                element[name] = properties[name];
            }
        }
    }
}

function append(content, element) {
    _assert(isContent(content),
            "Content should be one or a list of [string, DOM element]");
    content = cull.toSeq(content);
    var i, l;
    for (i = 0, l = content.length; i < l; ++i) {
        if (typeof content[i] === "string") {
            element.appendChild(document.createTextNode(content[i]));
        } else {
            element.appendChild(content[i]);
        }
    }
}

function content(children, element) {
    _assert(element && typeof element.innerHTML !== "undefined",
            "content() needs element");
    element.innerHTML = "";
    append(children, element);
}

el = function (tagName, attrProps, content) {
    _refute(arguments.length > 3,
           "Content should be one or a list of [string, DOM element]");
    if (!content && isContent(attrProps)) {
        content = attrProps;
        attrProps = {};
    }
    _refute(attrProps && attrProps.tagName,
           "Cannot set attribute property tagName. Use a list when " +
           "adding multiple content elements.");
    var element = document.createElement(tagName);
    setProp(attrProps, element);
    append(content || [], element);
    return element;
};

el.toString = function () {
    return "cull.dom.el()";
};

el.propmap = {
    style: function (el, styles) {
        var property;
        for (property in styles) {
            if (styles.hasOwnProperty(property)) {
                el.style[property] = styles[property];
            }
        }
    }
};

doall(function (tagName) { el[tagName] = partial(el, tagName); }, [
    "a", "br", "div", "fieldset", "form", "h2", "h3", "h4", "h5",
    "img", "input", "label", "li", "p", "span", "strong", "textarea",
    "ul", "span", "select", "option", "ol", "iframe"
]);

el.setProp = setProp;
el.append = append;
el.content = content;
cull.dom.el = el;
<|endoftext|>


<commit_before>/*!
 * domain-middleware - lib/domain.js
 * Copyright(c) 2012 fengmk2 <fengmk2@gmail.com>
 * MIT Licensed
 */

"use strict";

/**
 * Module dependencies.
 */

var cluster = require('cluster');
var domain = require('domain');

/**
 * Domain middleware, please use with `cluster` in production env.
 *
 * @param {Object} options
 *  - {HttpServer} server, we need to close it and stop taking new requests.
 *  - {Number} [killTimeout], worker suicide timeout, default is 30 seconds.
 * @return {Function(req, res, next)}
 */
module.exports = function createMiddleware(options) {
  options = options || {};
  options.killTimeout = options.killTimeout || 30000;
  if (!options.server) {
    throw new Error('server required!');
  }

  return function domainMiddleware(req, res, next) {
    var d = domain.create();
    d.add(req);
    d.add(res);
    d.on('error', function (err) {
      d._throwErrorCount = (d._throwErrorCount || 0) + 1;
      if (d._throwErrorCount > 1) {
        console.error('[domain-middleware] %s %s throw error %d times', req.method, req.url, d._throwErrorCount);
        console.error(err);
        return;
      }

      // Must let current connection close.
      res.setHeader('Connection', 'close');
      next(err);

      // make sure we close down within `options.killTimeout` seconds
      var killtimer = setTimeout(function () {
        console.log('[%s] [worker:%s] kill timeout, exit now.', new Date(), process.pid);
        if (process.env.NODE_ENV !== 'test') {
          process.exit(1);
        }
      }, options.killTimeout);

      // But don't keep the process open just for that!
      // If there is no more io waitting, just let process exit normally.
      if (typeof killtimer.unref === 'function') {
        // only worked on node 0.10+
        killtimer.unref();
      }

      // cluster mode
      if (cluster.worker) {
        try {
          // stop taking new requests.
          // because server could already closed, need try catch the error: `Error: Not running`
          options.server.close();
          console.warn('[%s] [worker:%s] close server!',
            new Date(), process.pid);

          // Let the master know we're dead.  This will trigger a
          // 'disconnect' in the cluster master, and then it will fork
          // a new worker.
          cluster.worker.disconnect();
          console.warn('[%s] [worker:%s] worker disconnect!',
            new Date(), process.pid);
        } catch (er2) {
          // Usually, this error throw cause by the active connections after the first domain error,
          // oh well, not much we can do at this point.
          console.error('[%s] [worker:%s] Error on server close or worker disconnect!\n%s',
            new Date(), process.pid, er2.stack);
        }
      }
    });

    d.run(next);
  };
};
<commit_msg>Add d to res.locals so can be accessed elsewhere<commit_after>/*!
 * domain-middleware - lib/domain.js
 * Copyright(c) 2012 fengmk2 <fengmk2@gmail.com>
 * MIT Licensed
 */

"use strict";

/**
 * Module dependencies.
 */

var cluster = require('cluster');
var domain = require('domain');

/**
 * Domain middleware, please use with `cluster` in production env.
 *
 * @param {Object} options
 *  - {HttpServer} server, we need to close it and stop taking new requests.
 *  - {Number} [killTimeout], worker suicide timeout, default is 30 seconds.
 * @return {Function(req, res, next)}
 */
module.exports = function createMiddleware(options) {
  options = options || {};
  options.killTimeout = options.killTimeout || 30000;
  if (!options.server) {
    throw new Error('server required!');
  }

  return function domainMiddleware(req, res, next) {
    var d = domain.create();
    d.add(req);
    d.add(res);
    d.on('error', function (err) {
      d._throwErrorCount = (d._throwErrorCount || 0) + 1;
      if (d._throwErrorCount > 1) {
        console.error('[domain-middleware] %s %s throw error %d times', req.method, req.url, d._throwErrorCount);
        console.error(err);
        return;
      }

      // Must let current connection close.
      res.setHeader('Connection', 'close');
      next(err);

      // make sure we close down within `options.killTimeout` seconds
      var killtimer = setTimeout(function () {
        console.log('[%s] [worker:%s] kill timeout, exit now.', new Date(), process.pid);
        if (process.env.NODE_ENV !== 'test') {
          process.exit(1);
        }
      }, options.killTimeout);

      // But don't keep the process open just for that!
      // If there is no more io waitting, just let process exit normally.
      if (typeof killtimer.unref === 'function') {
        // only worked on node 0.10+
        killtimer.unref();
      }

      // cluster mode
      if (cluster.worker) {
        try {
          // stop taking new requests.
          // because server could already closed, need try catch the error: `Error: Not running`
          options.server.close();
          console.warn('[%s] [worker:%s] close server!',
            new Date(), process.pid);

          // Let the master know we're dead.  This will trigger a
          // 'disconnect' in the cluster master, and then it will fork
          // a new worker.
          cluster.worker.disconnect();
          console.warn('[%s] [worker:%s] worker disconnect!',
            new Date(), process.pid);
        } catch (er2) {
          // Usually, this error throw cause by the active connections after the first domain error,
          // oh well, not much we can do at this point.
          console.error('[%s] [worker:%s] Error on server close or worker disconnect!\n%s',
            new Date(), process.pid, er2.stack);
        }
      }
    });

    res.locals.domain = d;

    d.run(next);
  };
};
<|endoftext|>


<commit_before>
function refreshProgress() {
	HttpProgressMonitor.getProgressStatus(updateProgress);
}
function updateProgress(data) {
	document.getElementById("progressBarText").innerHTML = data.description + "  :";
	if (data.done && data.forwardingURL != null) {
			window.location = data.forwardingURL;
		}
	} else {
		window.setTimeout("refreshProgress()", 1000);
	}
	return true;
}
function startProgress() {
	document.getElementById("progressBar").style.display = "block";
	document.getElementById("progressBarText").innerHTML = "In progress...";

    // wait a little while to make sure the progress job has started ..
	progressMotion();
	window.setTimeout("refreshProgress()", 800);
	return true;
}
function createProgressBar() {
	document.write("

");
}
function moveProgress(count) {
	document.getElementById("progressBarBoxContent").style.width = parseInt(count * 35) + "px";
}
function progressMotion() {
	for (i = 0; i < 10; i++) {
		window.setTimeout("moveProgress(" + i + ")", 50 * i);
	}
	for (j = 10; j > -1; j--) {
		window.setTimeout("moveProgress(" + j + ")", (50 * (10 - j)) + 500);
	}
	window.setTimeout("progressMotion()", 1000);
}

<commit_msg>one to many curly brakets!<commit_after>
function refreshProgress() {
	HttpProgressMonitor.getProgressStatus(updateProgress);
}
function updateProgress(data) {
	document.getElementById("progressBarText").innerHTML = data.description + "  :";
	if (data.done && data.forwardingURL != null) {
			window.location = data.forwardingURL;
	} else {
		window.setTimeout("refreshProgress()", 1000);
	}
	return true;
}
function startProgress() {
	document.getElementById("progressBar").style.display = "block";
	document.getElementById("progressBarText").innerHTML = "In progress...";

    // wait a little while to make sure the progress job has started ..
	progressMotion();
	window.setTimeout("refreshProgress()", 800);
	return true;
}
function createProgressBar() {
	document.write("

");
}
function moveProgress(count) {
	document.getElementById("progressBarBoxContent").style.width = parseInt(count * 35) + "px";
}
function progressMotion() {
	for (i = 0; i < 10; i++) {
		window.setTimeout("moveProgress(" + i + ")", 50 * i);
	}
	for (j = 10; j > -1; j--) {
		window.setTimeout("moveProgress(" + j + ")", (50 * (10 - j)) + 500);
	}
	window.setTimeout("progressMotion()", 1000);
}

<|endoftext|>


<commit_before>const fs = require('fs');

const parseInput = (input, config) => new Promise((resolve, reject) => {

    let parser = () => null;

    if (!config.parser) {

        parser = require('doxdox-parser-dox');

    }

    fs.stat(input, (err, stats) => {

        if (err) {

            return reject(err);

        }

        if (stats.isFile()) {

            fs.readFile(input, 'utf8', (err, data) => {

                if (err) {

                    return reject(err);

                }

                return resolve({
                    'name': input.replace(process.cwd(), ''),
                    'methods': parser(data, {'file': input})
                });

            });

        }

        return false;

    });

});

const parseInputs = (inputs, config) => new Promise(resolve => {

    let layout = () => null;

    if (!config.layout || config.layout === 'markdown') {

        layout = require('doxdox-plugin-markdown');

    }

    if (inputs.length) {

        Promise.all(inputs.map(input => parseInput(input, config)))
            .then(files => layout(Object.assign({
                files
            }, config)))
            .then(resolve);

    }

});

module.exports = {
    parseInputs
};
<commit_msg>Sorted keys.<commit_after>const fs = require('fs');

const parseInput = (input, config) => new Promise((resolve, reject) => {

    let parser = () => null;

    if (!config.parser) {

        parser = require('doxdox-parser-dox');

    }

    fs.stat(input, (err, stats) => {

        if (err) {

            return reject(err);

        }

        if (stats.isFile()) {

            fs.readFile(input, 'utf8', (err, data) => {

                if (err) {

                    return reject(err);

                }

                return resolve({
                    'methods': parser(data, {'file': input}),
                    'name': input.replace(process.cwd(), '')
                });

            });

        }

        return false;

    });

});

const parseInputs = (inputs, config) => new Promise(resolve => {

    let layout = () => null;

    if (!config.layout || config.layout === 'markdown') {

        layout = require('doxdox-plugin-markdown');

    }

    if (inputs.length) {

        Promise.all(inputs.map(input => parseInput(input, config)))
            .then(files => layout(Object.assign({
                files
            }, config)))
            .then(resolve);

    }

});

module.exports = {
    parseInputs
};
<|endoftext|>


<commit_before>/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 ONOS GUI -- Topology Layout Module.
 Module that contains the d3.force.layout logic
 */

(function () {
    'use strict';

    // Injected Services
    var Panel, gs, wss, flash, listProps;

    // Internal State
    var summaryPanel, summaryData;

    // configuration
    var id = 'topo2-p-summary',
        className = 'topo-p',
        panelOpts = {
            show: true,
            width: 260 // summary and detail panel width
        },
        handlerMap = {
            showSummary: handleSummaryData
        };

    function init() {

        bindHandlers();
        wss.sendEvent('requestSummary');

        var options = angular.extend({}, panelOpts, {
            class: className
        });

        summaryPanel = new Panel(id, options);
        summaryPanel.el.classed(className, true);
    }

    function render() {
        summaryPanel.emptyRegions();

        var svg = summaryPanel.appendToHeader('div')
                .classed('icon', true)
                .append('svg'),
            title = summaryPanel.appendToHeader('h2'),
            table = summaryPanel.appendToBody('table'),
            tbody = table.append('tbody');

        title.text(summaryData.title);
        gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
        listProps(tbody, summaryData);
    }

    function handleSummaryData(data) {
        summaryData = data;
        render();
    }

    function bindHandlers() {
        wss.bindHandlers(handlerMap);
    }

    function toggle() {
        var on = summaryPanel.el.toggle(),
            verb = on ? 'Show' : 'Hide';

        flash.flash(verb + ' Summary Panel');

        if (on) {
            wss.sendEvent('requestSummary');
        } else {
            wss.sendEvent('cancelSummary');
        }
    }

    function destroy() {
        wss.unbindHandlers(handlerMap);
        wss.sendEvent('cancelSummary');
        summaryPanel.destroy();
    }

    angular.module('ovTopo2')
    .factory('Topo2SummaryPanelService',
    ['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
        function (_ps_, _gs_, _wss_, _flash_, _listService_) {

            Panel = _ps_;
            gs = _gs_;
            wss = _wss_;
            flash = _flash_;
            listProps = _listService_;

            return {
                init: init,
                toggle: toggle,
                destroy: destroy,
                isVisible: function () { return summaryPanel.isVisible(); }
            };
        }
    ]);

})();
<commit_msg>Minor simplification.<commit_after>/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 ONOS GUI -- Topology Layout Module.
 Module that contains the d3.force.layout logic
 */

(function () {
    'use strict';

    // Injected Services
    var Panel, gs, wss, flash, listProps;

    // Internal State
    var summaryPanel, summaryData;

    // configuration
    var id = 'topo2-p-summary',
        className = 'topo-p',
        panelOpts = {
            show: true,
            width: 260 // summary and detail panel width
        },
        handlerMap = {
            showSummary: handleSummaryData
        };

    function init() {

        bindHandlers();
        wss.sendEvent('requestSummary');

        var options = angular.extend({}, panelOpts, {
            class: className
        });

        summaryPanel = new Panel(id, options);
        summaryPanel.el.classed(className, true);
    }

    function render() {
        summaryPanel.emptyRegions();

        var svg = summaryPanel.appendToHeader('div')
                .classed('icon', true)
                .append('svg'),
            title = summaryPanel.appendToHeader('h2'),
            table = summaryPanel.appendToBody('table'),
            tbody = table.append('tbody');

        title.text(summaryData.title);
        gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
        listProps(tbody, summaryData);
    }

    function handleSummaryData(data) {
        summaryData = data;
        render();
    }

    function bindHandlers() {
        wss.bindHandlers(handlerMap);
    }

    function toggle() {
        var on = summaryPanel.el.toggle(),
            verb = on ? 'Show' : 'Hide';

        flash.flash(verb + ' Summary Panel');
        wss.sendEvent(on ? 'requestSummary' : 'cancelSummary');
    }

    function destroy() {
        wss.unbindHandlers(handlerMap);
        wss.sendEvent('cancelSummary');
        summaryPanel.destroy();
    }

    angular.module('ovTopo2')
    .factory('Topo2SummaryPanelService',
    ['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService', 'ListService',
        function (_ps_, _gs_, _wss_, _flash_, _listService_) {

            Panel = _ps_;
            gs = _gs_;
            wss = _wss_;
            flash = _flash_;
            listProps = _listService_;

            return {
                init: init,
                toggle: toggle,
                destroy: destroy,
                isVisible: function () { return summaryPanel.isVisible(); }
            };
        }
    ]);

})();
<|endoftext|>


<commit_before>import angular from 'angular';
import 'angular-mocks';
import * as <%= componentNameCamel %> from './<%= componentName %>.component';

describe('<%= componentNameCamel %> component', () => {
  beforeEach(() => {
    angular
      .module('<%= componentNameCamel %>',[])
      .component('<%= componentNameCamel %>', <%= componentNameCamel %>);

    angular.mock.module('<%= componentNameCamel %>');
  });
  it('should render blank page', angular.mock.inject(($rootScope, $compile) => {
    const element = $compile('<<%= componentName %>></<%= componentName %>>')($rootScope);
    $rootScope.$digest();
    expect(element).not.toBeNull();
  }));
});
<commit_msg>consisted component spec code with other spec codes<commit_after>import angular from 'angular';
import 'angular-mocks';
import * as <%= componentNameCamel %> from './<%= componentName %>.component';

describe('<%= componentNameCamel %> component', () => {
  beforeEach(() => {
    angular
      .module('<%= componentNameCamel %>',[])
      .component('<%= componentNameCamel %>', <%= componentNameCamel %>);
    angular.mock.module('<%= componentNameCamel %>');
  });

  it('should render blank page', angular.mock.inject(($rootScope, $compile) => {
    const element = $compile('<<%= componentName %>></<%= componentName %>>')($rootScope);
    $rootScope.$digest();
    expect(element).not.toBeNull();
  }));

});
<|endoftext|>


<commit_before>'use strict';

describe('Word details controller', function() {
    var scope,
        $route,
        wordService,
        $location,
        $httpBackend;

    beforeEach(module('word'));

    beforeEach(inject(function (_$controller_, _$rootScope_,_$httpBackend_,_$route_,_wordService_,_$location_) {
        scope = _$rootScope_.$new();
        $httpBackend = _$httpBackend_;
        $route = {current:{params:{id:3}}};
        wordService =_wordService_;
        $location = _$location_;

        //spyOn($location, 'search').andReturn({id: 1});

        _$controller_('wordDetailsController', {
            $scope: scope,
            wordService: wordService,
            $route:$route
        });

        $httpBackend.when("GET", "/api/words/edit?id=3").respond(test_wordDetail);
        $httpBackend.when("GET", "/user/js/words/partials/featuredContent.html").respond(200);

    }));

    iit("should create the list of thumbnail objects to be displayed on carousel",function(){
        $httpBackend.flush();

        expect(scope.carouselItems.length).toBe(4);

        expect(scope.carouselItems[0].type).toBe('word');

        expect(scope.carouselItems[1].type).toBe('reflection');
        expect(scope.carouselItems[1].id).toBe(1);

        expect(scope.carouselItems[2].type).toBe('reflection');
        expect(scope.carouselItems[2].id).toBe(4);

        expect(scope.carouselItems[3].type).toBe('reflection');
        expect(scope.carouselItems[3].id).toBe(7);
    });
});

var test_wordDetail ={
    "id": 3,
    "wordOriginal": "अकथ कथा",
    "wordTranslation": "Untellable Tale",
    "wordTransliteration": "Akath Katha",
    "englishIntroExcerpt": "Akath means inexpressible, indescribable, ineffable. Beyond words. Beyond language. Beyond mind. But why all the hue and cry if the tale cannot be told? Perhaps because there is an enticing, irresistible vastness and mysteriousness to the unspeakable story. It is not mystification but an invitation to enter… a realm of experience beyond description.",
    "hindiIntroExcerpt": null,
    "diacritic": null,
    "isRootWord": true,
    "showOnLandingPage": true,
    "meaning": null,
    "wordIntroductions": [
        {
            "id": 82,
            "wordIntroHindi": "",
            "wordIntroEnglish": "
sfsdfdfer jie bpawe ojasd moiald twisew  dserfs
",
            "contentType": "text",
            "poet": null
        },
        {
            "id": 81,
            "wordIntroHindi": "",
            "wordIntroEnglish": "
some text hosfdo ijiojeq dsfije oernf opawed
",
            "contentType": "text",
            "poet": null
        }
    ],
    "reflections": [
        {
            "id": 4,
            "title": "Unbelievable",
            "speaker": {
                "id": 14,
                "name": "Gavra Devi",
                "hindiName": "",
                "primaryOccupation": ""
            },
            "published": true
        },
        {
            "id": 7,
            "title": "reflection",
            "speaker": {
                "id": 0,
                "name": null,
                "hindiName": null,
                "primaryOccupation": null
            },
            "published": true
        }
    ],
    "relatedWords": [],
    "songs": [],
    "synonyms": [],
    "writers": [],
    "people": [],
    "displayAjabShaharTeam": false,
    "defaultReflection": {
        "id": 1,
        "title": "Poet is God says Vipul",
        "speaker": {
            "id": 16,
            "name": "Vipul Rikhi",
            "hindiName": "",
            "primaryOccupation": ""
        },
        "published": true
    }
}<commit_msg>#70 | fixing some tests | indraneel<commit_after>'use strict';

describe('Word details controller', function() {
    var scope,
        $route,
        wordService,
        $location,
        $httpBackend;

    beforeEach(module('word'));

    beforeEach(inject(function (_$controller_, _$rootScope_,_$httpBackend_,_$route_,_wordService_,_$location_) {
        scope = _$rootScope_.$new();
        $httpBackend = _$httpBackend_;
        $route = {current:{params:{id:3}}};
        wordService =_wordService_;
        $location = _$location_;

        //spyOn($location, 'search').andReturn({id: 1});

        _$controller_('wordDetailsController', {
            $scope: scope,
            wordService: wordService,
            $route:$route
        });

        $httpBackend.when("GET", "/api/words/edit?id=3").respond(test_wordDetail);
        $httpBackend.when("GET", "/user/js/words/partials/featuredContent.html").respond(200);

    }));

    it("should create the list of thumbnail objects to be displayed on carousel",function(){
        $httpBackend.flush();

        expect(scope.carouselItems.length).toBe(4);

        expect(scope.carouselItems[0].type).toBe('word');

        expect(scope.carouselItems[1].type).toBe('reflection');
        expect(scope.carouselItems[1].id).toBe(1);

        expect(scope.carouselItems[2].type).toBe('reflection');
        expect(scope.carouselItems[2].id).toBe(4);

        expect(scope.carouselItems[3].type).toBe('reflection');
        expect(scope.carouselItems[3].id).toBe(7);
    });
});

var test_wordDetail ={
    "id": 3,
    "wordOriginal": "अकथ कथा",
    "wordTranslation": "Untellable Tale",
    "wordTransliteration": "Akath Katha",
    "englishIntroExcerpt": "Akath means inexpressible, indescribable, ineffable. Beyond words. Beyond language. Beyond mind. But why all the hue and cry if the tale cannot be told? Perhaps because there is an enticing, irresistible vastness and mysteriousness to the unspeakable story. It is not mystification but an invitation to enter… a realm of experience beyond description.",
    "hindiIntroExcerpt": null,
    "diacritic": null,
    "isRootWord": true,
    "showOnLandingPage": true,
    "meaning": null,
    "wordIntroductions": [
        {
            "id": 82,
            "wordIntroHindi": "",
            "wordIntroEnglish": "
sfsdfdfer jie bpawe ojasd moiald twisew  dserfs
",
            "contentType": "text",
            "poet": null
        },
        {
            "id": 81,
            "wordIntroHindi": "",
            "wordIntroEnglish": "
some text hosfdo ijiojeq dsfije oernf opawed
",
            "contentType": "text",
            "poet": null
        }
    ],
    "reflections": [
        {
            "id": 4,
            "title": "Unbelievable",
            "speaker": {
                "id": 14,
                "name": "Gavra Devi",
                "hindiName": "",
                "primaryOccupation": ""
            },
            "published": true
        },
        {
            "id": 7,
            "title": "reflection",
            "speaker": {
                "id": 0,
                "name": null,
                "hindiName": null,
                "primaryOccupation": null
            },
            "published": true
        }
    ],
    "relatedWords": [],
    "songs": [],
    "synonyms": [],
    "writers": [],
    "people": [],
    "displayAjabShaharTeam": false,
    "defaultReflection": {
        "id": 1,
        "title": "Poet is God says Vipul",
        "speaker": {
            "id": 16,
            "name": "Vipul Rikhi",
            "hindiName": "",
            "primaryOccupation": ""
        },
        "published": true
    }
}<|endoftext|>


<commit_before>var nconf = require('nconf'),
  fs = require('fs'),
  fstreamnpm = require('fstream-npm'),
  tar = require('tar'),
  zlib = require('zlib');

var drones = module.exports;

drones._getDomains = function(pkg) {
  var domains = [];

  ['domain', 'domains', 'subdomain', 'subdomains'].forEach(function(key) {
    if (pkg[key]) {
      if (typeof pkg[key] === 'string')
        pkg[key] = pkg[key].split(' ');

      pkg[key].forEach(function(domain) {
        if (domain)
          domains.push(domain);
      });
    }
  });

  return domains;
};

drones.listdrones = function(options, fn) {
  var self = this,
    path = 'drones';

  if (options.user && options.user.trim() != '') {
    path += '/' + options.user;

    if (options.app && options.app.trim() != '')
      path += '/' + options.app;
  }

  this.parent.request(path, function(err, result) {
    if (err)
      return fn(err);

    var msg = [['User', 'Name', 'Internal Address', 'Domains', 'Started']];

    if (result && result.drones && result.drones.push) {
      result.drones.forEach(function(d) {
        var domains = self._getDomains(d);

        msg.push([
          d.user,
          d.name,
          d.host + ':' + (d.env && d.env.PORT || '#'),
          domains.join('\n'),
          (d.started ? 'yes' : 'no')
        ]);
      });
    }

    fn(null, {raw: result, message: msg});
  });
};

drones._validatePackage = function(options) {
  var path = options.dir || process.cwd(),
    errors = {};

  try {
    nconf.file(path + '/package.json');
  }
  catch (e) {
    return {errors: false};
  }

  //merge any options if passed
  ['name', 'scripts.start', 'engines.node', 'domains'].forEach(function(k) {
    if (options[k] != undefined)
      nconf.set(k.replace('.', ':'), options[k]);
  });

  //save new package
  nconf.save();

  //check app name, only allow letters and numbers
  if (!nconf.get('name') || typeof nconf.get('name') !== 'string' ||
      nconf.get('name') && !nconf.get('name').match(/^[a-z0-9]+$/i))
    errors['name'] = 'Name has to provided and it can only be letters and numbers';

  //check for start script
  if (!nconf.get('scripts:start') || typeof nconf.get('scripts:start') !== 'string' || nconf.get('scripts:start') &&
      !fs.existsSync(path + '/' + nconf.get('scripts:start')))
    errors['scripts.start'] = 'Unspecified or missing start script';

  //check for node engine
  if (!nconf.get('engines:node') || typeof nconf.get('engines:node') !== 'string')
    errors['engines.node'] = 'Unspecified or incorrect node engine';

  //check for domains
  if (this._getDomains(nconf.get()).length === 0)
    errors['domains'] = 'At least one domain has to be specified';

  return {errors: errors, pkg: nconf.get()};
};

drones.deploy = function(options, fn) {
  var self = this;

  //use default host user if not specified
  options.user = options.user || this.parent.host.user;

  //validate package.json and update it if required
  var result = this._validatePackage(options);

  if (result.errors === false)
    return fn({message: 'Error parsing package.json'});

  var error_fields = Object.keys(result.errors);

  if (error_fields.length > 0) {
    var required = [],
      msg = [];

    for (var k in result.errors) {
      required.push(k);
      msg.push(result.errors[k]);
    }

    return fn({required: required, message: msg.join('\n')});
  }

  //create archive
  options.data = fstreamnpm({path: options.dir || process.cwd()})
    .on('error', fn)
    .pipe(tar.Pack())
    .on('error', fn)
    .pipe(zlib.Gzip())
    .on('error', fn);

  options.app = options.app || result.pkg && result.pkg.name || '';

  this.parent.request('drones/' + options.user + '/' + options.app + '/deploy', 'post', options, function(err, drone) {
    if (err)
      return fn(err);

    fn(null, {raw: drone, message: 'Deployment complete:\n' + self._getDomains(result.pkg).join('\n')});
  });
};

drones._changeState = function(options, fn, state) {
  var self = this;

  options.dir = options.dir || process.cwd();

  //look for local package.json
  nconf.file(options.dir + '/package.json');

  options.user = nconf.get('user') || options.user || this.parent.host.user;
  options.app = nconf.get('name') || options.app;

  this.parent.checkRequired(options, ['user', 'app'], function(err) {
    if (err)
      return fn(err);

    self.parent.request('drones/' + options.user + '/' + options.app + '/' + state, 'post', function(err, result) {
      if (err)
        return fn(err);

      fn(null, {raw: result, message: 'App successfully ' + state + 'ed:\n' + self._getDomains(result).join('\n')});
    });
  });
};

drones.start = function(options, fn) {
  this._changeState(options, fn, 'start');
};

drones.stop = function(options, fn) {
  this._changeState(options, fn, 'stop');
};

drones.restart = function(options, fn) {
  this._changeState(options, fn, 'restart');
};

drones.logs = function() {};<commit_msg>Added basic app logs<commit_after>var nconf = require('nconf'),
  fs = require('fs'),
  fstreamnpm = require('fstream-npm'),
  tar = require('tar'),
  zlib = require('zlib');

var drones = module.exports;

drones._getDomains = function(pkg) {
  var domains = [];

  ['domain', 'domains', 'subdomain', 'subdomains'].forEach(function(key) {
    if (pkg[key]) {
      if (typeof pkg[key] === 'string')
        pkg[key] = pkg[key].split(' ');

      pkg[key].forEach(function(domain) {
        if (domain)
          domains.push(domain);
      });
    }
  });

  return domains;
};

drones.listdrones = function(options, fn) {
  var self = this,
    path = 'drones';

  if (options.user && options.user.trim() != '') {
    path += '/' + options.user;

    if (options.app && options.app.trim() != '')
      path += '/' + options.app;
  }

  this.parent.request(path, function(err, result) {
    if (err)
      return fn(err);

    var msg = [['User', 'Name', 'Internal Address', 'Domains', 'Started']];

    if (result && result.drones && result.drones.push) {
      result.drones.forEach(function(d) {
        var domains = self._getDomains(d);

        msg.push([
          d.user,
          d.name,
          d.host + ':' + (d.env && d.env.PORT || '#'),
          domains.join('\n'),
          (d.started ? 'yes' : 'no')
        ]);
      });
    }

    fn(null, {raw: result, message: msg});
  });
};

drones._validatePackage = function(options) {
  var path = options.dir || process.cwd(),
    errors = {};

  try {
    nconf.file(path + '/package.json');
  }
  catch (e) {
    return {errors: false};
  }

  //merge any options if passed
  ['name', 'scripts.start', 'engines.node', 'domains'].forEach(function(k) {
    if (options[k] != undefined)
      nconf.set(k.replace('.', ':'), options[k]);
  });

  //save new package
  nconf.save();

  //check app name, only allow letters and numbers
  if (!nconf.get('name') || typeof nconf.get('name') !== 'string' ||
      nconf.get('name') && !nconf.get('name').match(/^[a-z0-9]+$/i))
    errors['name'] = 'Name has to provided and it can only be letters and numbers';

  //check for start script
  if (!nconf.get('scripts:start') || typeof nconf.get('scripts:start') !== 'string' || nconf.get('scripts:start') &&
      !fs.existsSync(path + '/' + nconf.get('scripts:start')))
    errors['scripts.start'] = 'Unspecified or missing start script';

  //check for node engine
  if (!nconf.get('engines:node') || typeof nconf.get('engines:node') !== 'string')
    errors['engines.node'] = 'Unspecified or incorrect node engine';

  //check for domains
  if (this._getDomains(nconf.get()).length === 0)
    errors['domains'] = 'At least one domain has to be specified';

  return {errors: errors, pkg: nconf.get()};
};

drones.deploy = function(options, fn) {
  var self = this;

  //use default host user if not specified
  options.user = options.user || this.parent.host.user;

  //validate package.json and update it if required
  var result = this._validatePackage(options);

  if (result.errors === false)
    return fn({message: 'Error parsing package.json'});

  var error_fields = Object.keys(result.errors);

  if (error_fields.length > 0) {
    var required = [],
      msg = [];

    for (var k in result.errors) {
      required.push(k);
      msg.push(result.errors[k]);
    }

    return fn({required: required, message: msg.join('\n')});
  }

  //create archive
  options.data = fstreamnpm({path: options.dir || process.cwd()})
    .on('error', fn)
    .pipe(tar.Pack())
    .on('error', fn)
    .pipe(zlib.Gzip())
    .on('error', fn);

  options.app = options.app || result.pkg && result.pkg.name || '';

  this.parent.request('drones/' + options.user + '/' + options.app + '/deploy', 'post', options, function(err, drone) {
    if (err)
      return fn(err);

    fn(null, {raw: drone, message: 'Deployment complete:\n' + self._getDomains(result.pkg).join('\n')});
  });
};

drones._changeState = function(options, fn, state) {
  var self = this;

  options.dir = options.dir || process.cwd();

  //look for local package.json
  nconf.file(options.dir + '/package.json');

  options.user = nconf.get('user') || options.user || this.parent.host.user;
  options.app = nconf.get('name') || options.app;

  this.parent.checkRequired(options, ['user', 'app'], function(err) {
    if (err)
      return fn(err);

    self.parent.request('drones/' + options.user + '/' + options.app + '/' + state, 'post', function(err, result) {
      if (err)
        return fn(err);

      fn(null, {raw: result, message: 'App successfully ' + state + 'ed:\n' + self._getDomains(result).join('\n')});
    });
  });
};

drones.start = function(options, fn) {
  this._changeState(options, fn, 'start');
};

drones.stop = function(options, fn) {
  this._changeState(options, fn, 'stop');
};

drones.restart = function(options, fn) {
  this._changeState(options, fn, 'restart');
};

drones.logs = function(options, fn) {
  var self = this;

  this.parent.checkRequired(options, ['user', 'app'], function(err) {
    var path = 'drones/' + options.user + '/' + options.app + '/logs';

    self.parent.request(path, function(err, result) {
      if (err)
        return fn(err);

      var msg = [['Time', 'Message', 'Type']];

      if (result && result.push && result.length > 0) {
        result.forEach(function(l) {
          msg.push([l.ts, l.msg, l.type]);
        });
      }

      fn(null, {raw: result, message: msg});
    });
  });
};<|endoftext|>


<commit_before>
'use strict';

import React, {
    Component,
    StyleSheet,
    Text,
    Image,
    View,
    TouchableHighlight,
    TouchableNativeFeedback,
    Platform,
    NetInfo,
} from 'react-native';

import SimpleStore from 'react-native-simple-store';
import RNFS from 'react-native-fs';

import CommonStyles from './common-styles.js';
import QuestionScreen from './question-screen.js';
import API from './api.js';
import Constants from './constants.js';
import Button from './button.js';
import ArrowButton from './arrow-button.js';

var TouchableElement = TouchableHighlight;
if (Platform.OS === 'android') {
    TouchableElement = TouchableNativeFeedback;
}

const titleImage = require('../assets/title-image.png');

class MainMenuScreen extends Component {
    constructor(props) {
        super(props);

        this.state = {
            loading: 0,
            success: 2,
        }
    }

    componentWillMount() {
        this.pullDownGameData();
    }

    render() {
        // a bit of a hack to make sure currentStreak is reset -------
        SimpleStore.save('currentStreak', 0);
        // -------

        var playButton = (
            <ArrowButton
                onPress={() => {this.onStartGame()}}
                text={this.state.loading ? 'Loading...' : 'How bad could it be'}
                disabled={this.state.loading}
            />
        );

        if (!this.state.loading && this.state.success < 2) {
            playButton = (
                <View>
                    <Text style={[CommonStyles.baseText, styles.errorText]}>
                        Unable to download quiz questions... Please make sure you have interent access.
                    </Text>
                    <Button
                        onPress={() => { this.pullDownGameData() }}
                        text={'Press to retry'}
                    />
                </View>
            );
        }

        return (
            <View style={[CommonStyles.screenBackground, styles.mainMenuScreen]}>
                <View style={styles.titleBox}>

                    <Image
                        style={styles.titleImage}
                        source={titleImage}
                    />

                </View>
                <View style={styles.menuBox}>

                    {playButton}

                </View>
            </View>
        );
    }

    pullDownGameData() {
        NetInfo.isConnected.fetch().done((isConnected) => {
            if (isConnected) {
                // `loading` used as a semaphore, we'll load questions
                // and assets in parallel
                this.setState({ loading: 2, success: 0 }, () => {
                    this.loadQuestions();
                    this.loadImages();
                });
            }
        });
    }

    loadQuestions() {
        API.getTopQuestions((err, newQuestions) => {
            if (err || !newQuestions.length) {
                console.log('ERROR: could not query for questions. ', err);
                return this.setState({ loading: this.state.loading - 1 });
            }

            SimpleStore.get('questions').then((oldQuestions) => {
                oldQuestions = oldQuestions || {};

                var questions = {};

                for (var i = 0; i < newQuestions.length; ++i) {
                    var q = newQuestions[i];

                    questions[q.id] = q;
                    if (oldQuestions[q.id] && oldQuestions[q.id].answered) {
                        questions[q.id].answered = true;
                    }
                }

                SimpleStore.save('questions', questions)
                .then((err) => {
                    if (err) {
                        console.log('ERROR: could not download / unpack image bundle. ', err);
                    }

                    this.setState({ loading: this.state.loading - 1, success: this.state.success + 1 });
                });
            });
        });
    }

    loadImages() {
        API.downloadImageBundle((err, path) => {
            this.setState({ loading: this.state.loading - 1, success: this.state.success + 1 });

            // RNFS.readDir(Constants.IMAGE_DIR)
            //   .then((result) => {
            //     console.log('GOT RESULT', result);
            // });
        });
    }

    onStartGame() {
        this.props.navigator.push({
            name: 'QuestionScreen',
            component: QuestionScreen,
        });
    }
}

const styles = StyleSheet.create({
    mainMenuScreen: {
        flex: 1,
        flexDirection: 'column',
    },
    titleBox: {
        flex: 4,
        alignSelf: 'center',
        justifyContent: 'center',
    },
    titleImage: {
        width: 300,
        height: 500,
    },
    menuBox: {
        flex: 1,
        margin: 20,
        marginRight: 30,
        justifyContent: 'center',
        alignItems: 'center',
    },
    errorText: {
        fontWeight: 'bold',
        color: '#FFFFFD',
        marginBottom: 10,
    },
});

export default MainMenuScreen;
<commit_msg>optionally preserve answers (for demo mode)<commit_after>
'use strict';

import React, {
    Component,
    StyleSheet,
    Text,
    Image,
    View,
    TouchableHighlight,
    TouchableNativeFeedback,
    Platform,
    NetInfo,
} from 'react-native';

import SimpleStore from 'react-native-simple-store';
import RNFS from 'react-native-fs';

import CommonStyles from './common-styles.js';
import QuestionScreen from './question-screen.js';
import API from './api.js';
import Constants from './constants.js';
import Button from './button.js';
import ArrowButton from './arrow-button.js';

var TouchableElement = TouchableHighlight;
if (Platform.OS === 'android') {
    TouchableElement = TouchableNativeFeedback;
}

const titleImage = require('../assets/title-image.png');
const preserveAnswers = true;

class MainMenuScreen extends Component {
    constructor(props) {
        super(props);

        this.state = {
            loading: 0,
            success: 2,
        }
    }

    componentWillMount() {
        this.pullDownGameData();
    }

    render() {
        // a bit of a hack to make sure currentStreak is reset -------
        SimpleStore.save('currentStreak', 0);
        // -------

        var playButton = (
            <ArrowButton
                onPress={() => {this.onStartGame()}}
                text={this.state.loading ? 'Loading...' : 'How bad could it be'}
                disabled={this.state.loading}
            />
        );

        if (!this.state.loading && this.state.success < 2) {
            playButton = (
                <View>
                    <Text style={[CommonStyles.baseText, styles.errorText]}>
                        Unable to download quiz questions... Please make sure you have interent access.
                    </Text>
                    <Button
                        onPress={() => { this.pullDownGameData() }}
                        text={'Press to retry'}
                    />
                </View>
            );
        }

        return (
            <View style={[CommonStyles.screenBackground, styles.mainMenuScreen]}>
                <View style={styles.titleBox}>

                    <Image
                        style={styles.titleImage}
                        source={titleImage}
                    />

                </View>
                <View style={styles.menuBox}>

                    {playButton}

                </View>
            </View>
        );
    }

    pullDownGameData() {
        NetInfo.isConnected.fetch().done((isConnected) => {
            if (isConnected) {
                // `loading` used as a semaphore, we'll load questions
                // and assets in parallel
                this.setState({ loading: 2, success: 0 }, () => {
                    this.loadQuestions();
                    this.loadImages();
                });
            }
        });
    }

    loadQuestions() {
        API.getTopQuestions((err, newQuestions) => {
            if (err || !newQuestions.length) {
                console.log('ERROR: could not query for questions. ', err);
                return this.setState({ loading: this.state.loading - 1 });
            }

            SimpleStore.get('questions').then((oldQuestions) => {
                oldQuestions = oldQuestions || {};

                var questions = {};

                for (var i = 0; i < newQuestions.length; ++i) {
                    var q = newQuestions[i];

                    questions[q.id] = q;
                    if (preserveAnswers && oldQuestions[q.id] && oldQuestions[q.id].answered) {
                        questions[q.id].answered = true;
                    }
                }

                SimpleStore.save('questions', questions)
                .then((err) => {
                    if (err) {
                        console.log('ERROR: could not download / unpack image bundle. ', err);
                    }

                    this.setState({ loading: this.state.loading - 1, success: this.state.success + 1 });
                });
            });
        });
    }

    loadImages() {
        API.downloadImageBundle((err, path) => {
            this.setState({ loading: this.state.loading - 1, success: this.state.success + 1 });

            // RNFS.readDir(Constants.IMAGE_DIR)
            //   .then((result) => {
            //     console.log('GOT RESULT', result);
            // });
        });
    }

    onStartGame() {
        this.props.navigator.push({
            name: 'QuestionScreen',
            component: QuestionScreen,
        });
    }
}

const styles = StyleSheet.create({
    mainMenuScreen: {
        flex: 1,
        flexDirection: 'column',
    },
    titleBox: {
        flex: 4,
        alignSelf: 'center',
        justifyContent: 'center',
    },
    titleImage: {
        width: 300,
        height: 500,
    },
    menuBox: {
        flex: 1,
        margin: 20,
        marginRight: 30,
        justifyContent: 'center',
        alignItems: 'center',
    },
    errorText: {
        fontWeight: 'bold',
        color: '#FFFFFD',
        marginBottom: 10,
    },
});

export default MainMenuScreen;
<|endoftext|>


<commit_before>var _ = require('underscore');
var cdb = require('cartodb.js');

/**
 * Default widget model
 *
 * Note: Currently all widgets have a dependency on a dataview, why it makes sense to have it here.
 * If you need a widget model that's backed up by a dataview model please implement your own model and adhere to the
 * public interface instead of extending/hacking this one.
 */
module.exports = cdb.core.Model.extend({
  defaults: {
    attrsNames: [],
    show_stats: false
  },

  defaultState: {
    'collapsed': false,
    'pinned': false
  },

  initialize: function (attrs, opts) {
    this.dataviewModel = opts.dataviewModel;
  },

  /**
   * @public
   * @param {Object} attrs, not that it should be
   * @return {Boolean} true if at least one attribute was changed
   * @throws {Error} Should throw an error if the attrs are invalid or inconsistent
   */
  update: function (attrs) {
    var wAttrs = _.pick(attrs, this.get('attrsNames'));
    this.set(wAttrs);
    this.dataviewModel.update(attrs);
    return !!(this.changedAttributes() || this.dataviewModel.changedAttributes());
  },

  /**
   * @public
   */
  remove: function () {
    this.dataviewModel.remove();
    this.trigger('destroy', this);
    this.stopListening();
  },

  setState: function (state) {
    this.set(state);
  },

  getState: function () {
    var state = {};
    for (var key in this.defaultState) {
      var attribute = this.get(key);
      if (typeof attribute !== 'undefined' && attribute !== this.defaultState[key]) {
        state[key] = attribute;
      }
    }
    return state;
  }
});
<commit_msg>performs underscore equal comparison instead of === to compare arrays<commit_after>var _ = require('underscore');
var cdb = require('cartodb.js');

/**
 * Default widget model
 *
 * Note: Currently all widgets have a dependency on a dataview, why it makes sense to have it here.
 * If you need a widget model that's backed up by a dataview model please implement your own model and adhere to the
 * public interface instead of extending/hacking this one.
 */
module.exports = cdb.core.Model.extend({
  defaults: {
    attrsNames: [],
    show_stats: false
  },

  defaultState: {
    'collapsed': false,
    'pinned': false
  },

  initialize: function (attrs, opts) {
    this.dataviewModel = opts.dataviewModel;
  },

  /**
   * @public
   * @param {Object} attrs, not that it should be
   * @return {Boolean} true if at least one attribute was changed
   * @throws {Error} Should throw an error if the attrs are invalid or inconsistent
   */
  update: function (attrs) {
    var wAttrs = _.pick(attrs, this.get('attrsNames'));
    this.set(wAttrs);
    this.dataviewModel.update(attrs);
    return !!(this.changedAttributes() || this.dataviewModel.changedAttributes());
  },

  /**
   * @public
   */
  remove: function () {
    this.dataviewModel.remove();
    this.trigger('destroy', this);
    this.stopListening();
  },

  setState: function (state) {
    this.set(state);
  },

  getState: function () {
    var state = {};
    for (var key in this.defaultState) {
      var attribute = this.get(key);
      if (typeof attribute !== 'undefined' && !_.isEqual(attribute, this.defaultState[key])) {
        state[key] = attribute;
      }
    }
    return state;
  }
});
<|endoftext|>


<commit_before>var _ = require('underscore');
var cdb = require('cartodb.js');
var AutoStylerFactory = require('./auto-style/factory');

/**
 * Default widget model
 *
 * Note: Currently all widgets have a dependency on a dataview, why it makes sense to have it here.
 * If you need a widget model that's backed up by a dataview model please implement your own model and adhere to the
 * public interface instead of extending/hacking this one.
 */
module.exports = cdb.core.Model.extend({
  defaults: {
    attrsNames: [],
    show_stats: false
  },

  defaultState: {
    'collapsed': false
  },

  initialize: function (attrs, models, opts) {
    opts = opts || {};
    this.dataviewModel = models.dataviewModel;
    this.defaults.autoStyleEnabled = opts.autoStyleEnabled;

    this.activeAutoStyler();
    this.bind('change:style', this.activeAutoStyler, this);
  },

  activeAutoStyler: function () {
    if (this.isAutoStyleEnabled() && !this.autoStyler) {
      this.autoStyler = AutoStylerFactory.get(this.dataviewModel, this.get('style'));
    }
  },

  /**
   * @public
   * @param {Object} attrs, not that it should be
   * @return {Boolean} true if at least one attribute was changed
   * @throws {Error} Should throw an error if the attrs are invalid or inconsistent
   */
  update: function (attrs) {
    var wAttrs = _.pick(attrs, this.get('attrsNames'));
    this.set(wAttrs);
    this.dataviewModel.update(attrs);
    this._triggerChangesInAutoStyle();
    return !!(this.changedAttributes() || this.dataviewModel.changedAttributes());
  },

  _triggerChangesInAutoStyle: function () {
    var changed = this.changed && this.changed.style && this.changed.style.auto_style && this.changed.style.auto_style.definition;
    var previous = this.previousAttributes();
    var former = previous.style && previous.style.auto_style && previous.style.auto_style.definition;

    if (!_.isEqual(changed, former)) {
      this.trigger('customAutoStyle', this);
    }
  },

  /**
   * @public
   */
  remove: function () {
    this.dataviewModel.remove();
    this.trigger('destroy', this);
    this.stopListening();
  },

  isAutoStyleEnabled: function () {
    if (!this.defaults.autoStyleEnabled) return false;

    var styles = this.get('style');

    if (this.get('type') === 'category' || this.get('type') === 'histogram') {
      if (!styles || !styles.auto_style) {
        return true;
      }

      return styles && styles.auto_style && styles.auto_style.allowed;
    } else {
      return false;
    }
  },

  getWidgetColor: function () {
    var styles = this.get('style');

    return styles && styles.widget_style &&
          styles.widget_style.definition &&
          styles.widget_style.definition.color &&
          styles.widget_style.definition.color.fixed;
  },

  hasColorsAutoStyle: function () {
    var autoStyle = this.getAutoStyle();
    var hasDefinedColors = false;

    if (!autoStyle || _.isEmpty(autoStyle) || _.isEmpty(autoStyle.definition)) {
      return false;
    }

    // Check colors in all geometries
    _.each(autoStyle.definition, function (geometryStyle) {
      if (geometryStyle.color && geometryStyle.color.range && geometryStyle.color.range.length > 0) {
        hasDefinedColors = true;
      }
    }, this);

    return hasDefinedColors;
  },

  getColor: function (name) {
    if (this.isAutoStyleEnabled() && this.isAutoStyle() && this.get('type') === 'category') {
      return this.autoStyler.colors.getColorByCategory(name);
    } else {
      return this.getWidgetColor();
    }
  },

  isAutoStyle: function () {
    return this.get('autoStyle');
  },

  autoStyle: function () {
    if (!this.isAutoStyleEnabled()) return;
    if (!this.dataForAutoStyle()) return;

    var layer = this.dataviewModel.layer;
    var initialStyle = layer.get('cartocss');
    if (!initialStyle && layer.get('meta')) {
      initialStyle = layer.get('meta').cartocss;
    }
    layer.set('initialStyle', initialStyle);

    var style = this.autoStyler.getStyle();
    layer.set('cartocss', style);
    this.set('autoStyle', true);
  },

  dataForAutoStyle: function () {
    return this.dataviewModel.get('data').length > 0;
  },

  reapplyAutoStyle: function () {
    var style = this.autoStyler.getStyle();
    this.dataviewModel.layer.set('cartocss', style);
    this.set('autoStyle', true);
  },

  cancelAutoStyle: function (noRestore) {
    if (!noRestore) {
      this.dataviewModel.layer.restoreCartoCSS();
    }
    this.set('autoStyle', false);
  },

  getAutoStyle: function () {
    var style = this.get('style');
    var layerModel = this.dataviewModel.layer;
    var cartocss = layerModel.get('cartocss') || (layerModel.get('meta') && layerModel.get('meta').cartocss);

    if (this.isAutoStyleEnabled() && this.autoStyler) {
      if (style && style.auto_style && style.auto_style.definition) {
        var toRet = _.extend(style.auto_style, {cartocss: cartocss});
        return _.extend({}, toRet, {definition: this.autoStyler.getDef(cartocss)});
      } else {
        return {
          definition: this.autoStyler.getDef(cartocss),
          cartocss: cartocss
        };
      }
    }

    return {};
  },

  setInitialState: function (state) {
    this.initialState = state || {};
  },

  applyInitialState: function () {
    var attrs = _.extend(
      this.initialState,
      {hasInitialState: true}
    );

    this.setState(attrs);
  },

  setState: function (state) {
    this.set(state);
  },

  getState: function () {
    var state = {};
    for (var key in this.defaultState) {
      var attribute = this.get(key);
      var defaultValue = this.defaultState[key];
      if (typeof defaultValue !== 'undefined' && typeof attribute !== 'undefined' && !_.isEqual(attribute, defaultValue)) {
        state[key] = attribute;
      }
    }
    return state;
  }
});
<commit_msg>Check autoStyleEnabled only if styles are undefined.<commit_after>var _ = require('underscore');
var cdb = require('cartodb.js');
var AutoStylerFactory = require('./auto-style/factory');

/**
 * Default widget model
 *
 * Note: Currently all widgets have a dependency on a dataview, why it makes sense to have it here.
 * If you need a widget model that's backed up by a dataview model please implement your own model and adhere to the
 * public interface instead of extending/hacking this one.
 */
module.exports = cdb.core.Model.extend({
  defaults: {
    attrsNames: [],
    show_stats: false
  },

  defaultState: {
    'collapsed': false
  },

  initialize: function (attrs, models, opts) {
    opts = opts || {};
    this.dataviewModel = models.dataviewModel;

    // Autostyle could be disabled initially if the styles have an aggregation
    this._autoStyleEnabledWhenCreated = opts.autoStyleEnabled;

    this.activeAutoStyler();
    this.bind('change:style', this.activeAutoStyler, this);
  },

  activeAutoStyler: function () {
    if (this.isAutoStyleEnabled() && !this.autoStyler) {
      this.autoStyler = AutoStylerFactory.get(this.dataviewModel, this.get('style'));
    }
  },

  /**
   * @public
   * @param {Object} attrs, not that it should be
   * @return {Boolean} true if at least one attribute was changed
   * @throws {Error} Should throw an error if the attrs are invalid or inconsistent
   */
  update: function (attrs) {
    var wAttrs = _.pick(attrs, this.get('attrsNames'));
    this.set(wAttrs);
    this.dataviewModel.update(attrs);
    this._triggerChangesInAutoStyle();
    return !!(this.changedAttributes() || this.dataviewModel.changedAttributes());
  },

  _triggerChangesInAutoStyle: function () {
    var changed = this.changed && this.changed.style && this.changed.style.auto_style && this.changed.style.auto_style.definition;
    var previous = this.previousAttributes();
    var former = previous.style && previous.style.auto_style && previous.style.auto_style.definition;

    if (!_.isEqual(changed, former)) {
      this.trigger('customAutoStyle', this);
    }
  },

  /**
   * @public
   */
  remove: function () {
    this.dataviewModel.remove();
    this.trigger('destroy', this);
    this.stopListening();
  },

  isAutoStyleEnabled: function () {
    var styles = this.get('style');

    if (this.get('type') === 'category' || this.get('type') === 'histogram') {
      if (!styles || !styles.auto_style) {
        // Only when styles are undefined we check the autostyle option
        return this._autoStyleEnabledWhenCreated
      }

      return styles && styles.auto_style && styles.auto_style.allowed;
    } else {
      return false;
    }
  },

  getWidgetColor: function () {
    var styles = this.get('style');

    return styles && styles.widget_style &&
          styles.widget_style.definition &&
          styles.widget_style.definition.color &&
          styles.widget_style.definition.color.fixed;
  },

  hasColorsAutoStyle: function () {
    var autoStyle = this.getAutoStyle();
    var hasDefinedColors = false;

    if (!autoStyle || _.isEmpty(autoStyle) || _.isEmpty(autoStyle.definition)) {
      return false;
    }

    // Check colors in all geometries
    _.each(autoStyle.definition, function (geometryStyle) {
      if (geometryStyle.color && geometryStyle.color.range && geometryStyle.color.range.length > 0) {
        hasDefinedColors = true;
      }
    }, this);

    return hasDefinedColors;
  },

  getColor: function (name) {
    if (this.isAutoStyleEnabled() && this.isAutoStyle() && this.get('type') === 'category') {
      return this.autoStyler.colors.getColorByCategory(name);
    } else {
      return this.getWidgetColor();
    }
  },

  isAutoStyle: function () {
    return this.get('autoStyle');
  },

  autoStyle: function () {
    if (!this.isAutoStyleEnabled()) return;
    if (!this.dataForAutoStyle()) return;

    var layer = this.dataviewModel.layer;
    var initialStyle = layer.get('cartocss');
    if (!initialStyle && layer.get('meta')) {
      initialStyle = layer.get('meta').cartocss;
    }
    layer.set('initialStyle', initialStyle);

    var style = this.autoStyler.getStyle();
    layer.set('cartocss', style);
    this.set('autoStyle', true);
  },

  dataForAutoStyle: function () {
    return this.dataviewModel.get('data').length > 0;
  },

  reapplyAutoStyle: function () {
    var style = this.autoStyler.getStyle();
    this.dataviewModel.layer.set('cartocss', style);
    this.set('autoStyle', true);
  },

  cancelAutoStyle: function (noRestore) {
    if (!noRestore) {
      this.dataviewModel.layer.restoreCartoCSS();
    }
    this.set('autoStyle', false);
  },

  getAutoStyle: function () {
    var style = this.get('style');
    var layerModel = this.dataviewModel.layer;
    var cartocss = layerModel.get('cartocss') || (layerModel.get('meta') && layerModel.get('meta').cartocss);

    if (this.isAutoStyleEnabled() && this.autoStyler) {
      if (style && style.auto_style && style.auto_style.definition) {
        var toRet = _.extend(style.auto_style, {cartocss: cartocss});
        return _.extend({}, toRet, {definition: this.autoStyler.getDef(cartocss)});
      } else {
        return {
          definition: this.autoStyler.getDef(cartocss),
          cartocss: cartocss
        };
      }
    }

    return {};
  },

  setInitialState: function (state) {
    this.initialState = state || {};
  },

  applyInitialState: function () {
    var attrs = _.extend(
      this.initialState,
      {hasInitialState: true}
    );

    this.setState(attrs);
  },

  setState: function (state) {
    this.set(state);
  },

  getState: function () {
    var state = {};
    for (var key in this.defaultState) {
      var attribute = this.get(key);
      var defaultValue = this.defaultState[key];
      if (typeof defaultValue !== 'undefined' && typeof attribute !== 'undefined' && !_.isEqual(attribute, defaultValue)) {
        state[key] = attribute;
      }
    }
    return state;
  }
});
<|endoftext|>