<commit_before>"use strict";
/* jshint evil : true, esnext: true, globalstrict: true, undef: true */
/* global _ : true, console, require, process  */

const _       = require('lodash');
const cheerio = require('cheerio');
const Hogan   = require('hogan.js');
const fs      = require('fs');
const util    = require('util');
const path    = require('path');
const he      = require('he');
const SNIPPET_REUSE_TAGS = ['head', 'tail', 'top', 'bottom'];
const FILES_USED = [];

var args     = process.argv.slice(2);

switch (args.length) {
  case 3: break;
  default:
    console.error(to_string(args));
    console.error("!!! arguments.length incorrect. Try: template_file  output_dir  public_path");
    process.exit(1);
}

var public_dir = should_be(args.pop(), is_string);
var dir        = should_be(args.pop(), is_dir);
var template   = should_be(args.pop(), is_file);

if (path.basename(template).match(/^_+\./)) {
  console.error('!!! Template is a partial: ' + template);
  process.exit(1);
}

var name              = path.basename(template, '.html');
var template_contents = read_and_cache_file_name(template);
var $template         = cheerio.load(template_contents, {recognizeSelfClosing: true});
var has_conditionals  = $template('when').length > 0;
$template = var_pipeline(

  $template,

  tag_snippet_to_markup,

  scripts_to_tag,
  styles_to_tag,
  tag_template_to_script,

  to_func(merge_tags,'head'),
  to_func(merge_tags,'tail'),
  to_func(merge_tags,'top'),
  to_func(merge_tags,'bottom'),

  to_func(remove_duplicate_tag,'link'),
  to_func(remove_duplicate_tag,'script'),
  to_func(remove_duplicate_tag,'meta'),

  conditionals_to_files,
  markup_to_file
);

// === Finish writing file.

function ABOUT(key) { // === Function that returns state.
  switch (key) {
    case 'template':         return template;
    case 'template-path':    return template;
    case 'name':             return name;
    case 'dir':              return dir;
    case 'new-file':         return dir + '/' + _.compact([name, arguments[1]]).join('-');
    case 'public-dir':       return public_dir;
    case 'json-file':        return path.join(ABOUT('dir'), "conditions.json");

    default:
      error("!!! Unknown key: " + key);
  }
}

function conditionals_to_files($) {
  let conds = tag_when_to_object($);
  if (is_empty(conds))
    return $;

  merge_and_write_conds(conds);
  conds.$whens.remove();

  return $;
} // === conditionals_to_files

function error(msg) {
  console.error(msg);
  process.exit(1);
}

function to_mustache(html) {
  return Hogan.compile(html, {asString: 1, delimiters: '[[ ]]'});
}

function get_comments($_) {
  return _.compact(_.map($_.contents(), function (node) {
    if (node.type === 'comment')
      return node.data;
  }));
}

function get_inline_vars(html) {
  var $ = cheerio(html);
  var attrs = {};
  _.each(get_comments($), function (data) {
    var lines  = data.split("\n");
    var key    = _.trim(lines.shift());
    attrs[key] = _.trim(lines.join("\n"));
  });

  return(attrs);
}

function compiled_to_compiler(code) {
  var f = new Function('Hogan', 'return new Hogan.Template(' + code + ');' );
  return f(Hogan);
}

function cheerio_to_mustache_to_html($) {
  var mustache        = to_mustache($.html());
  var inline_vars     = _.extend({}, get_inline_vars($.html()));

  return tag_template_to_script(
    compiled_to_compiler(mustache).render(inline_vars)
  );
} // === mustache_to_html

// ===  "template" tags can be deeply nested,
// so we process the inner-most ones first,
// then move on to the outer ones.
function tag_template_to_script($) {
  let tags = $('template');

  // === If no tags, we are done processing:
  if (tags.length === 0)
    return $;

  // === Find the inner-most (ie nested) template
  // tag and process it:
  let raw = _.find(tags, function (r) {
    return $('template', r).length === 0;
  });

  let type = $(raw).attr('type');
  if (!type || _.trim(type) === '')
    $(raw).attr('type', "application/template");
  let escaped = he.encode($(raw).html() || '', { useNamedReferences: false });
  $(raw).text(escaped);

  raw.name = "script";

  // === Recurse to handle outer template tags:
  return tag_template_to_script($);
}

function rel_path(file) {
  var public_dir = path.resolve(ABOUT('public-dir'));
  var full       = path.resolve(file);
  var fin        = full.replace(public_dir, '');
  if (fin.indexOf('/') !== 0)
    fin = '/' + fin;
  return fin;
}

function styles_to_tag($) {
  var new_path = ABOUT('new-file', 'style.css');
  var contents = map_to_html_and_remove($, $('style'));

  if (is_blank_string(contents))
    return $;

  fs.writeFileSync(new_path, contents);

  return append_to_tag(
    'head',
    $,
    '<link rel="stylesheet" type="text/css" href="' + rel_path(new_path) + '" />'
  );
}

function scripts_to_tag($) {
  var new_path = ABOUT('new-file', 'script.js');
  var contents = map_to_html_and_remove($, $('script'));

  if (is_blank_string(contents))
    return $;

  fs.writeFileSync(new_path, contents);

  return append_to_tag(
    'bottom',
    $,
    '<script type="application/javascript" src="' + rel_path(new_path)  + '"></script>'
  );
} // === scripts_to_tag

function map_to_html_and_remove($, coll) {
  return _.compact(_.map(coll, function (raw) {
    var html = $(raw).html();
    $(raw).remove();
    return html;
  })).join("\n");
}

function append_to_tag(tag_name, $, html) {
  var target = $(tag_name);
  if (!target[0]) {
    $.root().prepend('<' + tag_name + '></' + tag_name + '>');
    target = $(tag_name);
  }
  target.append(html);
  return $;
} // === append_to_tag

function markup_to_file($) {
  fs.writeFileSync(
    ABOUT('new-file') + '.html',
    $.html()
  );
  return $;
}

// === Used to help other functions check if
// file has already been used before. Counterpart
// is `read_and_cache_file_name`.
function is_file_loaded(file) {
  return _.includes(FILES_USED, fs.realpathSync(file));
}

function read_and_cache_file_name(file) {
  let canon = fs.realpathSync(file);
  if (!_.includes(FILES_USED, canon))
    FILES_USED.push(canon);
  return fs.readFileSync(file).toString();
}

function var_pipeline() {
  var funcs = _.toArray(arguments);
  var v     = funcs.shift();

  return _.reduce(funcs, function (acc, f) {
    return f(acc);
  }, v);
}

function log(_args) {
  return console.log.apply(console, arguments);
}

function log_and_return(v) {
  log(v);
  return v;
}

function to_func_first() {
  var args = _.toArray(arguments);
  var func = args.shift();

  return function () {
    return func.apply( null, _.toArray(arguments).concat(args));
  };
}

function to_func() {
  var args = _.toArray(arguments);
  var func = args.shift();

  return function () {
    return func.apply(
      null,
      [].concat(args).concat(_.toArray(arguments))
    );
  };
}

function read_conds() {
  var file = ABOUT('json-file');
  if (!is_file(file))
    return {};
  var raw = fs.readFileSync(file).toString();
  if (is_blank_string(raw))
    return {};
  return JSON.parse(raw);
}

function merge_and_write_conds(new_conds) {
  var conds = read_conds();
  conds[ABOUT('name')] = new_conds.conditions;
  fs.writeFileSync(ABOUT('json-file'), JSON.stringify(conds));
}

function tag_when_to_object($) {
  let conds = {};
  let $whens = conds.$whens = $('when');
  if (is_empty($whens))
    return {};

  conds.conditions = _.reduce($('val', $whens), function (vals, raw_val) {
    let $val = $(raw_val);
    var name = should_be(_.trim($val.attr('name')), is_non_blank_string);
    var val  = should_be(_.trim($val.attr('val')), is_non_blank_string);
    vals[name] = val;
    return vals;
  }, {});

  return conds;
}

function should_be(val, _funcs) {
  _funcs = _.toArray(arguments);
  val    = _funcs.shift();

  _.each(_funcs, function (f) {
    if (!f(val)) {
      console.error("!!! " + to_string(val) + ' should be: ' + to_string(f));
      process.exit(1);
    }
  });

  return val;
}

function to_string(v) {
  if (v === undefined)
    return 'undefined';
  if (v === null)
    return 'null';
  if (v === false)
    return 'false';
  if (v === true)
    return 'true';
  if (_.isFunction(v))
    return (v.name) ? v.name + ' (function)' : v.toString();
  if (_.isString(v))
    return '"' + v + '"';
  if (_.isArray(v))
    return '[' + _.map(_.toArray(v), to_string).join(', ') + '] (Array)';
  if (v.constructor === arguments.constructor)
    return '[' + _.map(_.toArray(v), to_string).join(', ') + '] (arguments)';
  return util.inspect(v);
}

function is_string(v) { return _.isString(v); }
function is_dir(v) { try { return fs.lstatSync(v).isDirectory(); } catch (e) { return false; } }
function is_file(v) { try { return fs.lstatSync(v).isFile(); } catch (e) { return false; } }
function is_blank_string(str) { return _.trim(str).length === 0; }
function is_non_blank_string(str) { return is_string(str) && !is_blank_string(str); }
function identity(v) { return v; }
function is_null_or_undefined(v) { return v === null || v === undefined; }
function is_partial($) { return $('html').length === 0; }
function is_array(v) { return _.isArray(v); }
function is_plain_object(v) { return _.isPlainObject(v); }

function sort_by_length(arr) {
  return arr.sort(function (a,b) {
    return to_length(a) - to_length(b);
  });
}

function is_empty(v) {
  if (is_array(v))
    return v.length === 0;
  if (is_plain_object(v))
    return _.keys(v).length === 0;
  if (v.hasOwnProperty('length') && _.isFinite(v.length))
    return v.length === 0;

  console.error("!!! Unknown .length for: " + to_string(v));
  process.exit(1);
}

function to_length(v) {
  if (is_string(v) || is_array(v))
    return v.length;
  if (_.isPlainObject(v))
    return _.keys(v).length;

  console.error("!!! Invalid value: " + to_string(v));
  process.exit(1);
}

function tag_snippet_to_markup($) {
  var snippets = $('snippet');
  if (is_empty(snippets))
    return $;

  _.each($('snippet'), function (raw) {
    var src      = should_be($(raw).attr('src'), is_non_blank_string);
    var contents = read_file(src);
    $(raw).replaceWith(contents);
  });

  return tag_snippet_to_markup($);
} // === function tag_snippet_to_markup

function read_file(file_path) {
  function read(src) {
    try {
      return fs.readFileSync(src).toString();
    } catch (e) {
      return null;
    }
  } // === function

  var contents;
  var paths = [
    path.join(process.cwd(), file_path),
    path.join(path.dirname(ABOUT('template-path')), file_path),
    path.join(path.dirname(ABOUT('new-file')), file_path)
  ];
  var efforts = paths.slice(0);

  while (!is_string(contents) && !is_empty(paths)) {
    contents = read(paths.shift());
  }

  if (contents)
    return contents;

  console.error('!!! File not found: ' + file_path + ' in: ' + to_string(efforts));
  process.exit(1);
} // === function read_file

function merge_tags(tag, $) {
  var tags = $(tag);
  if (tags.length === 0)
    return $;

  var $first = $($('head').first());
  _.each(tags, function (raw, i) {
    if (i === 0) return;
    var html = $(raw).html();
    $first.append(html);
    $(raw).remove();
  });

  return $;
} // === function merge_tags

function remove_duplicate_tag(tag, $) {
  var tags = $(tag);
  if (is_empty(tags)) return $;
  var cache = [];
  function to_o(raw) {
    return [raw.name, $(raw).attr(), _.trim($(raw).html() || "")];
  }
  _.each(tags, function (raw, i) {
    var o = to_o(raw);
    if (_.find(cache, function (oo) { return _.isEqual(oo, o); })) {
      $(raw).remove();
    } else {
      cache.push(o);
    }
  });
  return $;
} // === function

<commit_msg>Added: copy js/css files over to public-dir<commit_after>"use strict";
/* jshint evil : true, esnext: true, globalstrict: true, undef: true */
/* global _ : true, console, require, process  */

const _       = require('lodash');
const cheerio = require('cheerio');
const Hogan   = require('hogan.js');
const fs      = require('fs');
const util    = require('util');
const path    = require('path');
const he      = require('he');
const SNIPPET_REUSE_TAGS = ['head', 'tail', 'top', 'bottom'];
const FILES_USED = [];

var args     = process.argv.slice(2);

switch (args.length) {
  case 3: break;
  default:
    console.error(to_string(args));
    console.error("!!! arguments.length incorrect. Try: template_file  output_dir  public_path");
    process.exit(1);
}

var public_dir = should_be(args.pop(), is_string);
var dir        = should_be(args.pop(), is_dir);
var template   = should_be(args.pop(), is_file);

if (path.basename(template).match(/^_+\./)) {
  console.error('!!! Template is a partial: ' + template);
  process.exit(1);
}

var name              = path.basename(template, '.html');
var template_contents = read_and_cache_file_name(template);
var $template         = cheerio.load(template_contents, {recognizeSelfClosing: true});
var has_conditionals  = $template('when').length > 0;
$template = var_pipeline(

  $template,

  tag_snippet_to_markup,

  scripts_to_tag,
  styles_to_tag,
  copy_files_to_public, // .css, .js files
  tag_template_to_script,

  to_func(merge_tags,'head'),
  to_func(merge_tags,'tail'),
  to_func(merge_tags,'top'),
  to_func(merge_tags,'bottom'),

  to_func(remove_duplicate_tag,'link'),
  to_func(remove_duplicate_tag,'script'),
  to_func(remove_duplicate_tag,'meta'),

  conditionals_to_files,
  markup_to_file
);

// === Finish writing file.

function ABOUT(key) { // === Function that returns state.
  switch (key) {
    case 'template':         return template;
    case 'template-dir':     return path.dirname(template);
    case 'template-path':    return template;
    case 'name':             return name;
    case 'dir':              return dir;
    case 'new-file':         return dir + '/' + _.compact([name, arguments[1]]).join('-');
    case 'public-dir':       return public_dir;
    case 'json-file':        return path.join(ABOUT('dir'), "conditions.json");

    default:
      error("!!! Unknown key: " + key);
  }
}

function conditionals_to_files($) {
  let conds = tag_when_to_object($);
  if (is_empty(conds))
    return $;

  merge_and_write_conds(conds);
  conds.$whens.remove();

  return $;
} // === conditionals_to_files

function error(msg) {
  console.error(msg);
  process.exit(1);
}

function to_mustache(html) {
  return Hogan.compile(html, {asString: 1, delimiters: '[[ ]]'});
}

function get_comments($_) {
  return _.compact(_.map($_.contents(), function (node) {
    if (node.type === 'comment')
      return node.data;
  }));
}

function get_inline_vars(html) {
  var $ = cheerio(html);
  var attrs = {};
  _.each(get_comments($), function (data) {
    var lines  = data.split("\n");
    var key    = _.trim(lines.shift());
    attrs[key] = _.trim(lines.join("\n"));
  });

  return(attrs);
}

function compiled_to_compiler(code) {
  var f = new Function('Hogan', 'return new Hogan.Template(' + code + ');' );
  return f(Hogan);
}

function cheerio_to_mustache_to_html($) {
  var mustache        = to_mustache($.html());
  var inline_vars     = _.extend({}, get_inline_vars($.html()));

  return tag_template_to_script(
    compiled_to_compiler(mustache).render(inline_vars)
  );
} // === mustache_to_html

// ===  "template" tags can be deeply nested,
// so we process the inner-most ones first,
// then move on to the outer ones.
function tag_template_to_script($) {
  let tags = $('template');

  // === If no tags, we are done processing:
  if (tags.length === 0)
    return $;

  // === Find the inner-most (ie nested) template
  // tag and process it:
  let raw = _.find(tags, function (r) {
    return $('template', r).length === 0;
  });

  let type = $(raw).attr('type');
  if (!type || _.trim(type) === '')
    $(raw).attr('type', "application/template");
  let escaped = he.encode($(raw).html() || '', { useNamedReferences: false });
  $(raw).text(escaped);

  raw.name = "script";

  // === Recurse to handle outer template tags:
  return tag_template_to_script($);
}

function rel_path(file) {
  var public_dir = path.resolve(ABOUT('public-dir'));
  var full       = path.resolve(file);
  var fin        = full.replace(public_dir, '');
  if (fin.indexOf('/') !== 0)
    fin = '/' + fin;
  return fin;
}

function styles_to_tag($) {
  var new_path = ABOUT('new-file', 'style.css');
  var contents = map_to_html_and_remove($, $('style'));

  if (is_blank_string(contents))
    return $;

  fs.writeFileSync(new_path, contents);

  return append_to_tag(
    'head',
    $,
    '<link rel="stylesheet" type="text/css" href="' + rel_path(new_path) + '" />'
  );
}

function scripts_to_tag($) {
  var new_path = ABOUT('new-file', 'script.js');
  var contents = map_to_html_and_remove($, $('script'));

  if (is_blank_string(contents))
    return $;

  fs.writeFileSync(new_path, contents);

  return append_to_tag(
    'bottom',
    $,
    '<script type="application/javascript" src="' + rel_path(new_path)  + '"></script>'
  );
} // === scripts_to_tag

function map_to_html_and_remove($, coll) {
  return _.compact(_.map(coll, function (raw) {
    var html = $(raw).html();
    $(raw).remove();
    return html;
  })).join("\n");
}

function append_to_tag(tag_name, $, html) {
  var target = $(tag_name);
  if (!target[0]) {
    $.root().prepend('<' + tag_name + '></' + tag_name + '>');
    target = $(tag_name);
  }
  target.append(html);
  return $;
} // === append_to_tag

function markup_to_file($) {
  fs.writeFileSync(
    ABOUT('new-file') + '.html',
    $.html()
  );
  return $;
}

// === Used to help other functions check if
// file has already been used before. Counterpart
// is `read_and_cache_file_name`.
function is_file_loaded(file) {
  return _.includes(FILES_USED, fs.realpathSync(file));
}

function read_and_cache_file_name(file) {
  let canon = fs.realpathSync(file);
  if (!_.includes(FILES_USED, canon))
    FILES_USED.push(canon);
  return fs.readFileSync(file).toString();
}

function var_pipeline() {
  var funcs = _.toArray(arguments);
  var v     = funcs.shift();

  return _.reduce(funcs, function (acc, f) {
    return f(acc);
  }, v);
}

function log(_args) {
  return console.log.apply(console, arguments);
}

function log_and_return(v) {
  log(v);
  return v;
}

function to_func_first() {
  var args = _.toArray(arguments);
  var func = args.shift();

  return function () {
    return func.apply( null, _.toArray(arguments).concat(args));
  };
}

function to_func() {
  var args = _.toArray(arguments);
  var func = args.shift();

  return function () {
    return func.apply(
      null,
      [].concat(args).concat(_.toArray(arguments))
    );
  };
}

function read_conds() {
  var file = ABOUT('json-file');
  if (!is_file(file))
    return {};
  var raw = fs.readFileSync(file).toString();
  if (is_blank_string(raw))
    return {};
  return JSON.parse(raw);
}

function merge_and_write_conds(new_conds) {
  var conds = read_conds();
  conds[ABOUT('name')] = new_conds.conditions;
  fs.writeFileSync(ABOUT('json-file'), JSON.stringify(conds));
}

function tag_when_to_object($) {
  let conds = {};
  let $whens = conds.$whens = $('when');
  if (is_empty($whens))
    return {};

  conds.conditions = _.reduce($('val', $whens), function (vals, raw_val) {
    let $val = $(raw_val);
    var name = should_be(_.trim($val.attr('name')), is_non_blank_string);
    var val  = should_be(_.trim($val.attr('val')), is_non_blank_string);
    vals[name] = val;
    return vals;
  }, {});

  return conds;
}

function should_be(val, _funcs) {
  _funcs = _.toArray(arguments);
  val    = _funcs.shift();

  _.each(_funcs, function (f) {
    if (!f(val)) {
      console.error("!!! " + to_string(val) + ' should be: ' + to_string(f));
      process.exit(1);
    }
  });

  return val;
}

function to_string(v) {
  if (v === undefined)
    return 'undefined';
  if (v === null)
    return 'null';
  if (v === false)
    return 'false';
  if (v === true)
    return 'true';
  if (_.isFunction(v))
    return (v.name) ? v.name + ' (function)' : v.toString();
  if (_.isString(v))
    return '"' + v + '"';
  if (_.isArray(v))
    return '[' + _.map(_.toArray(v), to_string).join(', ') + '] (Array)';
  if (v.constructor === arguments.constructor)
    return '[' + _.map(_.toArray(v), to_string).join(', ') + '] (arguments)';
  return util.inspect(v);
}

function is_string(v) { return _.isString(v); }
function is_dir(v) { try { return fs.lstatSync(v).isDirectory(); } catch (e) { return false; } }
function is_file(v) { try { return fs.lstatSync(v).isFile(); } catch (e) { return false; } }
function is_blank_string(str) { return _.trim(str).length === 0; }
function is_non_blank_string(str) { return is_string(str) && !is_blank_string(str); }
function identity(v) { return v; }
function is_null_or_undefined(v) { return v === null || v === undefined; }
function is_partial($) { return $('html').length === 0; }
function is_array(v) { return _.isArray(v); }
function is_plain_object(v) { return _.isPlainObject(v); }

function sort_by_length(arr) {
  return arr.sort(function (a,b) {
    return to_length(a) - to_length(b);
  });
}

function is_empty(v) {
  if (is_array(v))
    return v.length === 0;
  if (is_plain_object(v))
    return _.keys(v).length === 0;
  if (v.hasOwnProperty('length') && _.isFinite(v.length))
    return v.length === 0;

  console.error("!!! Unknown .length for: " + to_string(v));
  process.exit(1);
}

function to_length(v) {
  if (is_string(v) || is_array(v))
    return v.length;
  if (_.isPlainObject(v))
    return _.keys(v).length;

  console.error("!!! Invalid value: " + to_string(v));
  process.exit(1);
}

function tag_snippet_to_markup($) {
  var snippets = $('snippet');
  if (is_empty(snippets))
    return $;

  _.each($('snippet'), function (raw) {
    var src      = should_be($(raw).attr('src'), is_non_blank_string);
    var contents = read_file(src);
    $(raw).replaceWith(contents);
  });

  return tag_snippet_to_markup($);
} // === function tag_snippet_to_markup

function read_file(file_path) {
  function read(src) {
    try {
      return fs.readFileSync(src).toString();
    } catch (e) {
      return null;
    }
  } // === function

  var contents;
  var paths = [
    path.join(process.cwd(), file_path),
    path.join(path.dirname(ABOUT('template-path')), file_path),
    path.join(path.dirname(ABOUT('new-file')), file_path)
  ];
  var efforts = paths.slice(0);

  while (!is_string(contents) && !is_empty(paths)) {
    contents = read(paths.shift());
  }

  if (contents)
    return contents;

  console.error('!!! File not found: ' + file_path + ' in: ' + to_string(efforts));
  process.exit(1);
} // === function read_file

function merge_tags(tag, $) {
  var tags = $(tag);
  if (tags.length === 0)
    return $;

  var $first = $($('head').first());
  _.each(tags, function (raw, i) {
    if (i === 0) return;
    var html = $(raw).html();
    $first.append(html);
    $(raw).remove();
  });

  return $;
} // === function merge_tags

function remove_duplicate_tag(tag, $) {
  var tags = $(tag);
  if (is_empty(tags)) return $;
  var cache = [];
  function to_o(raw) {
    return [raw.name, $(raw).attr(), _.trim($(raw).html() || "")];
  }
  _.each(tags, function (raw, i) {
    var o = to_o(raw);
    if (_.find(cache, function (oo) { return _.isEqual(oo, o); })) {
      $(raw).remove();
    } else {
      cache.push(o);
    }
  });
  return $;
} // === function

function copy_files_to_public($) {
  let files = filter_files(ABOUT('template-dir'), /(.+)(\.css|\.js)$/);
  _.each(files, function (orig) {
    fs.writeFileSync(
      ABOUT('new-file') + '.' + path.basename(orig),
      fs.readFileSync(orig)
    );
  });
  return $;
} // === function copy_files_to_public

function filter_files(dir, pattern) {
  let files = _.map(
    fs.readdirSync(dir),
    function (f) { return path.join(dir, f); }
  );
  return _.filter(files, function (f) { return f.match(pattern); } );
}

<|endoftext|>


<commit_before>const ee = require('ee')
const {map} = require('rx/operators')
const {calculateIndex} = require('sepal/ee/optical/indexes')

const imageFactory = require('sepal/ee/imageFactory')
const {zip} = require('rx')

const classify =
    ({
        model: {
            inputImagery: {images: imageRecipes},
            trainingData: {eeTable, eeTableColumn},
            auxiliaryImagery = [],
            scale
        }
    }) => {
        const referenceData = flushCache(ee.FeatureCollection(eeTable))
        // TODO: Verify that geometry has training data - where and when?

        return {
            getImage$() {
                return zip(
                    ...imageRecipes.map(recipe => toImage$(recipe, auxiliaryImagery))
                ).pipe(
                    map(images => {
                        const imageToClassify = ee.Image(images)
                        const trainingData = imageToClassify.sampleRegions({
                            collection: referenceData,
                            properties: [eeTableColumn],
                            scale: scale || imageToClassify.select(0).projection().nominalScale()
                        })
                        const classifier = ee.Classifier.randomForest(25)
                            .train(trainingData, eeTableColumn)
                        return imageToClassify
                            .classify(classifier.setOutputMode('CLASSIFICATION'))
                            .rename(['class'])
                    })
                )
            },
            getVisParams$() {
                return ee.getInfo$(
                    referenceData.reduceColumns({
                        reducer: ee.Reducer.minMax(),
                        selectors: [eeTableColumn]
                    })
                ).pipe(
                    map(({min, max}) => ({
                        min, max, palette: colors.slice(0, max - min + 1).join(',')
                    })
                    )
                )
            },
            getGeometry$() {
                // return inputImagery[0].getGeometry$() // [TODO] ?
            }
        }
    }

const toImage$ = (recipe, auxiliaryImagery) =>
    imageFactory(recipe).getImage$().pipe(
        map(image => addCovariates(image, recipe.bandSetSpecs, auxiliaryImagery))
    )

const addCovariates = (image, bandSetSpecs, auxiliaryImagery) => {
    return ee.Image(
        bandSetSpecs.map(({type, included, operation}) => {
            switch (type) {
            case 'IMAGE_BANDS':
                return image.selectExisting(included)
            case 'PAIR_WISE_EXPRESSION':
                return combinePairwise(image, included, operation)
            case 'INDEXES':
                return calculateIndexes(image, included)
            }
        })
    ).addBands(
        auxiliaryImagery.length && getAuxiliaryImagery(auxiliaryImagery)
    ).updateMask(
        image.mask().reduce(ee.Reducer.max())
    )

}

const getAuxiliaryImagery = auxiliaryImagery =>
    ee.Image(
        auxiliaryImagery.map(type => {
            switch (type) {
            case 'LATITUDE':
                return createLatitudeImage()
            case 'TERRAIN':
                return createTerrainImage()
            case 'WATER':
                return createSurfaceWaterImage()
            }
        })
    )

const createLatitudeImage = () =>
    ee.Image.pixelLonLat().select('latitude').float()

const createTerrainImage = () => {
    const elevation = ee.Image('USGS/SRTMGL1_003')
    const topography = ee.Algorithms.Terrain(elevation)
    const aspectRad = topography.select(['aspect']).multiply(ee.Number(Math.PI).divide(180))
    const eastness = aspectRad.sin().rename(['eastness']).float()
    const northness = aspectRad.cos().rename(['northness']).float()
    return topography.select(['elevation', 'slope', 'aspect'])
        .addBands(eastness)
        .addBands(northness)
}

const createSurfaceWaterImage = () => {
    const water = ee.Image('JRC/GSW1_0/GlobalSurfaceWater').unmask()
    const transitions = [
        'no_change',
        'permanent',
        'new_permanent',
        'lost_permanent',
        'seasonal',
        'new_seasonal',
        'lost_seasonal',
        'seasonal_to_permanent',
        'permanent_to_seasonal',
        'ephemeral_permanent',
        'ephemeral_seasonal'
    ]
    const transitionMasks = ee.Image(
        transitions.map((transition, i) =>
            water.select('transition').eq(i).rename(`water_${transition}`))
    )

    return water
        .select(
            ['occurrence', 'change_abs', 'change_norm', 'seasonality', 'max_extent'],
            ['water_occurrence', 'water_change_abs', 'water_change_norm', 'water_seasonality', 'water_max_extent']
        )
        .addBands(transitionMasks)
}

const combinePairwise = (image, bands, operation) => {
    const operations = {
        RATIO: 'b1 / b2',
        NORMALIZED_DIFFERENCE: '(b1 - b2) / (b1 + b2)',
        DIFFERENCE: 'b1 - b2',
        DISTANCE: 'atan2(b1, b2) / PI',
        ANGLE: 'hypot(b1, b2)',
    }
    return image
        .selectExisting(bands)
        .combinePairwise(operations[operation], `_${operation.toLowerCase()}`)
}

const calculateIndexes = (image, indexNames) =>
    ee.Image(
        indexNames.map(indexName =>
            calculateIndex(image, indexName)
        )
    )

const flushCache = features =>
    features.map(feature => feature
        .set('__flush_cache__', Math.random())
        .copyProperties(feature)
    )

const colors = [
    'FFB300',  // Vivid Yellow
    '803E75',  // Strong Purple
    'FF6800',  // Vivid Orange
    'A6BDD7',  // Very Light Blue
    'C10020',  // Vivid Red
    'CEA262',  // Grayish Yellow
    '817066',  // Medium Gray
    '007D34',  // Vivid Green
    'F6768E',  // Strong Purplish Pink
    '00538A',  // Strong Blue
    'FF7A5C',  // Strong Yellowish Pink
    '53377A',  // Strong Violet
    'FF8E00',  // Vivid Orange Yellow
    'B32851',  // Strong Purplish Red
    'F4C800',  // Vivid Greenish Yellow
    '7F180D',  // Strong Reddish Brown
    '93AA00',  // Vivid Yellowish Green
    '593315',  // Deep Yellowish Brown
    'F13A13',  // Vivid Reddish Orange
    '232C16',  // Dark Olive Green
]

module.exports = classify
<commit_msg>Sampled image to classify at scale of 1 if not explicitly specified.<commit_after>const ee = require('ee')
const {map} = require('rx/operators')
const {calculateIndex} = require('sepal/ee/optical/indexes')
const imageFactory = require('sepal/ee/imageFactory')
const {zip} = require('rx')

const classify =
    ({
        model: {
            inputImagery: {images: imageRecipes},
            trainingData: {eeTable, eeTableColumn},
            auxiliaryImagery = [],
            scale
        }
    }) => {
        const referenceData = flushCache(ee.FeatureCollection(eeTable))
        return {
            getImage$() {
                return zip(
                    ...imageRecipes.map(recipe => toImage$(recipe, auxiliaryImagery))
                ).pipe(
                    map(images => {
                        const imageToClassify = ee.Image(images)
                        const trainingData = imageToClassify.sampleRegions({
                            collection: referenceData,
                            properties: [eeTableColumn],
                            scale: scale || 1
                        })
                        const classifier = ee.Classifier.randomForest(25)
                            .train(trainingData, eeTableColumn)
                        return imageToClassify
                            .classify(classifier.setOutputMode('CLASSIFICATION'))
                            .rename(['class'])
                    })
                )
            },
            getVisParams$() {
                return ee.getInfo$(
                    referenceData.reduceColumns({
                        reducer: ee.Reducer.minMax(),
                        selectors: [eeTableColumn]
                    })
                ).pipe(
                    map(({min, max}) => ({
                        min, max, palette: colors.slice(0, max - min + 1).join(',')
                    })
                    )
                )
            },
            getGeometry$() {
                // return inputImagery[0].getGeometry$() // [TODO] ?
            }
        }
    }

const toImage$ = (recipe, auxiliaryImagery) =>
    imageFactory(recipe).getImage$().pipe(
        map(image => addCovariates(image, recipe.bandSetSpecs, auxiliaryImagery))
    )

const addCovariates = (image, bandSetSpecs, auxiliaryImagery) => {
    return ee.Image(
        bandSetSpecs.map(({type, included, operation}) => {
            switch (type) {
            case 'IMAGE_BANDS':
                return image.selectExisting(included)
            case 'PAIR_WISE_EXPRESSION':
                return combinePairwise(image, included, operation)
            case 'INDEXES':
                return calculateIndexes(image, included)
            }
        })
    ).addBands(
        auxiliaryImagery.length && getAuxiliaryImagery(auxiliaryImagery)
    ).updateMask(
        image.mask().reduce(ee.Reducer.max())
    )

}

const getAuxiliaryImagery = auxiliaryImagery =>
    ee.Image(
        auxiliaryImagery.map(type => {
            switch (type) {
            case 'LATITUDE':
                return createLatitudeImage()
            case 'TERRAIN':
                return createTerrainImage()
            case 'WATER':
                return createSurfaceWaterImage()
            }
        })
    )

const createLatitudeImage = () =>
    ee.Image.pixelLonLat().select('latitude').float()

const createTerrainImage = () => {
    const elevation = ee.Image('USGS/SRTMGL1_003')
    const topography = ee.Algorithms.Terrain(elevation)
    const aspectRad = topography.select(['aspect']).multiply(ee.Number(Math.PI).divide(180))
    const eastness = aspectRad.sin().rename(['eastness']).float()
    const northness = aspectRad.cos().rename(['northness']).float()
    return topography.select(['elevation', 'slope', 'aspect'])
        .addBands(eastness)
        .addBands(northness)
}

const createSurfaceWaterImage = () => {
    const water = ee.Image('JRC/GSW1_0/GlobalSurfaceWater').unmask()
    const transitions = [
        'no_change',
        'permanent',
        'new_permanent',
        'lost_permanent',
        'seasonal',
        'new_seasonal',
        'lost_seasonal',
        'seasonal_to_permanent',
        'permanent_to_seasonal',
        'ephemeral_permanent',
        'ephemeral_seasonal'
    ]
    const transitionMasks = ee.Image(
        transitions.map((transition, i) =>
            water.select('transition').eq(i).rename(`water_${transition}`))
    )

    return water
        .select(
            ['occurrence', 'change_abs', 'change_norm', 'seasonality', 'max_extent'],
            ['water_occurrence', 'water_change_abs', 'water_change_norm', 'water_seasonality', 'water_max_extent']
        )
        .addBands(transitionMasks)
}

const combinePairwise = (image, bands, operation) => {
    const operations = {
        RATIO: 'b1 / b2',
        NORMALIZED_DIFFERENCE: '(b1 - b2) / (b1 + b2)',
        DIFFERENCE: 'b1 - b2',
        DISTANCE: 'atan2(b1, b2) / PI',
        ANGLE: 'hypot(b1, b2)',
    }
    return image
        .selectExisting(bands)
        .combinePairwise(operations[operation], `_${operation.toLowerCase()}`)
}

const calculateIndexes = (image, indexNames) =>
    ee.Image(
        indexNames.map(indexName =>
            calculateIndex(image, indexName)
        )
    )

const flushCache = features =>
    features.map(feature => feature
        .set('__flush_cache__', Math.random())
        .copyProperties(feature)
    )

const colors = [
    'FFB300',  // Vivid Yellow
    '803E75',  // Strong Purple
    'FF6800',  // Vivid Orange
    'A6BDD7',  // Very Light Blue
    'C10020',  // Vivid Red
    'CEA262',  // Grayish Yellow
    '817066',  // Medium Gray
    '007D34',  // Vivid Green
    'F6768E',  // Strong Purplish Pink
    '00538A',  // Strong Blue
    'FF7A5C',  // Strong Yellowish Pink
    '53377A',  // Strong Violet
    'FF8E00',  // Vivid Orange Yellow
    'B32851',  // Strong Purplish Red
    'F4C800',  // Vivid Greenish Yellow
    '7F180D',  // Strong Reddish Brown
    '93AA00',  // Vivid Yellowish Green
    '593315',  // Deep Yellowish Brown
    'F13A13',  // Vivid Reddish Orange
    '232C16',  // Dark Olive Green
]

module.exports = classify
<|endoftext|>


<commit_before>angular.module('fundoo.services', []).factory('createDialog', ["$document", "$compile", "$rootScope", "$controller", "$timeout",
  function ($document, $compile, $rootScope, $controller, $timeout) {
    var defaults = {
      id: null,
      template: null,
      templateUrl: null,
      title: 'Default Title',
      backdrop: true,
      success: {label: 'OK', fn: null},
      cancel: {label: 'Close', fn: null},
      controller: null, //just like route controller declaration
      backdropClass: "modal-backdrop",
      backdropCancel: true,
      footerTemplate: null,
      hideFooter:false,
      modalClass: "modal",
      cancelOnEsc:true,
      css: {
        top: '100px',
        left: '30%',
        margin: '0 auto'
      }
    };
    var body = $document.find('body');

    return function Dialog(templateUrl/*optional*/, options, passedInLocals) {

      // Handle arguments if optional template isn't provided.
      if(angular.isObject(templateUrl)){
        passedInLocals = options;
        options = templateUrl;
      } else {
        options.templateUrl = templateUrl;
      }

      options = angular.extend({}, defaults, options); //options defined in constructor

      var key;
      var idAttr = options.id ? ' id="' + options.id + '" ' : '';
      var defaultFooter = '<button class="btn" ng-click="$modalCancel()">{{$modalCancelLabel}}</button>' +
        '<button class="btn btn-primary" ng-click="$modalSuccess()">{{$modalSuccessLabel}}</button>';
      var footerTemplate = options.hideFooter ? '' : '
' + (options.footerTemplate || defaultFooter) + '
';
      var modalBody = (function(){
        if(options.template){
          if(angular.isString(options.template)){
            // Simple string template
            return '
' + options.template + '
';
          } else {
            // jQuery/JQlite wrapped object
            return '
' + options.template.html() + '
';
          }
        } else {
          // Template url
          return '

'
        }
      })();
      //We don't have the scope we're gonna use yet, so just get a compile function for modal
      var modalEl = angular.element(
                '
' +
                    '
' +
                    '
' +
                    '
' +
                    '        <button type="button" class="close" ng-click="$modalCancel()">×</button>' +
                    '
{{$title}}
' +
                    '
' +
                    modalBody +
                    footerTemplate +
                    '
' +
                    '
' +
                    '
');

      for(key in options.css) {
        modalEl.css(key, options.css[key]);
      }
      var divHTML = "
";
      var backdropEl = angular.element(divHTML);
      backdropEl.addClass(options.backdropClass);
      backdropEl.addClass('fade in');

      var handleEscPressed = function (event) {
        if (event.keyCode === 27 && options.cancelOnEsc) {
          scope.$modalCancel();
        }
      };

      var closeFn = function () {
        body.unbind('keydown', handleEscPressed);
        modalEl.remove();
        if (options.backdrop) {
          backdropEl.remove();
        }
      };

      body.bind('keydown', handleEscPressed);

      var ctrl, locals,
        scope = options.scope || $rootScope.$new();

      scope.$title = options.title;
      scope.$modalClose = closeFn;
      scope.$modalCancel = function () {
        var callFn = options.cancel.fn || closeFn;
        callFn.call(this);
        scope.$modalClose();
      };
      scope.$modalSuccess = function () {
        var callFn = options.success.fn || closeFn;
        callFn.call(this);
        scope.$modalClose();
      };
      scope.$modalSuccessLabel = options.success.label;
      scope.$modalCancelLabel = options.cancel.label;

      if (options.controller) {
        locals = angular.extend({$scope: scope}, passedInLocals);
        ctrl = $controller(options.controller, locals);
        // Yes, ngControllerController is not a typo
        modalEl.contents().data('$ngControllerController', ctrl);
      }

      $compile(modalEl)(scope);
      $compile(backdropEl)(scope);
      body.append(modalEl);
      if (options.backdrop) body.append(backdropEl);

      $timeout(function () {
        modalEl.addClass('in');
      }, 200);
    };
  }]);
<commit_msg>Do not close window if function return is false<commit_after>angular.module('fundoo.services', []).factory('createDialog', ["$document", "$compile", "$rootScope", "$controller", "$timeout",
  function ($document, $compile, $rootScope, $controller, $timeout) {
    var defaults = {
      id: null,
      template: null,
      templateUrl: null,
      title: 'Default Title',
      backdrop: true,
      success: {label: 'OK', fn: null},
      cancel: {label: 'Close', fn: null},
      controller: null, //just like route controller declaration
      backdropClass: "modal-backdrop",
      backdropCancel: true,
      footerTemplate: null,
      hideFooter:false,
      modalClass: "modal",
      cancelOnEsc:true,
      css: {
        top: '100px',
        left: '30%',
        margin: '0 auto'
      }
    };
    var body = $document.find('body');

    return function Dialog(templateUrl/*optional*/, options, passedInLocals) {

      // Handle arguments if optional template isn't provided.
      if(angular.isObject(templateUrl)){
        passedInLocals = options;
        options = templateUrl;
      } else {
        options.templateUrl = templateUrl;
      }

      options = angular.extend({}, defaults, options); //options defined in constructor

      var key;
      var idAttr = options.id ? ' id="' + options.id + '" ' : '';
      var defaultFooter = '<button class="btn" ng-click="$modalCancel()">{{$modalCancelLabel}}</button>' +
        '<button class="btn btn-primary" ng-click="$modalSuccess()">{{$modalSuccessLabel}}</button>';
      var footerTemplate = options.hideFooter ? '' : '
' + (options.footerTemplate || defaultFooter) + '
';
      var modalBody = (function(){
        if(options.template){
          if(angular.isString(options.template)){
            // Simple string template
            return '
' + options.template + '
';
          } else {
            // jQuery/JQlite wrapped object
            return '
' + options.template.html() + '
';
          }
        } else {
          // Template url
          return '

'
        }
      })();
      //We don't have the scope we're gonna use yet, so just get a compile function for modal
      var modalEl = angular.element(
                '
' +
                    '
' +
                    '
' +
                    '
' +
                    '        <button type="button" class="close" ng-click="$modalCancel()">×</button>' +
                    '
{{$title}}
' +
                    '
' +
                    modalBody +
                    footerTemplate +
                    '
' +
                    '
' +
                    '
');

      for(key in options.css) {
        modalEl.css(key, options.css[key]);
      }
      var divHTML = "
";
      var backdropEl = angular.element(divHTML);
      backdropEl.addClass(options.backdropClass);
      backdropEl.addClass('fade in');

      var handleEscPressed = function (event) {
        if (event.keyCode === 27 && options.cancelOnEsc) {
          scope.$modalCancel();
        }
      };

      var closeFn = function () {
        body.unbind('keydown', handleEscPressed);
        modalEl.remove();
        if (options.backdrop) {
          backdropEl.remove();
        }
      };

      body.bind('keydown', handleEscPressed);

      var ctrl, locals,
        scope = options.scope || $rootScope.$new();

      scope.$title = options.title;
      scope.$modalClose = closeFn;
      scope.$modalCancel = function () {
        var callFn = options.cancel.fn || closeFn;
        callFn.call(this);
        scope.$modalClose();
      };
      scope.$modalSuccess = function () {
        var callFn = options.success.fn || closeFn;
        var ret = callFn.call(this);
        console.log(ret);
        if (ret!==false) {
          scope.$modalClose();
        }
      };
      scope.$modalSuccessLabel = options.success.label;
      scope.$modalCancelLabel = options.cancel.label;

      if (options.controller) {
        locals = angular.extend({$scope: scope}, passedInLocals);
        ctrl = $controller(options.controller, locals);
        // Yes, ngControllerController is not a typo
        modalEl.contents().data('$ngControllerController', ctrl);
      }

      $compile(modalEl)(scope);
      $compile(backdropEl)(scope);
      body.append(modalEl);
      if (options.backdrop) body.append(backdropEl);

      $timeout(function () {
        modalEl.addClass('in');
      }, 200);
    };
  }]);
<|endoftext|>


<commit_before>var utils = require('loader-utils')
var path = require('path')
var parse = require('./parser')
var selector = require.resolve('./selector')
var u = require('./utils')
var hash = require('hash-sum')

var rewriterInjectRE = /\b((css|(ng-)?html)(-loader)?(\?[^!]+)?)(?:!|$)/
var rewrites = {
    template: require.resolve('./template-rewrite'),
    style: require.resolve('./style-rewrite')
}

module.exports = function (content) {

    this.cacheable()

    var defaultLoaders = {
        html: 'html-loader',
        css: 'style-loader!css-loader',
        js: 'babel-loader?' + JSON.stringify({
            presets: ['es2015'],
            plugins: ['transform-runtime'],
            comments: false
        })
    }

    var defaultLang = {
        template: 'html',
        style: 'css',
        script: 'js'
    }

    var context = this
    var query = utils.parseQuery(this.query)
    var options = Object.assign({}, this.options.ng, this.ng, query)
    var filePath = this.resourcePath
    var fileName = path.basename(filePath)
    var moduleId = '_ng-' + hash(filePath)

    if (this.options.babel) {
        defaultLoaders.js = 'babel-loader'
    }

    if (this.sourceMap && !this.minimize &&
        options.cssSourceMap != false && process.env.NODE_ENV !== 'production') {
        defaultLoaders.css = 'style-loader!css-loader?sourceMap'
    }

    var loaders = Object.assign({}, defaultLoaders, options.loaders)

    var parts = parse(content, fileName, this.sourceMap)
    var hasLocalStyle = false
    var output = `
        var __comp_script__;
        var __comp_template__;
        var __comp_styles__;
    `
    function getRewrite(type, scoped) {
        var meta = '?id=' + moduleId
        switch (type) {
            case 'template':
                return scoped ? `${rewrites.template}${meta}!` : ''
            case 'style':
                return rewrites.style + (scoped ? `${meta}&scoped=true` : '!')
            default:
                return ''
        }
    }

    function addCssModulesToLoader(loader, part, index) {

        if (!part.module) return loader

        return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) {
            var option = utils.parseQuery($2)

            option.module = true
            option.importLoaders = true
            option.localIdentName = '[hash:base64]'

            if (index !== -1) {
                option.localIdentName += `_${index}`
            }

            return `${$1}?${JSON.stringify(option)}`
        })
    }

    function getLoaderString(type, part, index, scoped) {
        var lang = part.lang || defaultLang[type]
        var loader = loaders[lang]
        var rewrite = getRewrite(type, scoped)
        var injectString = (type === 'script' && query.inject) ? 'inject' : ''
        var templateLoader = require.resolve('./template-loader')

        if (loader != undefined) {
            if (Array.isArray(loader)) {
                loader = u.stringifyLoaders(loader)
            }

            if (type == 'style') {
                loader = addCssModulesToLoader(loader, part, index)
            }

            if (rewriterInjectRE.test(loader)) {
                loader = loader.replace(rewriterInjectRE, (m, $1) => {
                    return u.ensureBand($1) + rewrite
                })
            } else {
                loader = u.ensureBand(loader) + rewrite
            }

            return injectString + u.ensureBand(loader)

        } else {
            switch (type) {
                case 'template':
                    return `${defaultLoaders.html}!${rewrite + templateLoader}?raw&engine=${lang}!`
                case 'style':
                    loader = addCssModulesToLoader(defaultLoaders.css, part, index)
                    return `${loader}!${rewrite + lang}!`
                case 'script':
                    return `${injectString + lang}!`
            }
        }
    }

    function getRequireForImportString(type, req, scoped) {
        return utils.stringifyRequest(
            context, `!!${getLoaderString(type, req, -1, scoped)}${req.src}`
        )
    }

    function getRequireForImport(type, req, scoped) {
        return `require(${getRequireForImportString(type, req, scoped)})`
    }

    var cssModules = {}
    function setCssModule(style, require) {
        if (!style.module) return require
        if (style.module in cssModules) {
            context.emitError(`CSS module name ${style.module} is not unique!`)
            return require
        }

        cssModules[style.module] = true
        return `__comp_styles__["${style.module}"] = require;`
    }

    function getRequire(type, part, index, scoped) {
        return `require(${getRequireString(type, part, index, scoped)})`
    }

    function getSelectorString(type, index) {
        return `${selector}?type=${type}&index=${index}!`
    }

    function getRequireString(type, part, index, scoped) {
        return utils.stringifyRequest(context, [
            '!!', getLoaderString(type, part, index, scoped),
            getSelectorString(type, index || 0),
            utils.getRemainingRequest(context)
        ].join(''))
    }

    parts.styleImports.forEach(function (part) {
        if (part.scoped) hasLocalStyle = true
        if (part.module === '') part.module = '$style'

        var requireString = getRequireForImport(
            'style', part, part.scoped
        )

        output += setCssModule(part, requireString)
    })

    parts.style.forEach(function (style, i) {
        if (style.scoped) hasLocalStyle = true
        if (style.module === '') style.module = '$style'

        var requireString = getRequire(
            'style', style, i, style.scoped, style.module
        )

        output += setCssModule(style, requireString)
    })

    var script
    if (parts.script.length) {
        script = parts.script[0]

        output += `
            __comp_script__ = ${
                script.src
                ? getRequireForImport('string', script, 0)
                : getRequire('script', script, 0)
        }
        `

        if (!this.minimize) {
            output += `
                var invalidModule = Object.keys(__comp_script__).some(function(key) {
                    return key !== 'default' && key !== '__esModule';
                });
                if(invalidModule){
                    console.error("[ng-component-loader] Named exports are not supported in *.ng files.");
                }
            `
        }
    }

    var template
    if (parts.template.length) {
        template = parts.template[0]

        output += `
            __comp_template__ = ${
                template.src
                ? getRequireForImport('template', template, hasLocalStyle)
                : getRequire('template', template, 0, hasLocalStyle)
        }
        `
    }

    var hotId = JSON.stringify(`${moduleId}/${fileName}`)
    var srcFile = JSON.stringify(path.relative(process.cwd(), filePath));
    output += `
        __comp_script__ = __comp_script__ || {};
        if(__comp_script__.__esModule) __comp_script__ = __comp_script__.default;
        __comp_script__.__file = ${srcFile};
        __comp_script__.__id = ${hotId};
        if(__comp_template__){
            if(Array.isArray(__comp_script__)) __comp_script__[1].template = __comp_template__;
            else __comp_script__.template = __comp_template__;
        }
        module.exports.__esModule = true;
        module.exports.default = __comp_script__; `

    if (query.hijacked) {
        output += `
            var hotApi = require('ng-hot-reload-api');

            hotApi.init();
            if(module.hot){
                module.hot.accept(function(e){
                    console.error('[NGC] Error in compilation file. ', e);
                });

                if(!module.hot.data){
                    // register
                    hotApi.register(${hotId}, __comp_script__);
                } else {
                    // update
                    hotApi.update(${hotId}, __comp_script__);
                }
            }
        `
    }

    return output;
}
<commit_msg>Updated<commit_after>var utils = require('loader-utils')
var path = require('path')
var parse = require('./parser')
var selector = require.resolve('./selector')
var u = require('./utils')
var hash = require('hash-sum')

var rewriterInjectRE = /\b((css|(ng-)?html)(-loader)?(\?[^!]+)?)(?:!|$)/
var rewrites = {
    template: require.resolve('./template-rewrite'),
    style: require.resolve('./style-rewrite')
}

module.exports = function (content) {

    this.cacheable()

    var defaultLoaders = {
        html: 'html-loader',
        css: 'style-loader!css-loader',
        js: 'babel-loader?' + JSON.stringify({
            presets: ['es2015'],
            plugins: ['transform-runtime'],
            comments: false
        })
    }

    var defaultLang = {
        template: 'html',
        style: 'css',
        script: 'js'
    }

    var context = this
    var query = utils.parseQuery(this.query)
    var options = Object.assign({}, this.options.ng, this.ng, query)
    var filePath = this.resourcePath
    var fileName = path.basename(filePath)
    var moduleId = '_ng-' + hash(filePath)

    if (this.options.babel) {
        defaultLoaders.js = 'babel-loader'
    }

    if (this.sourceMap && !this.minimize &&
        options.cssSourceMap != false && process.env.NODE_ENV !== 'production') {
        defaultLoaders.css = 'style-loader!css-loader?sourceMap'
    }

    var loaders = Object.assign({}, defaultLoaders, options.loaders)

    var parts = parse(content, fileName, this.sourceMap)
    var hasLocalStyle = false
    var output = `
        var __comp_script__;
        var __comp_template__;
        var __comp_styles__;
    `
    function getRewrite(type, scoped) {
        var meta = '?id=' + moduleId
        switch (type) {
            case 'template':
                return scoped ? `${rewrites.template}${meta}!` : ''
            case 'style':
                return rewrites.style + (scoped ? `${meta}&scoped=true` : '!')
            default:
                return ''
        }
    }

    function addCssModulesToLoader(loader, part, index) {

        if (!part.module) return loader

        return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) {
            var option = utils.parseQuery($2)

            option.module = true
            option.importLoaders = true
            option.localIdentName = '[hash:base64]'

            if (index !== -1) {
                option.localIdentName += `_${index}`
            }

            return `${$1}?${JSON.stringify(option)}`
        })
    }

    function getLoaderString(type, part, index, scoped) {
        var lang = part.lang || defaultLang[type]
        var loader = loaders[lang]
        var rewrite = getRewrite(type, scoped)
        var injectString = (type === 'script' && query.inject) ? 'inject' : ''
        var templateLoader = require.resolve('./template-loader')

        if (loader != undefined) {
            if (Array.isArray(loader)) {
                loader = u.stringifyLoaders(loader)
            }

            if (type == 'style') {
                loader = addCssModulesToLoader(loader, part, index)
            }

            if (rewriterInjectRE.test(loader)) {
                loader = loader.replace(rewriterInjectRE, (m, $1) => {
                    return u.ensureBand($1) + rewrite
                })
            } else {
                loader = u.ensureBand(loader) + rewrite
            }

            return injectString + u.ensureBand(loader)

        } else {
            switch (type) {
                case 'template':
                    return `${defaultLoaders.html}!${rewrite + templateLoader}?raw&engine=${lang}!`
                case 'style':
                    loader = addCssModulesToLoader(defaultLoaders.css, part, index)
                    return `${loader}!${rewrite + lang}!`
                case 'script':
                    return `${injectString + lang}!`
            }
        }
    }

    function getRequireForImportString(type, req, scoped) {
        return utils.stringifyRequest(
            context, `!!${getLoaderString(type, req, -1, scoped)}${req.src}`
        )
    }

    function getRequireForImport(type, req, scoped) {
        return `require(${getRequireForImportString(type, req, scoped)})`
    }

    var cssModules = {}
    function setCssModule(style, require) {
        if (!style.module) return require
        if (style.module in cssModules) {
            context.emitError(`CSS module name ${style.module} is not unique!`)
            return require
        }

        cssModules[style.module] = true
        return `__comp_styles__["${style.module}"] = require;`
    }

    function getRequire(type, part, index, scoped) {
        return `require(${getRequireString(type, part, index, scoped)})`
    }

    function getSelectorString(type, index) {
        return `${selector}?type=${type}&index=${index}!`
    }

    function getRequireString(type, part, index, scoped) {
        return utils.stringifyRequest(context, [
            '!!', getLoaderString(type, part, index, scoped),
            getSelectorString(type, index || 0),
            utils.getRemainingRequest(context)
        ].join(''))
    }

    parts.styleImports.forEach(function (part) {
        if (part.scoped) hasLocalStyle = true
        if (part.module === '') part.module = '$style'

        var requireString = getRequireForImport(
            'style', part, part.scoped
        )

        output += setCssModule(part, requireString)
    })

    parts.style.forEach(function (style, i) {
        if (style.scoped) hasLocalStyle = true
        if (style.module === '') style.module = '$style'

        var requireString = getRequire(
            'style', style, i, style.scoped, style.module
        )

        output += setCssModule(style, requireString)
    })

    var script
    if (parts.script.length) {
        script = parts.script[0]

        output += `
            __comp_script__ = ${
                script.src
                ? getRequireForImport('string', script, 0)
                : getRequire('script', script, 0)
        }
        `

        if (!this.minimize) {
            output += `
                var invalidModule = Object.keys(__comp_script__).some(function(key) {
                    return key !== 'default' && key !== '__esModule';
                });
                if(invalidModule){
                    console.error("[ng-component-loader] Named exports are not supported in *.ng files.");
                }
            `
        }
    }

    var template
    if (parts.template.length) {
        template = parts.template[0]

        output += `
            __comp_template__ = ${
                template.src
                ? getRequireForImport('template', template, hasLocalStyle)
                : getRequire('template', template, 0, hasLocalStyle)
        }
        `
    }

    var hotId = JSON.stringify(`${moduleId}/${fileName}`)
    var srcFile = JSON.stringify(path.relative(process.cwd(), filePath));
    output += `
        __comp_script__ = __comp_script__ || {};
        if(__comp_script__.__esModule) __comp_script__ = __comp_script__.default;
        __comp_script__.__file = ${srcFile};
        __comp_script__.__id = ${hotId};
        if(__comp_template__){
            if(Array.isArray(__comp_script__)) __comp_script__[1].template = __comp_template__;
            else __comp_script__.template = __comp_template__;
        }
        module.exports.__esModule = true;
        module.exports.default = __comp_script__; `

    if (query.hijacked) {
        output += `
            if(module.hot) {
                var hotApi = require('ng-hot-reload-api');

                hotApi.init();

                if (!api.compatible) {
                    throw new Error('vue-hot-reload-api is not compatible with the version of Vue you are using.')
                }

                module.hot.accept(function(e){
                    console.error('[NGC] Error in compilation file. ', e);
                });

                if(!module.hot.data){
                    // register
                    hotApi.register(${hotId}, __comp_script__);
                } else {
                    // update
                    hotApi.update(${hotId}, __comp_script__);
                }
            }
        `
    }

    return output;
}
<|endoftext|>


<commit_before>import PropTypes from "prop-types";
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import { createPortal } from "react-dom";
import { useTransition, animated } from "@react-spring/web";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";
import { useDisableBodyScroll } from "@agir/lib/utils/hooks";
import { useDownloadBanner } from "@agir/front/app/hooks.js";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

const springConfig = {
  tension: 160,
  friction: 30,
};

const slideInTransitions = {
  right: {
    config: springConfig,
    from: { right: 0, transform: "translateX(100%)" },
    enter: { transform: "translateX(0%)" },
    leave: { transform: "translateX(100%)" },
  },
  left: {
    config: springConfig,
    from: { left: 0, transform: "translateX(-100%)" },
    enter: { transform: "translateX(0%)" },
    leave: { transform: "translateX(-100%)" },
  },
};

const fadeInTransition = {
  config: springConfig,
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
};

const Overlay = styled(animated.div)`
  width: 100%;
  height: 100%;
  max-height: 100%;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(164, 159, 173, 0.6);
  cursor: ${({ onClick }) => (onClick ? "pointer" : "default")};
  z-index: 1;
  will-change: opacity;
`;

const AnimatedOverlay = (props) => {
  const { shouldShow = false, onClick } = props;
  const transitions = useTransition(!!shouldShow, fadeInTransition);

  return transitions((style, item) =>
    item ? <Overlay style={style} onClick={onClick} /> : null
  );
};

AnimatedOverlay.propTypes = {
  shouldShow: PropTypes.bool,
  onClick: PropTypes.func,
  className: PropTypes.string,
};

export const StyledBackButton = styled.button`
  &,
  &:hover,
  &:focus {
    background-color: transparent;
    border: none;
    box-shadow: none;
    padding: 0 0 0.5rem;
    margin: 0;
    text-align: left;
    cursor: pointer;
  }
  &:hover,
  &:focus {
    opacity: 0.75;
  }
`;

const PanelContent = styled(animated.aside)`
  position: fixed;
  z-index: ${style.zindexPanel};
  height: 100vh;
  max-height: -webkit-fill-available;
  overflow: auto;
  top: 0;
  ${({ $position }) => `${$position}: 0;`}
  display: inline-block;
  width: auto;
  min-width: 600px;
  background-color: white;
  margin: 0;
  padding: 2rem 1.5rem;
  will-change: transform;

  @media (max-width: ${style.collapse}px) {
    display: block;
    width: 100%;
    min-width: 100%;
    padding: 1.5rem;
  }

  & > h4 {
    margin: 0;
    padding: 0 0 0.5rem;
  }
`;

const PanelFrame = styled.div`
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  max-height: -webkit-fill-available;
  overflow: hidden;
  z-index: ${style.zindexPanel};
  pointer-events: ${({ $open }) => ($open ? "auto" : "none")};

  @media (max-width: ${style.collapse}px) {
    display: block;
    width: 100%;
    min-width: 100%;
    z-index: ${({ $isBehindTopBar }) =>
      $isBehindTopBar ? style.zindexTopBar - 1 : style.zindexPanel};

    ${PanelContent} {
      padding-top: ${({ $isBehindTopBar, $hasDownloadBanner }) => {
        if ($isBehindTopBar && $hasDownloadBanner) {
          return "136px";
        }
        if ($isBehindTopBar) {
          return "56px";
        }
        return "1.5rem";
      }};
    }
  }
`;

const getFocusableElements = (parent) => {
  if (!parent) {
    return [];
  }
  return [
    ...parent.querySelectorAll(
      'a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select'
    ),
  ].filter(
    (elem) =>
      !elem.disabled &&
      !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length)
  );
};

const useFocusTrap = (shouldShow) => {
  const panelRef = useRef(null);
  const handleTabKey = useCallback((e) => {
    if (!panelRef.current) {
      return;
    }
    const focusablePanelElements = getFocusableElements(panelRef.current);
    const firstElement = focusablePanelElements[0];
    const lastElement =
      focusablePanelElements[focusablePanelElements.length - 1];
    if (!e.shiftKey && document.activeElement === lastElement) {
      firstElement.focus();
      e.preventDefault();
    }
    if (e.shiftKey && document.activeElement === firstElement) {
      lastElement.focus();
      e.preventDefault();
    }
  }, []);

  const keyListenersMap = useMemo(
    () => new Map([[9, handleTabKey]]),
    [handleTabKey]
  );

  useEffect(() => {
    const keyListener = (e) => {
      const listener = keyListenersMap.get(e.keyCode);
      return listener && listener(e);
    };
    if (shouldShow && panelRef.current) {
      document.addEventListener("keydown", keyListener);
      const firstElement = getFocusableElements(panelRef.current)[0];
      firstElement ? firstElement.focus() : panelRef.current.focus();
    }

    return () => document.removeEventListener("keydown", keyListener);
  }, [shouldShow, keyListenersMap]);

  return panelRef;
};

const Panel = (props) => {
  const {
    shouldShow = false,
    position = "right",
    title,
    children,
    onClose,
    onBack,
    noScroll,
    isBehindTopBar,
    className,
    style,
  } = props;

  const [hasDownloadBanner] = useDownloadBanner();

  const panelRef = useDisableBodyScroll(noScroll, shouldShow);
  const panelContentRef = useFocusTrap(shouldShow);

  const slideInTransition =
    slideInTransitions[position] || slideInTransitions.right;
  const transitions = useTransition(!!shouldShow, slideInTransition);

  const panelParent = useMemo(() => {
    const panelParent = document.createElement("div");
    panelParent.className = "panel-root";
    document.body.appendChild(panelParent);

    return panelParent;
  }, []);

  useEffect(
    () => () => {
      panelParent && document.body.removeChild(panelParent);
    },
    [panelParent]
  );

  return createPortal(
    <PanelFrame
      ref={panelRef}
      $open={shouldShow}
      $isBehindTopBar={isBehindTopBar}
      $hasDownloadBanner={hasDownloadBanner}
    >
      <AnimatedOverlay onClick={onClose} shouldShow={shouldShow} />
      {transitions((tStyle, item) =>
        item ? (
          <PanelContent
            ref={panelContentRef}
            className={className}
            style={{ ...style, ...tStyle }}
            role="dialog"
            $position={position}
          >
            {typeof onBack === "function" ? (

            ) : null}
            {title &&
{title}
}
            {children}
          </PanelContent>
        ) : null
      )}
    </PanelFrame>,
    panelParent
  );
};
Panel.propTypes = {
  shouldShow: PropTypes.bool,
  children: PropTypes.node,
  onClose: PropTypes.func,
  onBack: PropTypes.func,
  noScroll: PropTypes.bool,
  isBehindTopBar: PropTypes.bool,
  position: PropTypes.oneOf(["right", "left"]),
  title: PropTypes.string,
  className: PropTypes.string,
};

export default Panel;
<commit_msg>fix: generic panel component padding top<commit_after>import PropTypes from "prop-types";
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import { createPortal } from "react-dom";
import { useTransition, animated } from "@react-spring/web";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";
import { useDisableBodyScroll } from "@agir/lib/utils/hooks";
import { useDownloadBanner } from "@agir/front/app/hooks.js";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

const springConfig = {
  tension: 160,
  friction: 30,
};

const slideInTransitions = {
  right: {
    config: springConfig,
    from: { right: 0, transform: "translateX(100%)" },
    enter: { transform: "translateX(0%)" },
    leave: { transform: "translateX(100%)" },
  },
  left: {
    config: springConfig,
    from: { left: 0, transform: "translateX(-100%)" },
    enter: { transform: "translateX(0%)" },
    leave: { transform: "translateX(-100%)" },
  },
};

const fadeInTransition = {
  config: springConfig,
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
};

const Overlay = styled(animated.div)`
  width: 100%;
  height: 100%;
  max-height: 100%;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(164, 159, 173, 0.6);
  cursor: ${({ onClick }) => (onClick ? "pointer" : "default")};
  z-index: 1;
  will-change: opacity;
`;

const AnimatedOverlay = (props) => {
  const { shouldShow = false, onClick } = props;
  const transitions = useTransition(!!shouldShow, fadeInTransition);

  return transitions((style, item) =>
    item ? <Overlay style={style} onClick={onClick} /> : null
  );
};

AnimatedOverlay.propTypes = {
  shouldShow: PropTypes.bool,
  onClick: PropTypes.func,
  className: PropTypes.string,
};

export const StyledBackButton = styled.button`
  &,
  &:hover,
  &:focus {
    background-color: transparent;
    border: none;
    box-shadow: none;
    padding: 0 0 0.5rem;
    margin: 0;
    text-align: left;
    cursor: pointer;
  }
  &:hover,
  &:focus {
    opacity: 0.75;
  }
`;

const PanelContent = styled(animated.aside)`
  position: fixed;
  z-index: ${style.zindexPanel};
  height: 100vh;
  max-height: -webkit-fill-available;
  overflow: auto;
  top: 0;
  ${({ $position }) => `${$position}: 0;`}
  display: inline-block;
  width: auto;
  min-width: 600px;
  background-color: white;
  margin: 0;
  padding: 2rem 1.5rem;
  will-change: transform;

  @media (max-width: ${style.collapse}px) {
    display: block;
    width: 100%;
    min-width: 100%;
    padding: 1.5rem;
  }

  & > h4 {
    margin: 0;
    padding: 0 0 0.5rem;
  }
`;

const PanelFrame = styled.div`
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  max-height: -webkit-fill-available;
  overflow: hidden;
  z-index: ${style.zindexPanel};
  pointer-events: ${({ $open }) => ($open ? "auto" : "none")};

  @media (max-width: ${style.collapse}px) {
    display: block;
    width: 100%;
    min-width: 100%;
    z-index: ${({ $isBehindTopBar }) =>
      $isBehindTopBar ? style.zindexTopBar - 1 : style.zindexPanel};

    ${PanelContent} {
      padding-top: ${({ $isBehindTopBar, $hasDownloadBanner }) => {
        if ($isBehindTopBar && $hasDownloadBanner) {
          return "136px";
        }
        if ($isBehindTopBar) {
          return "56px";
        }
        return "0";
      }};
    }
  }
`;

const getFocusableElements = (parent) => {
  if (!parent) {
    return [];
  }
  return [
    ...parent.querySelectorAll(
      'a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select'
    ),
  ].filter(
    (elem) =>
      !elem.disabled &&
      !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length)
  );
};

const useFocusTrap = (shouldShow) => {
  const panelRef = useRef(null);
  const handleTabKey = useCallback((e) => {
    if (!panelRef.current) {
      return;
    }
    const focusablePanelElements = getFocusableElements(panelRef.current);
    const firstElement = focusablePanelElements[0];
    const lastElement =
      focusablePanelElements[focusablePanelElements.length - 1];
    if (!e.shiftKey && document.activeElement === lastElement) {
      firstElement.focus();
      e.preventDefault();
    }
    if (e.shiftKey && document.activeElement === firstElement) {
      lastElement.focus();
      e.preventDefault();
    }
  }, []);

  const keyListenersMap = useMemo(
    () => new Map([[9, handleTabKey]]),
    [handleTabKey]
  );

  useEffect(() => {
    const keyListener = (e) => {
      const listener = keyListenersMap.get(e.keyCode);
      return listener && listener(e);
    };
    if (shouldShow && panelRef.current) {
      document.addEventListener("keydown", keyListener);
      const firstElement = getFocusableElements(panelRef.current)[0];
      firstElement ? firstElement.focus() : panelRef.current.focus();
    }

    return () => document.removeEventListener("keydown", keyListener);
  }, [shouldShow, keyListenersMap]);

  return panelRef;
};

const Panel = (props) => {
  const {
    shouldShow = false,
    position = "right",
    title,
    children,
    onClose,
    onBack,
    noScroll,
    isBehindTopBar,
    className,
    style,
  } = props;

  const [hasDownloadBanner] = useDownloadBanner();

  const panelRef = useDisableBodyScroll(noScroll, shouldShow);
  const panelContentRef = useFocusTrap(shouldShow);

  const slideInTransition =
    slideInTransitions[position] || slideInTransitions.right;
  const transitions = useTransition(!!shouldShow, slideInTransition);

  const panelParent = useMemo(() => {
    const panelParent = document.createElement("div");
    panelParent.className = "panel-root";
    document.body.appendChild(panelParent);

    return panelParent;
  }, []);

  useEffect(
    () => () => {
      panelParent && document.body.removeChild(panelParent);
    },
    [panelParent]
  );

  return createPortal(
    <PanelFrame
      ref={panelRef}
      $open={shouldShow}
      $isBehindTopBar={isBehindTopBar}
      $hasDownloadBanner={hasDownloadBanner}
    >
      <AnimatedOverlay onClick={onClose} shouldShow={shouldShow} />
      {transitions((tStyle, item) =>
        item ? (
          <PanelContent
            ref={panelContentRef}
            className={className}
            style={{ ...style, ...tStyle }}
            role="dialog"
            $position={position}
          >
            {typeof onBack === "function" ? (

            ) : null}
            {title &&
{title}
}
            {children}
          </PanelContent>
        ) : null
      )}
    </PanelFrame>,
    panelParent
  );
};
Panel.propTypes = {
  shouldShow: PropTypes.bool,
  children: PropTypes.node,
  onClose: PropTypes.func,
  onBack: PropTypes.func,
  noScroll: PropTypes.bool,
  isBehindTopBar: PropTypes.bool,
  position: PropTypes.oneOf(["right", "left"]),
  title: PropTypes.string,
  className: PropTypes.string,
};

export default Panel;
<|endoftext|>


<commit_before>function createDungeon(){
	var form = document.getElementById("dungeon-form");
	setFormDisabled(form, true);

	if(form.elements["width"].value*form.elements["height"].value>45000){
		alert('The area of the dungeon must be less than 45000!');
		setFormDisabled(form, false);
    return false;
	}

	if(form.elements["roomMinWidth"].value>=form.elements["roomMaxWidth"].value || form.elements["roomMinHeight"].value>=form.elements["roomMaxHeight"].value ){
		alert("The room's min sizes must be less than their respective max size!");
		setFormDisabled(form, false);
    return false;
	}

  if(form.elements["name"].value!=form.elements["name"].value.match(/[\w0-9]+/)){
    alert("The dungeon's name can only be letters, numbers, and underscores!");
    return false;
  }

	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
		if (xhttp.readyState == 4 && xhttp.status == 200) {
			var response = JSON.parse(xhttp.responseText), send = false;
			switch(response.stats){
				case -1:
					send = false;
					alert(response.message);
					break;
				case 1:
					send = true;
					break;
			}
			if(send){
				var xhttp2 = new XMLHttpRequest();
				xhttp2.onreadystatechange = function() {
					if (xhttp2.readyState == 4 && xhttp2.status == 200) {
						document.location = "/dungeon/"+form.elements["name"].value.toLowerCase();
					}
				};
				xhttp2.open("POST", "/create", true);
				xhttp2.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				var message = {};
				for(var ele in form.elements){
					if (parseInt(ele)==ele || !form.elements.hasOwnProperty(ele)) continue;
					message[ele] = form.elements[ele].value;
				}console.log(JSON.stringify(message));
				xhttp2.send(JSON.stringify(message));
			}
			else
				setFormDisabled(form, false);
		}
	};
	xhttp.open("POST", "/attempt", true);
	xhttp.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
	var message = {};
	for(var ele in form.elements){
		if (parseInt(ele)==ele || !form.elements.hasOwnProperty(ele)) continue;
		message[ele] = form.elements[ele].value;
	}
	xhttp.send(JSON.stringify(message));
  return false;
}

function setFormDisabled(form, val){
	form.elements["width"].disabled = val;
	form.elements["height"].disabled = val;
	form.elements["numRooms"].disabled = val;
	form.elements["roomMinWidth"].disabled = val;
	form.elements["roomMaxWidth"].disabled = val;
	form.elements["roomMinHeight"].disabled = val;
	form.elements["roomMaxHeight"].disabled = val;
	form.elements["name"].disabled = val;
  document.getElementById("submit").disabled = val;
}
<commit_msg>Fixed issue with vaildation on generation creation.<commit_after>function createDungeon(){
	var form = document.getElementById("dungeon-form");
	setFormDisabled(form, true);

	if(form.elements["width"].value*form.elements["height"].value>45000){
		alert('The area of the dungeon must be less than 45000!');
		setFormDisabled(form, false);
    return false;
	}

	if(parseInt(form.elements["roomMinWidth"].value)>=parseInt(form.elements["roomMaxWidth"].value) || parseInt(form.elements["roomMinHeight"].value)>=parseInt(form.elements["roomMaxHeight"].value)){
		alert("The room's min sizes must be less than their respective max size!");
		setFormDisabled(form, false);
    return false;
	}

  if(form.elements["name"].value!=form.elements["name"].value.match(/[\w0-9]+/)){
    alert("The dungeon's name can only be letters, numbers, and underscores!");
    setFormDisabled(form, false);
    return false;
  }

	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
		if (xhttp.readyState == 4 && xhttp.status == 200) {
			var response = JSON.parse(xhttp.responseText), send = false;
			switch(response.stats){
				case -1:
					send = false;
					alert(response.message);
					break;
				case 1:
					send = true;
					break;
			}
			if(send){
				var xhttp2 = new XMLHttpRequest();
				xhttp2.onreadystatechange = function() {
					if (xhttp2.readyState == 4 && xhttp2.status == 200) {
						document.location = "/dungeon/"+form.elements["name"].value.toLowerCase();
					}
				};
				xhttp2.open("POST", "/create", true);
				xhttp2.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				var message = {};
				for(var ele in form.elements){
					if (parseInt(ele)==ele || !form.elements.hasOwnProperty(ele)) continue;
					message[ele] = form.elements[ele].value;
				}console.log(JSON.stringify(message));
				xhttp2.send(JSON.stringify(message));
			}
			else
				setFormDisabled(form, false);
		}
	};
	xhttp.open("POST", "/attempt", true);
	xhttp.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
	var message = {};
	for(var ele in form.elements){
		if (parseInt(ele)==ele || !form.elements.hasOwnProperty(ele)) continue;
		message[ele] = form.elements[ele].value;
	}
	xhttp.send(JSON.stringify(message));
  return false;
}

function setFormDisabled(form, val){
	form.elements["width"].disabled = val;
	form.elements["height"].disabled = val;
	form.elements["numRooms"].disabled = val;
	form.elements["roomMinWidth"].disabled = val;
	form.elements["roomMaxWidth"].disabled = val;
	form.elements["roomMinHeight"].disabled = val;
	form.elements["roomMaxHeight"].disabled = val;
	form.elements["name"].disabled = val;
  document.getElementById("submit").disabled = val;
}
<|endoftext|>


<commit_before>
<commit_msg>Added simple JSON parsing and AJAX call<commit_after>function getExternal(filepath, callback) //ajax request function
{	//filepath - path of file to be fetched
	//callback - function to be executed with file gotten
	//doesn't return, callback should be executed and return
	var ajax = new XMLHttpRequest();
	ajax.onreadystatechange = function () {
		if (ajax.readyState === 4 && ajax.status === 200) {
			callback(ajax.responseText);
		}
	};
	ajax.open("GET", filepath, "true");
	ajax.send();
}
function parseJSON(filepath) //parses JSON output
{	//filepath - path of JSON file to be fetched
	//returns javascript object
	getExternal(filepath, function(text)
	{
		var obj = JSON.parse(text);
		return obj;
	});
}<|endoftext|>


<commit_before>var cheerio = require('cheerio');
var irc = require('irc');
var Pinboard = require('node-pinboard');
var request = require('request');
var twitter = require('twitter-text');

var CHAN = '#utdlug' + (process.argv[3] ? 'testing' : '');
var bot = new irc.Client('irc.oftc.net', 'utdlug', {channels: [CHAN]});
var pinboard = new Pinboard(process.argv[2]);

bot.addListener('message', function(from, to, msg) {
  twitter.extractUrls(msg).map(function(url) {
    try {
      if (url.substring(0, 4) != 'http') {
        url = 'http://' + url;
      };

      request(url, function(err, res, body) {
        pinboard.add({
          url: url,
          description: cheerio.load(body)('title').text() || url,
          tags: ['by:' + from].concat(twitter.extractHashtags(msg)).join(','),
          replace: 'no',
        }, function(res) {
          console.log(res)
        })
      });
    } catch(e) {
      console.log(e);
    };
  });
});
<commit_msg>handle links with no html<commit_after>var cheerio = require('cheerio');
var irc = require('irc');
var Pinboard = require('node-pinboard');
var request = require('request');
var twitter = require('twitter-text');

var CHAN = '#utdlug' + (process.argv[3] ? 'testing' : '');
var bot = new irc.Client('irc.oftc.net', 'utdlug', {channels: [CHAN]});
var pinboard = new Pinboard(process.argv[2]);

bot.addListener('message', function(from, to, msg) {
  twitter.extractUrls(msg).map(function(url) {
    try {
      if (url.substring(0, 4) != 'http') {
        url = 'http://' + url;
      };

      request(url, function(err, res, body) {
        pinboard.add({
          url: url,
          description: cheerio.load(body || '')('title').text() || url,
          tags: ['by:' + from].concat(twitter.extractHashtags(msg)).join(','),
          replace: 'no',
        }, function(res) {
          console.log(res);
        })
      });
    } catch(e) {
      console.log(e);
    };
  });
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'ProxyDAO',
  extends: 'foam.dao.AbstractDAO',

  requires: [
    'foam.dao.ProxyListener'
  ],

  documentation: 'Proxy implementation for the DAO interface.',

  properties: [
    {
      class: 'Proxy',
      of: 'foam.dao.DAO',
      name: 'delegate',
      forwards: [ 'put', 'remove', 'find', 'select', 'removeAll' ],
      topics: [ 'on' ], // TODO: Remove this when all users of it are updated.
      factory: function() { return foam.dao.NullDAO.create() },
      postSet: function(old, nu) {
        if ( old ) this.on.reset.pub();
      }
    },
    {
      name: 'of',
      factory: function() {
        return this.delegate.of;
      }
    }
  ],

  methods: [
    function listen(sink, skip, limit, order, predicate) {
      var listener = this.ProxyListener.create({
        delegate: sink,
        args: [skip, limit, order, predicate]
      });

      listener.onDetach(listener.dao$.follow(this.delegate$));

      return listener;
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ProxyListener',

  implements: ['foam.dao.Sink'],

  properties: [
    'args',
    'delegate',
    {
      name: 'innerSub',
      postSet: function(_, s) {
        if (s) this.onDetach(s);
      }
    },
    {
      name: 'dao',
      postSet: function(old, nu) {
        this.innerSub && this.innerSub.detach();
        this.innerSub = nu && nu.listen.apply(nu, [this].concat(this.args));
        if ( old ) this.reset();
      }
    }
  ],

  methods: [
    function put(obj, s) {
      this.delegate.put(this, obj);
    },

    function remove(obj, s) {
      this.delegate.remove(this, obj);
    },

    function reset(s) {
      this.delegate.reset(this);
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ArraySink',
  extends: 'foam.dao.AbstractSink',

  imports: ['warn?'],

  properties: [
    {
      class: 'Array',
      name: 'array'
    },
    {
      name: 'a',
      getter: function() {
        this.warn && this.warn('Use of deprecated ArraySink.a');
        return this.array;
      }
    },
  ],

  methods: [
    function put(o, sub) {
      this.array.push(o);
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'PromisedDAO',
  extends: 'foam.dao.AbstractDAO',

  properties: [
    {
      class: 'Promised',
      of: 'foam.dao.DAO',
      methods: [ 'put', 'remove', 'find', 'select', 'removeAll', 'listen' ],
      name: 'promise'
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'LocalStorageDAO',
  extends: 'foam.dao.ArrayDAO',

  properties: [
    {
      name:  'name',
      label: 'Store Name',
      class:  'foam.core.String'
    }
  ],

  methods: [
    function init() {
      var objs = localStorage.getItem(this.name);
      if ( objs ) this.array = foam.json.parseString(objs, this);

      this.on.put.sub(this.updated);
      this.on.remove.sub(this.updated);

      // TODO: base on an indexed DAO
    }
  ],

  listeners: [
    {
      name: 'updated',
      isMerged: true,
      mergeDelay: 100,
      code: function() {
        localStorage.setItem(this.name, foam.json.stringify(this.array));
      }
    }
  ]
});

foam.LIB({
  name: 'foam.String',
  methods: [
    {
      name: 'daoize',
      code: foam.Function.memoize1(function(str) {
        // Turns SomeClassName into someClassNameDAO,
        // of package.ClassName into package.ClassNameDAO
        return str.substring(0, 1).toLowerCase() + str.substring(1) + 'DAO';
      })
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'InvalidArgumentException',
  extends: 'foam.dao.ExternalException',

  properties: [
    {
      class: 'String',
      name: 'message'
    }
  ]
});
<commit_msg>Remove redundant import of 'warn' in ArraySink.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.dao',
  name: 'ProxyDAO',
  extends: 'foam.dao.AbstractDAO',

  requires: [
    'foam.dao.ProxyListener'
  ],

  documentation: 'Proxy implementation for the DAO interface.',

  properties: [
    {
      class: 'Proxy',
      of: 'foam.dao.DAO',
      name: 'delegate',
      forwards: [ 'put', 'remove', 'find', 'select', 'removeAll' ],
      topics: [ 'on' ], // TODO: Remove this when all users of it are updated.
      factory: function() { return foam.dao.NullDAO.create() },
      postSet: function(old, nu) {
        if ( old ) this.on.reset.pub();
      }
    },
    {
      name: 'of',
      factory: function() {
        return this.delegate.of;
      }
    }
  ],

  methods: [
    function listen(sink, skip, limit, order, predicate) {
      var listener = this.ProxyListener.create({
        delegate: sink,
        args: [skip, limit, order, predicate]
      });

      listener.onDetach(listener.dao$.follow(this.delegate$));

      return listener;
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ProxyListener',

  implements: ['foam.dao.Sink'],

  properties: [
    'args',
    'delegate',
    {
      name: 'innerSub',
      postSet: function(_, s) {
        if (s) this.onDetach(s);
      }
    },
    {
      name: 'dao',
      postSet: function(old, nu) {
        this.innerSub && this.innerSub.detach();
        this.innerSub = nu && nu.listen.apply(nu, [this].concat(this.args));
        if ( old ) this.reset();
      }
    }
  ],

  methods: [
    function put(obj, s) {
      this.delegate.put(this, obj);
    },

    function remove(obj, s) {
      this.delegate.remove(this, obj);
    },

    function reset(s) {
      this.delegate.reset(this);
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'ArraySink',
  extends: 'foam.dao.AbstractSink',

  properties: [
    {
      class: 'Array',
      name: 'array'
    },
    {
      name: 'a',
      getter: function() {
        this.warn('Use of deprecated ArraySink.a');
        return this.array;
      }
    },
  ],

  methods: [
    function put(o, sub) {
      this.array.push(o);
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'PromisedDAO',
  extends: 'foam.dao.AbstractDAO',

  properties: [
    {
      class: 'Promised',
      of: 'foam.dao.DAO',
      methods: [ 'put', 'remove', 'find', 'select', 'removeAll', 'listen' ],
      name: 'promise'
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'LocalStorageDAO',
  extends: 'foam.dao.ArrayDAO',

  properties: [
    {
      name:  'name',
      label: 'Store Name',
      class:  'foam.core.String'
    }
  ],

  methods: [
    function init() {
      var objs = localStorage.getItem(this.name);
      if ( objs ) this.array = foam.json.parseString(objs, this);

      this.on.put.sub(this.updated);
      this.on.remove.sub(this.updated);

      // TODO: base on an indexed DAO
    }
  ],

  listeners: [
    {
      name: 'updated',
      isMerged: true,
      mergeDelay: 100,
      code: function() {
        localStorage.setItem(this.name, foam.json.stringify(this.array));
      }
    }
  ]
});

foam.LIB({
  name: 'foam.String',
  methods: [
    {
      name: 'daoize',
      code: foam.Function.memoize1(function(str) {
        // Turns SomeClassName into someClassNameDAO,
        // of package.ClassName into package.ClassNameDAO
        return str.substring(0, 1).toLowerCase() + str.substring(1) + 'DAO';
      })
    }
  ]
});

foam.CLASS({
  package: 'foam.dao',
  name: 'InvalidArgumentException',
  extends: 'foam.dao.ExternalException',

  properties: [
    {
      class: 'String',
      name: 'message'
    }
  ]
});
<|endoftext|>