<commit_before>var cheerio = require('cheerio');
var fs = require('fs');
var moment = require('moment');
var urllib = require('url');

var multidep = require('../multidep');
var pkg = require('../package');
var utils = require('../lib/utils');

var isUrl = utils.isUrl;
var urljoin = utils.urljoin;

var aframeVersions = multidep.versions.aframe;

var MASTER = 'master';
var aframeCurrentSha = MASTER;
try {
  aframeCurrentSha = pkg.dependencies.aframe.split('#')[1];
} catch (e) {}

/**
 * Generate data structure for generating table of contents.
 *
 * @param {string} content - Page content.
 * @returns {array} [{title: 'Title', link: '#anchor', children: []}]
 */
hexo.extend.helper.register('table_of_contents', function (content) {
  var $ = cheerio.load(content);
  var h2Set = $('h2');
  var toc = [];

  // Get H2s.
  var items = h2Set.map(function (h2) {
    var $h2 = $(this);

    // Add H2.
    var link = $h2.find('a')[0];
    var item = {
      title: link.attribs.title,
      href: link.attribs.href.toLowercase(),
      children: []
    };

    // Get H3s. Loop until we hit an H2 or until no more siblings.
    var links = $h2.nextUntil('h2', 'h3').find('a');
    for (var i = 0; i < links.length; i++) {
      item.children.push({
        title: links[i].attribs.title,
        href: links[i].attribs.href.toLowercase()
      });
    }
    return item;
  });

  // Convert to be `forEach`able.
  for (var i = 0; i < items.length; i++) {
    toc.push(items[i]);
  }
  return toc;
});

/**
 * twitter|andgokevin -> [@andgokevin](twitter.com/andgokevin)
 * twitter|andgokevin|Kevin Ngo -> [Kevin Ngo](twitter.com/andgokevin)
 * github|ngokevin -> [ngokevin](github.com/ngokevin)
 * ngokevin -> [ngokevin](ngokevin)
 * http://ngokevin.com|Kevin Ngo -> [Kevin Ngo](ngokevin.com)
 */
hexo.extend.helper.register('blog_attribution', function (author) {
  var authorSplit = author.split('|');
  var display;
  var link;

  // Nothing to do.
  if (authorSplit.length === 1) { return author; }

  // Twitter handle.
  if (authorSplit[0] === 'twitter') {
    if (authorSplit.length === 2) {
      display = authorSplit[1];
      link = authorSplit[1];
    } else {
      display = authorSplit[2];
      link = authorSplit[1];
    }
    // Strip `@` from link.
    if (link[0] === '@') {
      link = link.substring(1);
    }
    return '' +
      display + '';
  }

  // GitHub username.
  if (authorSplit[0] === 'github') {
    if (authorSplit.length === 2) {
      display = authorSplit[1];
      link = authorSplit[1];
    } else {
      display = authorSplit[2];
      link = authorSplit[1];
    }
    return '' +
      display + '';
  }

  // Link.
  display = authorSplit[1];
  link = authorSplit[0];
  return '' + display + '';
});

hexo.extend.helper.register('markdown', function (text) {
  return hexo.render.renderSync({text: text, engine: 'markdown'});
});

hexo.extend.helper.register('blog_date', function (date) {
  return date.format('MMM D[,] YYYY');
});

hexo.extend.helper.register('blog_date_subtract_week', function (date) {
  return moment(date).subtract({weeks: 1}).format('MMM D[,] YYYY');
});

/**
 * #1000 -> github.com/aframevr/aframe/pull/1000
 * abcde -> github.com/aframevr/aframe/commit/abcde
 * aframevr/aframe-editor|#1000 -> github.com/aframevr/aframe-editor/pull/1000
 */
hexo.extend.helper.register('github_contribution', function (contribution, display) {
  var project = this.config.github.aframe.username + '/' + this.config.github.aframe.repo;
  var contributionSplit;
  display = display || contribution;

  if (contribution.indexOf('|') !== -1) {
    contributionSplit = contribution.split('|');
    project = contributionSplit[0];
    contribution = contributionSplit[1];
  }

  if (contribution[0] === '#') {
    contribution = contribution.substring(1);
    return '' +
      display + '';
  }
  return '' +
    display + '';
});

hexo.extend.helper.register('github_release_url', function (version) {
  version = version || ('v' + this.config.aframe_version);
  return urljoin(this.config.github.aframe.url, 'releases', 'tag', version);
});

hexo.extend.helper.register('github_file_url', function (path) {
  return urljoin(this.config.github.aframe.url, 'blob', aframeCurrentSha, path);
});

/**
 * Get GitHub edit URL.
 * - Change .html to .md.
 * - For docs, must remove the active version (e.g., docs/0.2.0/guide.html -> docs/guide.md).
 */
hexo.extend.helper.register('website_github_edit_url', function (path) {
  // For docs.
  if (path.indexOf('docs/') !== -1) {
    var activeVersion = path.split('/')[path.split('/').indexOf('docs') + 1];
    return urljoin(this.config.github.aframe.url, 'edit', MASTER,
                   path.replace('docs/' + activeVersion, 'docs').replace(/\.html$/, '.md'));
  }
  // For blog posts.
  return urljoin(this.config.github.aframe_site.url, 'edit', MASTER, this.config.source_dir,
                 path.replace(/\.html$/, '.md'));
});

/**
 * Like Hexo's `url_for` helper but returns an absolute URL.
 */
hexo.extend.helper.register('absolute_url_for', function (path, options) {
  var url = urljoin(this.config.url, this.url_for(path, options));
  if (options && options.secure === false) {
    url = url.replace(/^https:/, 'http:');
  }
  return url;
});

hexo.extend.helper.register('page_url', function (path, options) {
  return this.url_for(path, options).replace(/index\.html$/, '');
});

hexo.extend.helper.register('example_url', function (item) {
  return urljoin(this.url_for('examples'), item.section, item.slug) + '/';
});

hexo.extend.helper.register('docs_url_prefix', function (item) {
  return this.page.source.split('/', 2).join('/') + '/';
});

/**
 * Return actively-being-viewed version of the docs based on page.
 * Extract <VERSION> out of `.../docs/<VERSION>/...`.
 */
hexo.extend.helper.register('docs_active_version', function (page) {
  var splitPath = page.path.split('/');
  var docIndex = splitPath.indexOf('docs');
  return splitPath[docIndex + 1];
});

/**
 * Sort documentation pages. Pages that have `order` go first. Then alphabetized by title.
 */
hexo.extend.helper.register('docs_nav_sort', function (pages) {
  var orderedPages = [];
  var alphabetizedPages = [];
  pages.forEach(function addOrderedPages (page) {
    if ('order' in page) {
      orderedPages.push(page);
      return;
    }
    alphabetizedPages.push(page);
  });
  orderedPages = orderedPages.sort(function sort (pageA, pageB) {
    if (pageA.order < pageB.order) { return -1; }
    if (pageA.order > pageB.order) { return 1; }
    return 0;
  });
  alphabetizedPages = alphabetizedPages.sort(function sort (pageA, pageB) {
    if (pageA.title < pageB.title) { return -1; }
    if (pageA.title > pageB.title) { return 1; }
    return 0;
  });
  return orderedPages.concat(alphabetizedPages);
});

/**
 * Retrieve first page of a version's documentation. The first page will be determined
 * using section_order + order. Generally, whichever page has `{section_order: 1, order: 1}`.
 *
 * docs_root_path(site.pages, '0.2.0')
 * >> docs/0.2.0/guide/
 *
 * @param {object} pages - site.pages.
 */
hexo.extend.helper.register('docs_root_path', function (pages, version) {
  var page = docs_version_filter(pages, version).find({parent_section: 'docs'})
                                                .sort('section_order')
                                                .sort('order').data[0];
  return '/' + page.path.replace('index.html', '');
});

/**
 * Filter documentation navigation to only include pages of the version being browsed.
 */
hexo.extend.helper.register('docs_version_filter', function (pages, version) {
  return docs_version_filter(pages, version);
});
function docs_version_filter (pages, version) {
  return pages.filter(function (page) {
    return page.path.indexOf('docs/' + version) !== -1;
  });
}

/**
 * Return list of A-Frame versions, including `master`.
 * Order (reverse chronological): master, current, <oldVersions>.
 */
hexo.extend.helper.register('docs_versions', function () {
  return [MASTER].concat(aframeVersions.sort().reverse());
});

hexo.extend.helper.register('is_external_url', isUrl);

hexo.extend.filter.register('urljoin', urljoin);

hexo.extend.filter.register('after_render:html', function (str, data) {
  if (data.path && data.path.substr(-3) === '.md') {
    str = str.replace(/href="([^"]+)"/g, function (origStr, p1) {
      return 'href="' + convertMarkdownToHtmlUrl(p1) + '"';
    });
  }
  return str;
});

function convertMarkdownToHtmlUrl (url) {
  var urlObj = urllib.parse(url);
  if (!urlObj.pathname || urlObj.pathname[0] === '/') {
    // Do not rewrite absolute URLs.
    return url;
  }
  urlObj.pathname = urlObj.pathname.replace(/\.md$/, '.html')
                                   .replace('/index.html', '/');
  return urllib.format(urlObj);
}
<commit_msg>fix to lower case typo<commit_after>var cheerio = require('cheerio');
var fs = require('fs');
var moment = require('moment');
var urllib = require('url');

var multidep = require('../multidep');
var pkg = require('../package');
var utils = require('../lib/utils');

var isUrl = utils.isUrl;
var urljoin = utils.urljoin;

var aframeVersions = multidep.versions.aframe;

var MASTER = 'master';
var aframeCurrentSha = MASTER;
try {
  aframeCurrentSha = pkg.dependencies.aframe.split('#')[1];
} catch (e) {}

/**
 * Generate data structure for generating table of contents.
 *
 * @param {string} content - Page content.
 * @returns {array} [{title: 'Title', link: '#anchor', children: []}]
 */
hexo.extend.helper.register('table_of_contents', function (content) {
  var $ = cheerio.load(content);
  var h2Set = $('h2');
  var toc = [];

  // Get H2s.
  var items = h2Set.map(function (h2) {
    var $h2 = $(this);

    // Add H2.
    var link = $h2.find('a')[0];
    var item = {
      title: link.attribs.title,
      href: link.attribs.href.toLowerCase(),
      children: []
    };

    // Get H3s. Loop until we hit an H2 or until no more siblings.
    var links = $h2.nextUntil('h2', 'h3').find('a');
    for (var i = 0; i < links.length; i++) {
      item.children.push({
        title: links[i].attribs.title,
        href: links[i].attribs.href.toLowerCase()
      });
    }
    return item;
  });

  // Convert to be `forEach`able.
  for (var i = 0; i < items.length; i++) {
    toc.push(items[i]);
  }
  return toc;
});

/**
 * twitter|andgokevin -> [@andgokevin](twitter.com/andgokevin)
 * twitter|andgokevin|Kevin Ngo -> [Kevin Ngo](twitter.com/andgokevin)
 * github|ngokevin -> [ngokevin](github.com/ngokevin)
 * ngokevin -> [ngokevin](ngokevin)
 * http://ngokevin.com|Kevin Ngo -> [Kevin Ngo](ngokevin.com)
 */
hexo.extend.helper.register('blog_attribution', function (author) {
  var authorSplit = author.split('|');
  var display;
  var link;

  // Nothing to do.
  if (authorSplit.length === 1) { return author; }

  // Twitter handle.
  if (authorSplit[0] === 'twitter') {
    if (authorSplit.length === 2) {
      display = authorSplit[1];
      link = authorSplit[1];
    } else {
      display = authorSplit[2];
      link = authorSplit[1];
    }
    // Strip `@` from link.
    if (link[0] === '@') {
      link = link.substring(1);
    }
    return '' +
      display + '';
  }

  // GitHub username.
  if (authorSplit[0] === 'github') {
    if (authorSplit.length === 2) {
      display = authorSplit[1];
      link = authorSplit[1];
    } else {
      display = authorSplit[2];
      link = authorSplit[1];
    }
    return '' +
      display + '';
  }

  // Link.
  display = authorSplit[1];
  link = authorSplit[0];
  return '' + display + '';
});

hexo.extend.helper.register('markdown', function (text) {
  return hexo.render.renderSync({text: text, engine: 'markdown'});
});

hexo.extend.helper.register('blog_date', function (date) {
  return date.format('MMM D[,] YYYY');
});

hexo.extend.helper.register('blog_date_subtract_week', function (date) {
  return moment(date).subtract({weeks: 1}).format('MMM D[,] YYYY');
});

/**
 * #1000 -> github.com/aframevr/aframe/pull/1000
 * abcde -> github.com/aframevr/aframe/commit/abcde
 * aframevr/aframe-editor|#1000 -> github.com/aframevr/aframe-editor/pull/1000
 */
hexo.extend.helper.register('github_contribution', function (contribution, display) {
  var project = this.config.github.aframe.username + '/' + this.config.github.aframe.repo;
  var contributionSplit;
  display = display || contribution;

  if (contribution.indexOf('|') !== -1) {
    contributionSplit = contribution.split('|');
    project = contributionSplit[0];
    contribution = contributionSplit[1];
  }

  if (contribution[0] === '#') {
    contribution = contribution.substring(1);
    return '' +
      display + '';
  }
  return '' +
    display + '';
});

hexo.extend.helper.register('github_release_url', function (version) {
  version = version || ('v' + this.config.aframe_version);
  return urljoin(this.config.github.aframe.url, 'releases', 'tag', version);
});

hexo.extend.helper.register('github_file_url', function (path) {
  return urljoin(this.config.github.aframe.url, 'blob', aframeCurrentSha, path);
});

/**
 * Get GitHub edit URL.
 * - Change .html to .md.
 * - For docs, must remove the active version (e.g., docs/0.2.0/guide.html -> docs/guide.md).
 */
hexo.extend.helper.register('website_github_edit_url', function (path) {
  // For docs.
  if (path.indexOf('docs/') !== -1) {
    var activeVersion = path.split('/')[path.split('/').indexOf('docs') + 1];
    return urljoin(this.config.github.aframe.url, 'edit', MASTER,
                   path.replace('docs/' + activeVersion, 'docs').replace(/\.html$/, '.md'));
  }
  // For blog posts.
  return urljoin(this.config.github.aframe_site.url, 'edit', MASTER, this.config.source_dir,
                 path.replace(/\.html$/, '.md'));
});

/**
 * Like Hexo's `url_for` helper but returns an absolute URL.
 */
hexo.extend.helper.register('absolute_url_for', function (path, options) {
  var url = urljoin(this.config.url, this.url_for(path, options));
  if (options && options.secure === false) {
    url = url.replace(/^https:/, 'http:');
  }
  return url;
});

hexo.extend.helper.register('page_url', function (path, options) {
  return this.url_for(path, options).replace(/index\.html$/, '');
});

hexo.extend.helper.register('example_url', function (item) {
  return urljoin(this.url_for('examples'), item.section, item.slug) + '/';
});

hexo.extend.helper.register('docs_url_prefix', function (item) {
  return this.page.source.split('/', 2).join('/') + '/';
});

/**
 * Return actively-being-viewed version of the docs based on page.
 * Extract <VERSION> out of `.../docs/<VERSION>/...`.
 */
hexo.extend.helper.register('docs_active_version', function (page) {
  var splitPath = page.path.split('/');
  var docIndex = splitPath.indexOf('docs');
  return splitPath[docIndex + 1];
});

/**
 * Sort documentation pages. Pages that have `order` go first. Then alphabetized by title.
 */
hexo.extend.helper.register('docs_nav_sort', function (pages) {
  var orderedPages = [];
  var alphabetizedPages = [];
  pages.forEach(function addOrderedPages (page) {
    if ('order' in page) {
      orderedPages.push(page);
      return;
    }
    alphabetizedPages.push(page);
  });
  orderedPages = orderedPages.sort(function sort (pageA, pageB) {
    if (pageA.order < pageB.order) { return -1; }
    if (pageA.order > pageB.order) { return 1; }
    return 0;
  });
  alphabetizedPages = alphabetizedPages.sort(function sort (pageA, pageB) {
    if (pageA.title < pageB.title) { return -1; }
    if (pageA.title > pageB.title) { return 1; }
    return 0;
  });
  return orderedPages.concat(alphabetizedPages);
});

/**
 * Retrieve first page of a version's documentation. The first page will be determined
 * using section_order + order. Generally, whichever page has `{section_order: 1, order: 1}`.
 *
 * docs_root_path(site.pages, '0.2.0')
 * >> docs/0.2.0/guide/
 *
 * @param {object} pages - site.pages.
 */
hexo.extend.helper.register('docs_root_path', function (pages, version) {
  var page = docs_version_filter(pages, version).find({parent_section: 'docs'})
                                                .sort('section_order')
                                                .sort('order').data[0];
  return '/' + page.path.replace('index.html', '');
});

/**
 * Filter documentation navigation to only include pages of the version being browsed.
 */
hexo.extend.helper.register('docs_version_filter', function (pages, version) {
  return docs_version_filter(pages, version);
});
function docs_version_filter (pages, version) {
  return pages.filter(function (page) {
    return page.path.indexOf('docs/' + version) !== -1;
  });
}

/**
 * Return list of A-Frame versions, including `master`.
 * Order (reverse chronological): master, current, <oldVersions>.
 */
hexo.extend.helper.register('docs_versions', function () {
  return [MASTER].concat(aframeVersions.sort().reverse());
});

hexo.extend.helper.register('is_external_url', isUrl);

hexo.extend.filter.register('urljoin', urljoin);

hexo.extend.filter.register('after_render:html', function (str, data) {
  if (data.path && data.path.substr(-3) === '.md') {
    str = str.replace(/href="([^"]+)"/g, function (origStr, p1) {
      return 'href="' + convertMarkdownToHtmlUrl(p1) + '"';
    });
  }
  return str;
});

function convertMarkdownToHtmlUrl (url) {
  var urlObj = urllib.parse(url);
  if (!urlObj.pathname || urlObj.pathname[0] === '/') {
    // Do not rewrite absolute URLs.
    return url;
  }
  urlObj.pathname = urlObj.pathname.replace(/\.md$/, '.html')
                                   .replace('/index.html', '/');
  return urllib.format(urlObj);
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'ArrayView',
  extends: 'foam.u2.View',

  requires: [
    'foam.core.FObject',
    'foam.u2.layout.Cols',
    'foam.u2.layout.Rows'
  ],

  exports: [
    'enableRemoving',
    'mode',
    'updateData'
  ],

  properties: [
    {
      class: 'foam.u2.ViewSpec',
      name: 'valueView',
      value: { class: 'foam.u2.view.AnyView' }
    },
    {
      name: 'defaultNewItem',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'enableAdding',
      value: true
    },
    {
      class: 'Boolean',
      name: 'enableRemoving',
      value: true
    }
  ],

  actions: [
    {
      name: 'addRow',
      label: 'Add',
      isAvailable: function(mode, enableAdding) {
        return enableAdding && mode === foam.u2.DisplayMode.RW;
      },
      code: function() {
        var newItem = this.defaultNewItem;
        if ( this.FObject.isInstance(newItem) ) {
          newItem = newItem.clone();
        }
        this.data[this.data.length] = newItem;
        this.updateData();
      }
    }
  ],

  classes: [
    {
      name: 'Row',
      imports: [
        'data',
        'enableRemoving',
        'mode',
        'updateData'
      ],
      properties: [
        {
          class: 'Int',
          name: 'index',
          visibility: 'RO'
        },
        {
          name: 'value',
          postSet: function(_, n) {
            this.data[this.index] = n;
          }
        }
      ],
      actions: [
        {
          name: 'remove',
          label: '',
          isAvailable: function(enableRemoving, mode) {
            return enableRemoving && mode === foam.u2.DisplayMode.RW;
          },
          code: function() {
            this.data.splice(this.index, 1);
            this.updateData();
          }
        }
      ]
    }
  ],

  listeners: [
    {
      name: 'updateData',
      isFramed: true,
      code: function() {
        var d = this.data;
        this.data = [];
        this.data = d;
      }
    }
  ],

  css: `
    ^ .foam-u2-ActionView-addRow {
      margin: 8px 0;
    }

    ^ .foam-u2-ActionView-remove {
      align-self: flex-start;
    }

   ^ .foam-u2-ActionView-remove {
     padding: 2 0 10px 8px;
   }

    ^value-view {
      flex: 1;
    }
  `,

  methods: [
    function initE() {
      this.SUPER();
      var self = this;

      this.addClass(this.myClass());

      this
        .add(this.slot(function(data, valueView) {
          return self.E()
            .start(self.Rows)
              .forEach(data || [], function(e, i) {
                var row = self.Row.create({ index: i, value: e });
                this
                  .startContext({ data: row })
                    .start(self.Cols)
                      .addClass(self.myClass('value-view-container'))
                      .start(valueView, { data$: row.value$ })
                        .addClass(self.myClass('value-view'))
                      .end()
                      .tag(self.Row.REMOVE, {
                        isDestructive: true,
                        icon: '/images/remove-circle.svg',
                        buttonStyle: 'UNSTYLED'
                      })
                    .end()
                  .endContext();
                row.onDetach(row.sub(self.updateData));
              });
        }))
        .startContext({ data: this })
          .tag(this.ADD_ROW, { buttonStyle: 'SECONDARY' })
        .endContext();
    }
  ]
});
<commit_msg>Make ArrayView much faster (avoid flicker) when updating.<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'ArrayView',
  extends: 'foam.u2.View',

  requires: [
    'foam.core.FObject',
    'foam.u2.layout.Cols',
    'foam.u2.layout.Rows'
  ],

  exports: [
    'enableRemoving',
    'mode',
    'updateData'
  ],

  properties: [
    {
      class: 'foam.u2.ViewSpec',
      name: 'valueView',
      value: { class: 'foam.u2.view.AnyView' }
    },
    {
      name: 'defaultNewItem',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'enableAdding',
      value: true
    },
    {
      class: 'Boolean',
      name: 'enableRemoving',
      value: true
    },
    // The next two properties are used to avoid excess flickering.
    // We only update data to data2_ when we know that our feedback
    // didn't cause the update. This prevents the whole view from
    // being redrawn when we update a single row's value.
    {
      name: 'data2_'
    },
    {
      class: 'Boolean',
      name: 'feedback_'
    }
  ],

  actions: [
    {
      name: 'addRow',
      label: 'Add',
      isAvailable: function(mode, enableAdding) {
        return enableAdding && mode === foam.u2.DisplayMode.RW;
      },
      code: function() {
        var newItem = this.defaultNewItem;
        if ( this.FObject.isInstance(newItem) ) {
          newItem = newItem.clone();
        }
        this.data[this.data.length] = newItem;
        this.updateData();
      }
    }
  ],

  classes: [
    {
      name: 'Row',
      imports: [
        'data',
        'enableRemoving',
        'mode',
        'updateData'
      ],
      properties: [
        {
          class: 'Int',
          name: 'index',
          visibility: 'RO'
        },
        {
          name: 'value',
          postSet: function(_, n) {
            this.data[this.index] = n;
          }
        }
      ],
      actions: [
        {
          name: 'remove',
          label: '',
          isAvailable: function(enableRemoving, mode) {
            return enableRemoving && mode === foam.u2.DisplayMode.RW;
          },
          code: function() {
            this.data.splice(this.index, 1);
            this.updateData();
          }
        }
      ]
    }
  ],

  css: `
    ^ .foam-u2-ActionView-addRow {
      margin: 8px 0;
    }

    ^ .foam-u2-ActionView-remove {
      align-self: flex-start;
    }

   ^ .foam-u2-ActionView-remove {
     padding: 2 0 10px 8px;
   }

    ^value-view {
      flex: 1;
    }
  `,

  methods: [
    function initE() {
      this.SUPER();
      var self = this;

      this.onDetach(this.data$.sub(() => { if ( ! this.feedback_ ) this.data2_ = this.data; }));
      this.data2_ = this.data;
      this.addClass(this.myClass());

      this
        .add(this.slot(function(data2_, valueView) {
          var data = data2_;
          return self.E()
            .start(self.Rows)
              .forEach(data || [], function(e, i) {
                var row = self.Row.create({ index: i, value: e });
                this
                  .startContext({ data: row })
                    .start(self.Cols)
                      .addClass(self.myClass('value-view-container'))
                      .start(valueView, { data$: row.value$ })
                        .addClass(self.myClass('value-view'))
                      .end()
                      .tag(self.Row.REMOVE, {
                        isDestructive: true,
                        // icon: '/images/remove-circle.svg',
                        // encode data as an embedded data URL of the SVG
                        // because then the GUI updates without flickering
                        icon: "data:image/svg+xml;utf8,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath fill='%23d9170e' d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z'/%3E%3C/svg%3E",
                        buttonStyle: 'UNSTYLED'
                      })
                    .end()
                  .endContext();
                row.onDetach(row.sub(self.updateDataWithoutFeedback));
              });
        }))
        .startContext({ data: this })
          .tag(this.ADD_ROW, { buttonStyle: 'SECONDARY' })
        .endContext();
    }
  ],

  listeners: [
    {
      name: 'updateData',
      code: function() {
        this.data = foam.Array.shallowClone(this.data);
      }
    },
    {
      name: 'updateDataWithoutFeedback',
      code: function() {
        this.feedback_ = true;
        this.updateData();
        this.feedback_ = false;
      }
    }

  ]
});
<|endoftext|>


<commit_before>const browserify = require('browserify');
const watchify = require('watchify');
const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const config = require('../config');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');

let bundler = browserify(config.scripts.sources)
  .transform('babelify', { presets: ['es2015'] })
  .transform('stringify', {
    appliesTo: { includeExtensions: ['.html'] },
  })
  .transform('browserify-ngannotate')
  .transform('browserify-css');

function bundle() {
  const stream = bundler.bundle()
    .pipe($.plumber())
    .pipe(source(`${config.scripts.destinationName}.js`))
    .pipe(buffer())
    .pipe(gulp.dest(config.dist));

  if (config.production) {
    stream
      .pipe($.sourcemaps.init({
        loadMaps: true,
      }))
      .pipe($.uglify())
      .pipe($.rename({
        extname: '.min.js',
      }))
      .pipe($.rev())
      .pipe($.sourcemaps.write('./'))
      .pipe(gulp.dest(config.dist));
  }

  stream.pipe($.connect.reload());

  return stream;
}

gulp.task('build:scripts', bundle);

gulp.task('watch:scripts', () => {
  bundler = watchify(bundler);
  bundler.on('update', () => gulp.start('build:scripts'));
});
<commit_msg>Fix #2 HTML templates not minified<commit_after>const browserify = require('browserify');
const watchify = require('watchify');
const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const config = require('../config');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');

let bundler = browserify(config.scripts.sources)
  .transform('babelify', { presets: ['es2015'] })
  .transform('stringify', {
    appliesTo: { includeExtensions: ['.html'] },
    minify: config.production,
  })
  .transform('browserify-ngannotate')
  .transform('browserify-css');

function bundle() {
  const stream = bundler.bundle()
    .pipe($.plumber())
    .pipe(source(`${config.scripts.destinationName}.js`))
    .pipe(buffer())
    .pipe(gulp.dest(config.dist));

  if (config.production) {
    stream
      .pipe($.sourcemaps.init({
        loadMaps: true,
      }))
      .pipe($.uglify())
      .pipe($.rename({
        extname: '.min.js',
      }))
      .pipe($.rev())
      .pipe($.sourcemaps.write('./'))
      .pipe(gulp.dest(config.dist));
  }

  stream.pipe($.connect.reload());

  return stream;
}

gulp.task('build:scripts', bundle);

gulp.task('watch:scripts', () => {
  bundler = watchify(bundler);
  bundler.on('update', () => gulp.start('build:scripts'));
});
<|endoftext|>


<commit_before>// Use the gulp-help plugin which defines a default gulp task
// which lists what tasks are available.
var gulp = require('gulp-help')(require('gulp'));

// Process and file manipulation to capture stdout
// from the Cucumber tests.
var spawn = require('child_process').spawn;
var fs = require('fs');

// Sequential Gulp tasks
var runSequence = require('run-sequence').use(gulp);

var projectPaths = require('../../package.json').paths;
var path = require('path');

var cucumber = require('gulp-cucumber');

var jasmine = require('gulp-jasmine');
var jasmineReporters = require('jasmine-reporters');

// Parse any command line arguments ignoring
// Node and the name of the calling script.
var argv = require('minimist')(process.argv.slice(2));

// Extract arguments for the Cucumber tasks.
var tags = argv.tags || false;
var reporter = argv.reporter || false;

// Create the reporters for Jamsine.
var terminalReporter = new jasmineReporters.TerminalReporter({
  color: true,
  verbosity: 3
});
var jUnitXmlReporter = new jasmineReporters.JUnitXmlReporter({
  savePath: path.normalize(projectPaths['test-output-dir']),
  filePrefix: 'unitTests',
  consolidateAll: true
});

function createCucumberOptions(tags, reporter) {
  return {
    support: projectPaths['cucumber-support-js'],
    tags: tags,
    format: reporter || 'summary'
  };
}

// Run all the Cucumber features, doesn't start server
gulp.task('test:cucumber', 'Run Cucumber alone, output to stdout', function() {
  return gulp.src(projectPaths['feature-files'])
  .pipe(cucumber(createCucumberOptions(tags, reporter)));
}, {
  options: {'tags': 'Supports optional tags argument e.g.\n\t\t\t--tags @parsing\n\t\t\t--tags @tag1,orTag2\n\t\t\t--tags @tag1 --tags @andTag2\n\t\t\t--tags @tag1 --tags ~@andNotTag2'}
});

// TODO convert the JSON output to XML output.

// Write Cucumber JSON output to file.
// Starting a new Cucumber process and captuting stdout is a work around
// Until CucmberJS supports arbitrary plugins at which point I'd
// hope a stream based reporter could be to gulp-cucumber and the
// results could be put in file in the normal Gulp way
// https://github.com/vgamula/gulp-cucumber/issues/17
gulp.task('test:cucumber:fileoutput', 'Run Cucumber, only output JSON to file.', function(done) {
  var baseEncoding = 'utf8';
  var outPath = path.join(projectPaths['test-output-dir'], 'cucumber.json');
  var fileStream = fs.createWriteStream(outPath, {
    encoding: baseEncoding
  });

  // The command args to run.
  // Use Cucumber JSON reporter with the intent to feed it to the Cucumber XML converter.
  // Use the Gulp --silent option to reduce the output to Cucumber JSON only.
  var commandArgs = ['test:cucumber', '--silent', '--reporter', 'json'];

  // Pass through any tags arguments.
  // Can be string or array so use
  // concat to gaurantee array.
  if (tags) {
    tags = [].concat(tags);
    commandArgs = tags.reduce(function(previous, current) {
      return previous.concat(['--tags', current]);
    }, commandArgs);
  }

  var stream = spawn('./node_modules/.bin/gulp', commandArgs);

  stream.stdout.setEncoding(baseEncoding);
  stream.stderr.setEncoding(baseEncoding);
  stream.stderr.pipe(fileStream);
  stream.stdout.pipe(fileStream);
  stream.on('close', function(e) {
    fileStream.end();
    done(e);
  });
}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// The default Cucumber test run requires the server to be running.
gulp.task('test:features', 'Everything necessesary to test the features.', function(done) {
  runSequence('set-envs:test',
  'server:start',
  'test:cucumber',
  function () {
    runSequence('server:stop', done);
  });
}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// The default Cucumber test run requires server to be running.
gulp.task('test:features:fileoutput', 'Everything necessesary to test the features and send the output to file.', function(done) {
  runSequence('set-envs:test',
  'server:start',
  'test:cucumber:fileoutput',
  function () {
    runSequence('server:stop', done);
  });

}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// Run the unit tests, report to terminal and disk.
gulp.task('test:unit', 'Run the unit tests.', function () {
  return gulp.src(projectPaths['unit-test-js'])
  .pipe(jasmine({
    reporter: [
      terminalReporter,
      jUnitXmlReporter
    ]
  }));
});
<commit_msg>Stop capturing stderr for the test resutls, so we can dump stuff in stderr and not have it mess up the json to xml conversion.<commit_after>// Use the gulp-help plugin which defines a default gulp task
// which lists what tasks are available.
var gulp = require('gulp-help')(require('gulp'));

// Process and file manipulation to capture stdout
// from the Cucumber tests.
var spawn = require('child_process').spawn;
var fs = require('fs');

// Sequential Gulp tasks
var runSequence = require('run-sequence').use(gulp);

var projectPaths = require('../../package.json').paths;
var path = require('path');

var cucumber = require('gulp-cucumber');

var jasmine = require('gulp-jasmine');
var jasmineReporters = require('jasmine-reporters');

// Parse any command line arguments ignoring
// Node and the name of the calling script.
var argv = require('minimist')(process.argv.slice(2));

// Extract arguments for the Cucumber tasks.
var tags = argv.tags || false;
var reporter = argv.reporter || false;

// Create the reporters for Jamsine.
var terminalReporter = new jasmineReporters.TerminalReporter({
  color: true,
  verbosity: 3
});
var jUnitXmlReporter = new jasmineReporters.JUnitXmlReporter({
  savePath: path.normalize(projectPaths['test-output-dir']),
  filePrefix: 'unitTests',
  consolidateAll: true
});

function createCucumberOptions(tags, reporter) {
  return {
    support: projectPaths['cucumber-support-js'],
    tags: tags,
    format: reporter || 'summary'
  };
}

// Run all the Cucumber features, doesn't start server
gulp.task('test:cucumber', 'Run Cucumber alone, output to stdout', function() {
  return gulp.src(projectPaths['feature-files'])
  .pipe(cucumber(createCucumberOptions(tags, reporter)));
}, {
  options: {'tags': 'Supports optional tags argument e.g.\n\t\t\t--tags @parsing\n\t\t\t--tags @tag1,orTag2\n\t\t\t--tags @tag1 --tags @andTag2\n\t\t\t--tags @tag1 --tags ~@andNotTag2'}
});

// TODO convert the JSON output to XML output.

// Write Cucumber JSON output to file.
// Starting a new Cucumber process and captuting stdout is a work around
// Until CucmberJS supports arbitrary plugins at which point I'd
// hope a stream based reporter could be to gulp-cucumber and the
// results could be put in file in the normal Gulp way
// https://github.com/vgamula/gulp-cucumber/issues/17
gulp.task('test:cucumber:fileoutput', 'Run Cucumber, only output JSON to file.', function(done) {
  var baseEncoding = 'utf8';
  var outPath = path.join(projectPaths['test-output-dir'], 'cucumber.json');
  var fileStream = fs.createWriteStream(outPath, {
    encoding: baseEncoding
  });

  // The command args to run.
  // Use Cucumber JSON reporter with the intent to feed it to the Cucumber XML converter.
  // Use the Gulp --silent option to reduce the output to Cucumber JSON only.
  var commandArgs = ['test:cucumber', '--silent', '--reporter', 'json'];

  // Pass through any tags arguments.
  // Can be string or array so use
  // concat to gaurantee array.
  if (tags) {
    tags = [].concat(tags);
    commandArgs = tags.reduce(function(previous, current) {
      return previous.concat(['--tags', current]);
    }, commandArgs);
  }

  var stream = spawn('./node_modules/.bin/gulp', commandArgs);

  stream.stdout.setEncoding(baseEncoding);
  stream.stdout.pipe(fileStream);
  stream.on('close', function(e) {
    fileStream.end();
    done(e);
  });
}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// The default Cucumber test run requires the server to be running.
gulp.task('test:features', 'Everything necessesary to test the features.', function(done) {
  runSequence('set-envs:test',
  'server:start',
  'test:cucumber',
  function () {
    runSequence('server:stop', done);
  });
}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// The default Cucumber test run requires server to be running.
gulp.task('test:features:fileoutput', 'Everything necessesary to test the features and send the output to file.', function(done) {
  runSequence('set-envs:test',
  'server:start',
  'test:cucumber:fileoutput',
  function () {
    runSequence('server:stop', done);
  });

}, {
  options: {'tags': 'Supports same optional tags arguments as \'test:cucumber\' task.'}
});

// Run the unit tests, report to terminal and disk.
gulp.task('test:unit', 'Run the unit tests.', function () {
  return gulp.src(projectPaths['unit-test-js'])
  .pipe(jasmine({
    reporter: [
      terminalReporter,
      jUnitXmlReporter
    ]
  }));
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs-extra');

console.log("=============================================");
console.log("Starting WordPress Hybrid Client Installation");
console.log("=============================================");

copy('../dist/config', '../config');
copy('../dist/root/config.xml', '../config.xml');
copy('../dist/root/ionic.config.json', '../ionic.config.json');
copy('../release.sh.dist', '../release.sh');

function copy(source, target, overwrite) {
    if (!overwrite && fs.existsSync(target)) {
        console.log('the destination already exist, will not overwrite: ' + target);
        return;
    }
    fs.copy(source, target, function(err) {
        if (err) return console.error(err)
        console.log('success: ' + target)
    })
}
<commit_msg>forces config overwrite when CI<commit_after>#!/usr/bin/env node

var fs = require('fs-extra');

console.log("=============================================");
console.log("Starting WordPress Hybrid Client Installation");
console.log("=============================================");

copy('../dist/config', '../config');
copy('../dist/root/config.xml', '../config.xml');
copy('../dist/root/ionic.config.json', '../ionic.config.json');
copy('../release.sh.dist', '../release.sh');

function copy(source, target, overwrite) {
    overwrite = process.env.CI ? true : overwrite;
    if (!overwrite && fs.existsSync(target)) {
        console.log('the destination already exist, will not overwrite: ' + target);
        return;
    }
    fs.copy(source, target, function (err) {
        if (err) return console.error(err)
        console.log('success: ' + target)
    })
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');

const HttpsProxyAgent = require('https-proxy-agent');
const fetch = require('node-fetch');
const ProgressBar = require('progress');
const Proxy = require('proxy-from-env');

const helper = require('../js/helper');
const pkgInfo = require('../package.json');

const CDN_URL =
  process.env.SENTRYCLI_LOCAL_CDNURL ||
  process.env.npm_config_sentrycli_cdnurl ||
  process.env.SENTRYCLI_CDNURL ||
  'https://github.com/getsentry/sentry-cli/releases/download';

function getDownloadUrl(platform, arch) {
  const releasesUrl = `${CDN_URL}/${pkgInfo.version}/sentry-cli`;
  const archString = arch.indexOf('64') > -1 ? 'x86_64' : 'i686';
  switch (platform) {
    case 'darwin':
      return `${releasesUrl}-Darwin-x86_64`;
    case 'win32':
      return `${releasesUrl}-Windows-${archString}.exe`;
    case 'linux':
    case 'freebsd':
      return `${releasesUrl}-Linux-${archString}`;
    default:
      return null;
  }
}

function createProgressBar(name, total) {
  if (process.stdout.isTTY) {
    return new ProgressBar(`fetching ${name} :bar :percent :etas`, {
      complete: '█',
      incomplete: '░',
      width: 20,
      total,
    });
  }

  if (/yarn/.test(process.env.npm_config_user_agent)) {
    let pct = null;
    let current = 0;
    return {
      tick: length => {
        current += length;
        const next = Math.round((current / total) * 100);
        if (next > pct) {
          pct = next;
          process.stdout.write(`fetching ${name} ${pct}%\n`);
        }
      },
    };
  }

  return { tick: () => {} };
}

function downloadBinary() {
  const arch = os.arch();
  const platform = os.platform();
  const outputPath = path.resolve(
    __dirname,
    platform === 'win32' ? '../bin/sentry-cli.exe' : '../sentry-cli'
  );

  if (fs.existsSync(outputPath)) {
    return Promise.resolve();
  }

  const downloadUrl = getDownloadUrl(platform, arch);
  if (!downloadUrl) {
    return Promise.reject(new Error(`unsupported target ${platform}-${arch}`));
  }

  const proxyUrl = Proxy.getProxyForUrl(downloadUrl);
  const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : null;

  // temporary fix for https://github.com/TooTallNate/node-https-proxy-agent/pull/43
  if (agent) {
    agent.defaultPort = 443;
  }

  return fetch(downloadUrl, { redirect: 'follow', agent }).then(response => {
    if (!response.ok) {
      throw new Error(`Received ${response.status}: ${response.statusText}`);
    }

    const name = downloadUrl.match(/.*\/(.*?)$/)[1];
    const total = parseInt(response.headers.get('content-length'), 10);
    const progressBar = createProgressBar(name, total);

    return new Promise((resolve, reject) => {
      response.body
        .on('error', e => reject(e))
        .on('data', chunk => progressBar.tick(chunk.length))
        .pipe(fs.createWriteStream(outputPath, { mode: '0755' }))
        .on('error', e => reject(e))
        .on('close', () => resolve());
    });
  });
}

function checkVersion() {
  return helper.execute(['--version']).then(output => {
    const version = output.replace('sentry-cli ', '').trim();
    const expected = process.env.SENTRYCLI_LOCAL_CDNURL ? 'DEV' : pkgInfo.version;
    if (version !== expected) {
      throw new Error(`Unexpected sentry-cli version: ${version}`);
    }
  });
}

if (process.env.SENTRYCLI_LOCAL_CDNURL) {
  // For testing, mock the CDN by spawning a local server
  const server = http.createServer((request, response) => {
    const contents = fs.readFileSync(path.join(__dirname, '../js/__mocks__/sentry-cli'));
    response.writeHead(200, {
      'Content-Type': 'application/octet-stream',
      'Content-Length': String(contents.byteLength),
    });
    response.end(contents);
  });

  server.listen(8999);
  process.on('exit', () => server.close());
}

downloadBinary()
  .then(() => checkVersion())
  .then(() => process.exit(0))
  .catch(e => {
    // eslint-disable-next-line no-console
    console.error(e.toString());
    process.exit(1);
  });
<commit_msg>ref(npm): Improve binary version verification error message (#409)<commit_after>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');

const HttpsProxyAgent = require('https-proxy-agent');
const fetch = require('node-fetch');
const ProgressBar = require('progress');
const Proxy = require('proxy-from-env');

const helper = require('../js/helper');
const pkgInfo = require('../package.json');

const CDN_URL =
  process.env.SENTRYCLI_LOCAL_CDNURL ||
  process.env.npm_config_sentrycli_cdnurl ||
  process.env.SENTRYCLI_CDNURL ||
  'https://github.com/getsentry/sentry-cli/releases/download';

function getDownloadUrl(platform, arch) {
  const releasesUrl = `${CDN_URL}/${pkgInfo.version}/sentry-cli`;
  const archString = arch.indexOf('64') > -1 ? 'x86_64' : 'i686';
  switch (platform) {
    case 'darwin':
      return `${releasesUrl}-Darwin-x86_64`;
    case 'win32':
      return `${releasesUrl}-Windows-${archString}.exe`;
    case 'linux':
    case 'freebsd':
      return `${releasesUrl}-Linux-${archString}`;
    default:
      return null;
  }
}

function createProgressBar(name, total) {
  if (process.stdout.isTTY) {
    return new ProgressBar(`fetching ${name} :bar :percent :etas`, {
      complete: '█',
      incomplete: '░',
      width: 20,
      total,
    });
  }

  if (/yarn/.test(process.env.npm_config_user_agent)) {
    let pct = null;
    let current = 0;
    return {
      tick: length => {
        current += length;
        const next = Math.round((current / total) * 100);
        if (next > pct) {
          pct = next;
          process.stdout.write(`fetching ${name} ${pct}%\n`);
        }
      },
    };
  }

  return { tick: () => {} };
}

function downloadBinary() {
  const arch = os.arch();
  const platform = os.platform();
  const outputPath = path.resolve(
    __dirname,
    platform === 'win32' ? '../bin/sentry-cli.exe' : '../sentry-cli'
  );

  if (fs.existsSync(outputPath)) {
    return Promise.resolve();
  }

  const downloadUrl = getDownloadUrl(platform, arch);
  if (!downloadUrl) {
    return Promise.reject(new Error(`unsupported target ${platform}-${arch}`));
  }

  const proxyUrl = Proxy.getProxyForUrl(downloadUrl);
  const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : null;

  // temporary fix for https://github.com/TooTallNate/node-https-proxy-agent/pull/43
  if (agent) {
    agent.defaultPort = 443;
  }

  return fetch(downloadUrl, { redirect: 'follow', agent }).then(response => {
    if (!response.ok) {
      throw new Error(`Received ${response.status}: ${response.statusText}`);
    }

    const name = downloadUrl.match(/.*\/(.*?)$/)[1];
    const total = parseInt(response.headers.get('content-length'), 10);
    const progressBar = createProgressBar(name, total);

    return new Promise((resolve, reject) => {
      response.body
        .on('error', e => reject(e))
        .on('data', chunk => progressBar.tick(chunk.length))
        .pipe(fs.createWriteStream(outputPath, { mode: '0755' }))
        .on('error', e => reject(e))
        .on('close', () => resolve());
    });
  });
}

function checkVersion() {
  return helper.execute(['--version']).then(output => {
    const version = output.replace('sentry-cli ', '').trim();
    const expected = process.env.SENTRYCLI_LOCAL_CDNURL ? 'DEV' : pkgInfo.version;
    if (version !== expected) {
      throw new Error(
        `Unexpected sentry-cli version "${version}", expected "${expected}`
      );
    }
  });
}

if (process.env.SENTRYCLI_LOCAL_CDNURL) {
  // For testing, mock the CDN by spawning a local server
  const server = http.createServer((request, response) => {
    const contents = fs.readFileSync(path.join(__dirname, '../js/__mocks__/sentry-cli'));
    response.writeHead(200, {
      'Content-Type': 'application/octet-stream',
      'Content-Length': String(contents.byteLength),
    });
    response.end(contents);
  });

  server.listen(8999);
  process.on('exit', () => server.close());
}

downloadBinary()
  .then(() => checkVersion())
  .then(() => process.exit(0))
  .catch(e => {
    // eslint-disable-next-line no-console
    console.error(e.toString());
    process.exit(1);
  });
<|endoftext|>


<commit_before>function generateLanguage() {

	var MainFunctionTemplate = _
			.template("function map_S_<%=input.replace('input','')%>_S_<%=output.replace('output','')%>(<%=input%>, <%=output%>) { <%_.forEach(mappings, function (mapping,i) {%>"
					+ "<%=mapping%>"
					+ "<%print('; ')%>"
					+ "<%})%>"
					+ "return <%=output%>;" + "\n" + "<%=utilityFunctions%>}");
	var MappingOperation = _
			.template("<%=output%> = resolveMapping(<%=input%> , <%=output%> , <%=mapperOperation%>)");

	var utilityFunctions = "function resolveMapping(input, output, mapperOperation) {if(mapperOperation === 'directmapping'){return input;}}";

	function VariableElement(name, id, value) {
		this.name = name;
		this.id = id;
		this.value = value;
		this.index = -1;
		this.visited = false;
	}

	VariableElement.prototype.isOutputVariable = function() {
		return this.name.search('output') == 0;
	};

	VariableElement.prototype.getName = function() {
		return this.name;
	};

	function OperationContainer(name, id) {
		this.name = name;
		this.id = id;
		this.index = -1;
		this.visited = false;
	}

	function VariablePair(source, target) {
		this.source = source;
		this.target = target;
	}

	VariablePair.prototype.printMapping = function() {
		return this.target.name + " = " + this.source.name;
	};

	VariablePair.prototype.getInput = function() {
		return this.source.name;
	};

	VariablePair.prototype.getOutput = function() {
		return this.target.name;
	};

	console.log("mapping started");
	var graphOperationModelElements = [];
	var inputVariablesArray = [];
	var outputVariablesArray = [];
	var operationsArray = [];
	var resolvedVariableArray = [];
	var resolvedOutputVariableArray = [];

	var inputAdjList = [];
	var outputAdjList = [];
	var executionSeq = [];
	var directVariableMappings = [];

	populateOutputVariableArray();
	populateAdjLists();
	GenerateExecutionSequence();
	var generatedScript = printOutput();
	return generatedScript;

	function printOutput() {
		var inputRootName = inputVariablesArray[0].getName().split(".")[0];
		var outputRootName = outputVariablesArray[0].getName().split(".")[0];
		var directMappingOutput = "";
		var mappings = [];
		for (var i = 0; directVariableMappings.length > i; ++i) {
			console.log(directVariableMappings[i].printMapping());
			directMappingOutput += directVariableMappings[i].printMapping()
					+ "\n";
			mappings.push(MappingOperation({
				input : directVariableMappings[i].getInput(),
				output : directVariableMappings[i].getOutput(),
				mapperOperation : '"directmapping"'
			}));
		}
		var operationString = "";
		var opNumber = -1;
		for (var index = 0; executionSeq.length > index; ++index) {
			operationString = "[ ";
			opNumber = executionSeq[index];
			var varList = outputAdjList[opNumber]
			for (var i = 0; i < varList.length; ++i) {
				operationString += varList[i].name + " ";
			}
			operationString += " ] = ";
			operationString += operationsArray[opNumber].name + " [ ";
			varList = inputAdjList[opNumber]
			for (var i = 0; i < varList.length; ++i) {
				operationString += inputVariablesArray[varList[i]].name + " ";
			}
			operationString += " ]";
			console.log(operationString);
			directMappingOutput += operationString + "\n";
		}

		return MainFunctionTemplate({
			input : inputRootName,
			output : outputRootName,
			mappings : mappings,
			utilityFunctions : utilityFunctions
		});
	}

	function GenerateExecutionSequence() {
		var startIndex = 0;
		var unexecutedOperationList = [];
		var tempUnexecutedOperationList = [];
		var numberOfOperations = operationsArray.length;
		for (var i = 0; i < numberOfOperations; ++i) {
			unexecutedOperationList.push(i);
		}
		while (executionSeq.length < numberOfOperations) {
			for (var index = 0; unexecutedOperationList.length > index; ++index) {
				if (operationIsExecutable(unexecutedOperationList[index])) {
					executionSeq.push(unexecutedOperationList[index]);
					addOutputsToResolvedVariables(unexecutedOperationList[index]);
				} else {
					tempUnexecutedOperationList
							.push(unexecutedOperationList[index]);
				}
			}
			unexecutedOperationList = tempUnexecutedOperationList;
			tempUnexecutedOperationList = [];
		}
	}

	function operationIsExecutable(index) {
		var inputVariables = inputAdjList[index];
		for (var count = 0; inputVariables.length > count; count++) {
			if (resolvedVariableArray.indexOf(inputVariables[count]) < 0) {
				return false;
			}
		}
		return true;
	}

	function addOutputsToResolvedVariables(index) {
		var outputVariables = outputAdjList[index];
		for (var count = 0; outputVariables.length > count; count++) {
			if (outputVariables[count].isOutputVariable()) {
				resolvedOutputVariableArray.push(outputVariables[count]);
			} else {
				resolvedVariableArray.push(outputVariables[count].index);
			}
		}
	}

	function populateAdjLists() {
		var tempNodeArray = [];
		var topElement = mInput.getEmbeddedCells()[0];
		tempNodeArray.push(topElement);
		var tempElement;
		var embeds;
		var variablePrefix = "input";
		var links = [];
		var link;
		var target;
		var source;
		while (tempNodeArray.length > 0) {
			tempElement = tempNodeArray.shift();
			if (isElementaVariableContainer(tempElement)) {
				embeds = tempElement.getEmbeddedCells();
				tempNodeArray = tempNodeArray.concat(embeds);
			} else if (isElementaVariable(tempElement)) {
				variablePrefix = "input";
				variablePrefix = getVariablePrefixValue(variablePrefix,
						tempElement);
				var tempVar = new VariableElement(getVariableName(
						variablePrefix, tempElement), tempElement.get('id'), "");
				inputVariablesArray.push(tempVar);
				tempElement.get('attrs')['graphProperties'].index = inputVariablesArray.length - 1;
				tempVar.index = inputVariablesArray.length - 1;
				resolvedVariableArray.push(tempVar.index);
				var opt = {
					outbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					target = link.getTargetElement();
					if (isElementaVariable(target) && target != null) {
						directVariableMappings
								.push(new VariablePair(
										inputVariablesArray[tempElement
												.get('attrs')['graphProperties'].index],
										outputVariablesArray[target
												.get('attrs')['graphProperties'].index]));
					} else if (target.get('attrs')['graphProperties'].marked == 0) {
						target.get('attrs')['graphProperties'].marked = 1;
						tempNodeArray.push(target);
					}
				}

			} else if (isElementanOperation(tempElement)
					&& tempElement.get('attrs')['graphProperties'].visited == 0) {
				var tempOp = new OperationContainer(
						getOperationName(tempElement), tempElement.get('id'));
				operationsArray.push(tempOp);
				graphOperationModelElements.push(tempElement);
				tempElement.get('attrs')['graphProperties'].index = operationsArray.length - 1;
				tempOp.index = operationsArray.length - 1;
				outputAdjList[tempOp.index] = [];
				inputAdjList[tempOp.index] = [];
				var opt = {
					outbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					target = link.getTargetElement();
					if (isElementaVariable(target) && target != null) {
						outputAdjList[tempOp.index]
								.push(outputVariablesArray[target.get('attrs')['graphProperties'].index]);
					} else {
						if (target.get('attrs')['graphProperties'].marked == 0) {
							target.get('attrs')['graphProperties'].marked = 1;
							tempNodeArray.push(target);
						}
						var variablePrefix = tempElement.get("attrs")['.label'].text
								+ "_"
								+ tempOp.index
								+ "_"
								+ link.get('source')['port'];
						var indexOfPort = tempElement.get('outPorts').indexOf(
								link.get('source')['port']);
						if (tempElement.get('attrs')['graphProperties'].portVariableIndex[indexOfPort] < 0) {
							var tempVar = new VariableElement(variablePrefix,
									tempElement.get('id'), "");
							inputVariablesArray.push(tempVar);
							tempElement.get('attrs')['graphProperties'].portVariableIndex[indexOfPort] = inputVariablesArray.length - 1;
							tempVar.index = inputVariablesArray.length - 1;
							outputAdjList[tempOp.index].push(tempVar);
							if (target.get('attrs')['graphProperties'].visited == 1) {
								inputAdjList[target.get('attrs')['graphProperties'].index]
										.push(tempVar.index);
							}

						}
					}
				}
				var opt = {
					inbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					source = link.getSourceElement();
					if (isElementaVariable(source) && source != null) {
						inputAdjList[tempOp.index]
								.push(source.get('attrs')['graphProperties'].index);
					} else {
						if (source.get('attrs')['graphProperties'].marked == 0) {
							source.get('attrs')['graphProperties'].marked = 1;
							tempNodeArray.push(source);
						} else if (source.get('attrs')['graphProperties'].visited == 1) {
							var indexOfPort = (source.get('outPorts'))
									.indexOf(link.get('source')['port']);

							inputAdjList[tempOp.index]
									.push(source.get('attrs')['graphProperties'].portVariableIndex[indexOfPort]);
						}

					}
				}

				tempElement.get('attrs')['graphProperties'].visited = 1;
			} else {
				console.log("Unknown Element");
			}
		}

		for (var index = 0; graphOperationModelElements.length > index; ++index) {
			graphOperationModelElements[index].get('attrs')['graphProperties'].visited = 0;
			graphOperationModelElements[index].get('attrs')['graphProperties'].marked = 0;
			graphOperationModelElements[index].get('attrs')['graphProperties'].index = -1;
			graphOperationModelElements[index].get('attrs')['graphProperties'].portVariableIndex = [];
			for (var i = 0; i < graphOperationModelElements[index]
					.get('outPorts').length; ++i) {
				graphOperationModelElements[index].get('attrs')['graphProperties'].portVariableIndex
						.push(-1);
			}
		}
	}

	function isElementaVariableContainer(element) {
		return element.getEmbeddedCells().length > 0;
	}

	function isElementaVariable(element) {
		return element.get("inPorts").length == 0
				|| element.get("outPorts").length == 0;
	}
	function isElementanOperation(element) {
		return element.get("inPorts").length > 0
				|| element.get("outPorts").length > 0;
	}

	function populateOutputVariableArray() {
		var tempNodeArray = [];
		var topElement = mOutput.getEmbeddedCells()[0];
		tempNodeArray.push(topElement);
		var tempElement;
		var embeds;
		var variablePrefix = "output";
		while (tempNodeArray.length > 0) {
			tempElement = tempNodeArray.pop();
			embeds = tempElement.getEmbeddedCells();
			if (embeds.length > 0) {
				tempNodeArray = tempNodeArray.concat(embeds);
			} else {
				variablePrefix = "output";
				variablePrefix = getVariablePrefixValue(variablePrefix,
						tempElement);
				outputVariablesArray
						.push(new VariableElement(getVariableName(
								variablePrefix, tempElement), tempElement
								.get('id'), ""));
				tempElement.get('attrs')['graphProperties'].index = outputVariablesArray.length - 1;
			}
		}
	}

	function getVariablePrefixValue(variablePrefix, tempElement) {
		var ancestorArray = tempElement.getAncestors();
		var parentsLength = ancestorArray.length;
		if (parentsLength > 2) {
			var tempPrefix = "";
			tempPrefix = ancestorArray[0].get("attrs")['.label'].text;
			for (var index = 2; index < parentsLength - 1; ++index) {
				tempPrefix = ancestorArray[index].get("attrs")['.label'].text
						+ "." + tempPrefix;
			}
			variablePrefix += tempPrefix;
		}
		return variablePrefix;
	}

	function insertStringAtPosition(position, baseString, newString) {
		var leftString = baseString.substring(0, position + 1);
		var rightString = baseString.substring(position + 1, baseString.length);
		return leftString + newString + rightString;
	}

	function getElementTextFromRect(element) {
		return element.get("attrs").text.text;
	}

	function getVariableName(variablePrefix, element) {
		return variablePrefix.concat(".", element.get("attrs")['.label'].text);
	}

	function getOperationName(element) {
		return element.get("attrs")['.label'].text;
	}
}
<commit_msg>Improving language Gen for do concat operation<commit_after>function generateLanguage() {

	var MainFunctionTemplate = _
			.template("function map_S_<%=input.replace('input','')%>_S_<%=output.replace('output','')%>(<%=input%>, <%=output%>) { <%_.forEach(mappings, function (mapping,i) {%>"
					+ "<%=mapping%>"
					+ "<%print('; ')%>"
					+ "<%})%>"
					+ "return <%=output%>;" + "\n" + "<%=utilityFunctions%>}");
	var MappingOperation = _
			.template("<% if (output.search('output') == 0) { %> <%=output%><% }else{ %>var <%=output%><%}%> = resolveMapping(<%=input%> , <%=output%> , <%=mapperOperation%>)");

	var utilityFunctions = "function resolveMapping(input, output, mapperOperation) {if (mapperOperation === 'directmapping') {	return input[0];"
			+ "} else if (mapperOperation == 'Concat') {return input[0] + ' ' + input[1];	}else if (mapperOperation === 'Split'){	return input[0].split(' ');	}}"
	/*
	 * +"function getVariableArrayFromMap(input, variable)
	 * {tempObj.push(input);var tempChildArray = [];var variableArray = [];var
	 * variableParentArray = variable.split('.');"+ "var parentNum =
	 * variableParentArray.length;for (var i = 1; i < parentNum-1; ++i) { var
	 * arraySize = tempObj.length;"+ "for (var j = 0; j < arraySize; ++j) {var
	 * obj = tempObj.shift()[variableParentArray[i]];for ( var element in obj)
	 * {"+ "tempChildArray.push(obj[element]); }} tempObj =
	 * tempChildArray;tempChildArray = [];}return tempObj;}";
	 */

	function VariableElement(name, id, value) {
		this.name = name;
		this.id = id;
		this.value = value;
		this.index = -1;
		this.visited = false;
	}

	VariableElement.prototype.isOutputVariable = function() {
		return this.name.search('output') == 0;
	};

	VariableElement.prototype.getName = function() {
		return this.name;
	};

	function OperationContainer(name, id) {
		this.name = name;
		this.id = id;
		this.index = -1;
		this.visited = false;
	}

	function VariablePair(source, target) {
		this.source = source;
		this.target = target;
	}

	VariablePair.prototype.printMapping = function() {
		return this.target.name + " = " + this.source.name;
	};

	VariablePair.prototype.getInput = function() {
		return this.source.name;
	};

	VariablePair.prototype.getOutput = function() {
		return this.target.name;
	};

	console.log("mapping started");
	var graphOperationModelElements = [];
	var inputVariablesArray = [];
	var outputVariablesArray = [];
	var operationsArray = [];
	var resolvedVariableArray = [];
	var resolvedOutputVariableArray = [];

	var inputAdjList = [];
	var outputAdjList = [];
	var executionSeq = [];
	var directVariableMappings = [];

	populateOutputVariableArray();
	populateAdjLists();
	GenerateExecutionSequence();
	var generatedScript = printOutput();
	return generatedScript;

	function printOutput() {
		var inputRootName = inputVariablesArray[0].getName().split(".")[0];
		var outputRootName = outputVariablesArray[0].getName().split(".")[0];
		var directMappingOutput = "";
		var mappings = [];
		for (var i = 0; directVariableMappings.length > i; ++i) {
			console.log(directVariableMappings[i].printMapping());
			directMappingOutput += directVariableMappings[i].printMapping()
					+ "\n";
			mappings.push(MappingOperation({
				input : directVariableMappings[i].getInput(),
				output : directVariableMappings[i].getOutput(),
				mapperOperation : '"directmapping"'
			}));
		}
		var operationString = "";
		var opNumber = -1;
		var inputArray = "";
		var outputArray = "";
		for (var index = 0; executionSeq.length > index; ++index) {
			operationString = "";
			opNumber = executionSeq[index];
			var varList = outputAdjList[opNumber]
			for (var i = 0; i < varList.length; ++i) {
				operationString += varList[i].name;
				if (i < varList.length - 1) {
					operationString += ",";
				}
			}
			operationString += "";
			outputArray = operationString;
			operationString = "[";
			varList = inputAdjList[opNumber]
			for (var i = 0; i < varList.length; ++i) {
				operationString += inputVariablesArray[varList[i]].name;
				if (i < varList.length - 1) {
					operationString += ",";
				}
			}
			operationString += "]";
			inputArray = operationString;
			console.log(operationString);
			directMappingOutput += operationString + "\n";
			mappings.push(MappingOperation({
				input : inputArray,
				output : outputArray,
				mapperOperation : "'" + operationsArray[opNumber].name + "'"
			}));
		}

		return MainFunctionTemplate({
			input : inputRootName,
			output : outputRootName,
			mappings : mappings,
			utilityFunctions : utilityFunctions
		});
	}

	function GenerateExecutionSequence() {
		var startIndex = 0;
		var unexecutedOperationList = [];
		var tempUnexecutedOperationList = [];
		var numberOfOperations = operationsArray.length;
		for (var i = 0; i < numberOfOperations; ++i) {
			unexecutedOperationList.push(i);
		}
		while (executionSeq.length < numberOfOperations) {
			for (var index = 0; unexecutedOperationList.length > index; ++index) {
				if (operationIsExecutable(unexecutedOperationList[index])) {
					executionSeq.push(unexecutedOperationList[index]);
					addOutputsToResolvedVariables(unexecutedOperationList[index]);
				} else {
					tempUnexecutedOperationList
							.push(unexecutedOperationList[index]);
				}
			}
			unexecutedOperationList = tempUnexecutedOperationList;
			tempUnexecutedOperationList = [];
		}
	}

	function operationIsExecutable(index) {
		var inputVariables = inputAdjList[index];
		for (var count = 0; inputVariables.length > count; count++) {
			if (resolvedVariableArray.indexOf(inputVariables[count]) < 0) {
				return false;
			}
		}
		return true;
	}

	function addOutputsToResolvedVariables(index) {
		var outputVariables = outputAdjList[index];
		for (var count = 0; outputVariables.length > count; count++) {
			if (outputVariables[count].isOutputVariable()) {
				resolvedOutputVariableArray.push(outputVariables[count]);
			} else {
				resolvedVariableArray.push(outputVariables[count].index);
			}
		}
	}

	function populateAdjLists() {
		var tempNodeArray = [];
		var topElement = mInput.getEmbeddedCells()[0];
		tempNodeArray.push(topElement);
		var tempElement;
		var embeds;
		var variablePrefix = "input";
		var links = [];
		var link;
		var target;
		var source;
		while (tempNodeArray.length > 0) {
			tempElement = tempNodeArray.shift();
			if (isElementaVariableContainer(tempElement)) {
				embeds = tempElement.getEmbeddedCells();
				tempNodeArray = tempNodeArray.concat(embeds);
			} else if (isElementaVariable(tempElement)) {
				variablePrefix = "input";
				variablePrefix = getVariablePrefixValue(variablePrefix,
						tempElement);
				var tempVar = new VariableElement(getVariableName(
						variablePrefix, tempElement), tempElement.get('id'), "");
				inputVariablesArray.push(tempVar);
				tempElement.get('attrs')['graphProperties'].index = inputVariablesArray.length - 1;
				tempVar.index = inputVariablesArray.length - 1;
				resolvedVariableArray.push(tempVar.index);
				var opt = {
					outbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					target = link.getTargetElement();
					if (isElementaVariable(target) && target != null) {
						directVariableMappings
								.push(new VariablePair(
										inputVariablesArray[tempElement
												.get('attrs')['graphProperties'].index],
										outputVariablesArray[target
												.get('attrs')['graphProperties'].index]));
					} else if (target.get('attrs')['graphProperties'].marked == 0) {
						target.get('attrs')['graphProperties'].marked = 1;
						tempNodeArray.push(target);
					}
				}

			} else if (isElementanOperation(tempElement)
					&& tempElement.get('attrs')['graphProperties'].visited == 0) {
				var tempOp = new OperationContainer(
						getOperationName(tempElement), tempElement.get('id'));
				operationsArray.push(tempOp);
				graphOperationModelElements.push(tempElement);
				tempElement.get('attrs')['graphProperties'].index = operationsArray.length - 1;
				tempOp.index = operationsArray.length - 1;
				outputAdjList[tempOp.index] = [];
				inputAdjList[tempOp.index] = [];
				var opt = {
					outbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					target = link.getTargetElement();
					if (isElementaVariable(target) && target != null) {
						outputAdjList[tempOp.index]
								.push(outputVariablesArray[target.get('attrs')['graphProperties'].index]);
					} else {
						if (target.get('attrs')['graphProperties'].marked == 0) {
							target.get('attrs')['graphProperties'].marked = 1;
							tempNodeArray.push(target);
						}
						var variablePrefix = tempElement.get("attrs")['.label'].text
								+ "_"
								+ tempOp.index
								+ "_"
								+ link.get('source')['port'];
						var indexOfPort = tempElement.get('outPorts').indexOf(
								link.get('source')['port']);
						if (tempElement.get('attrs')['graphProperties'].portVariableIndex[indexOfPort] < 0) {
							var tempVar = new VariableElement(variablePrefix,
									tempElement.get('id'), "");
							inputVariablesArray.push(tempVar);
							tempElement.get('attrs')['graphProperties'].portVariableIndex[indexOfPort] = inputVariablesArray.length - 1;
							tempVar.index = inputVariablesArray.length - 1;
							outputAdjList[tempOp.index].push(tempVar);
							if (target.get('attrs')['graphProperties'].visited == 1) {
								inputAdjList[target.get('attrs')['graphProperties'].index]
										.push(tempVar.index);
							}

						}
					}
				}
				var opt = {
					inbound : true
				};
				links = graph.getConnectedLinks(tempElement, opt);
				for (var count = 0; links.length > count; ++count) {
					link = links[count];
					source = link.getSourceElement();
					if (isElementaVariable(source) && source != null) {
						inputAdjList[tempOp.index]
								.push(source.get('attrs')['graphProperties'].index);
					} else {
						if (source.get('attrs')['graphProperties'].marked == 0) {
							source.get('attrs')['graphProperties'].marked = 1;
							tempNodeArray.push(source);
						} else if (source.get('attrs')['graphProperties'].visited == 1) {
							var indexOfPort = (source.get('outPorts'))
									.indexOf(link.get('source')['port']);

							inputAdjList[tempOp.index]
									.push(source.get('attrs')['graphProperties'].portVariableIndex[indexOfPort]);
						}

					}
				}

				tempElement.get('attrs')['graphProperties'].visited = 1;
			} else {
				console.log("Unknown Element");
			}
		}

		for (var index = 0; graphOperationModelElements.length > index; ++index) {
			graphOperationModelElements[index].get('attrs')['graphProperties'].visited = 0;
			graphOperationModelElements[index].get('attrs')['graphProperties'].marked = 0;
			graphOperationModelElements[index].get('attrs')['graphProperties'].index = -1;
			graphOperationModelElements[index].get('attrs')['graphProperties'].portVariableIndex = [];
			for (var i = 0; i < graphOperationModelElements[index]
					.get('outPorts').length; ++i) {
				graphOperationModelElements[index].get('attrs')['graphProperties'].portVariableIndex
						.push(-1);
			}
		}
	}

	function isElementaVariableContainer(element) {
		return element.getEmbeddedCells().length > 0;
	}

	function isElementaVariable(element) {
		return element.get("inPorts").length == 0
				|| element.get("outPorts").length == 0;
	}
	function isElementanOperation(element) {
		return element.get("inPorts").length > 0
				|| element.get("outPorts").length > 0;
	}

	function populateOutputVariableArray() {
		var tempNodeArray = [];
		var topElement = mOutput.getEmbeddedCells()[0];
		tempNodeArray.push(topElement);
		var tempElement;
		var embeds;
		var variablePrefix = "output";
		while (tempNodeArray.length > 0) {
			tempElement = tempNodeArray.pop();
			embeds = tempElement.getEmbeddedCells();
			if (embeds.length > 0) {
				tempNodeArray = tempNodeArray.concat(embeds);
			} else {
				variablePrefix = "output";
				variablePrefix = getVariablePrefixValue(variablePrefix,
						tempElement);
				outputVariablesArray
						.push(new VariableElement(getVariableName(
								variablePrefix, tempElement), tempElement
								.get('id'), ""));
				tempElement.get('attrs')['graphProperties'].index = outputVariablesArray.length - 1;
			}
		}
	}

	function getVariablePrefixValue(variablePrefix, tempElement) {
		var ancestorArray = tempElement.getAncestors();
		var parentsLength = ancestorArray.length;
		if (parentsLength > 2) {
			var tempPrefix = "";
			tempPrefix = ancestorArray[0].get("attrs")['.label'].text;
			for (var index = 1; index < parentsLength - 2; ++index) {
				tempPrefix = ancestorArray[index].get("attrs")['.label'].text
						+ "." + tempPrefix;
			}
			variablePrefix += tempPrefix;
		}
		return variablePrefix;
	}

	function insertStringAtPosition(position, baseString, newString) {
		var leftString = baseString.substring(0, position + 1);
		var rightString = baseString.substring(position + 1, baseString.length);
		return leftString + newString + rightString;
	}

	function getElementTextFromRect(element) {
		return element.get("attrs").text.text;
	}

	function getVariableName(variablePrefix, element) {
		return variablePrefix.concat(".", element.get("attrs")['.label'].text);
	}

	function getOperationName(element) {
		return element.get("attrs")['.label'].text;
	}
}
<|endoftext|>


<commit_before>// * ———————————————————————————————————————————————————————— * //
// * 	project configurator
// *	reads the configuration file and sets the variables
// * ———————————————————————————————————————————————————————— * //
var enduro_configurator = function () {}

// vendor dependencies
var fs = require('fs')
var extend = require('extend')

// local dependencies
var enduro_helpers = require(ENDURO_FOLDER + '/libs/flat_utilities/enduro_helpers')

// default public config
var public_default_config = {
	project_name: 'Enduro project',
	project_slug: 'en',
	render_templates: true,
	juicebox_enabled: true,
}

var secret_default_config = {}

// * ———————————————————————————————————————————————————————— * //
// * 	read configurtion file
// *
// *	@return {promise} - empty promise
// * ———————————————————————————————————————————————————————— * //
enduro_configurator.prototype.read_config = function () {

	var CONFIG_PATH = CMD_FOLDER + '/enduro.json'
	var SECRET_CONFIG_PATH = CMD_FOLDER + '/enduro_secret.json'

	return Promise.all([
		read_config_file(CONFIG_PATH, public_default_config),
		read_config_file(SECRET_CONFIG_PATH, secret_default_config)
	])
	.then(() => {
		global.config.variables = {}
		global.config.variables.S3_KEY = (global.config.secret && global.config.secret.s3 && global.config.secret.s3.S3_KEY) || process.env.S3_KEY
		global.config.variables.S3_SECRET = (global.config.secret && global.config.secret.s3 && global.config.secret.s3.S3_SECRET) || process.env.S3_SECRET

		global.config.variables.s3_enabled = (global.config.project_name && global.config.variables.S3_KEY && global.config.variables.S3_SECRET)
		global.config.variables.juicebox_enabled = global.config.variables.s3_possible && config.juicebox_enabled && !flags.nojuice
		return Promise.resolve()
	})
}

function read_config_file (config_file, default_config) {
	return new Promise(function (resolve, reject) {

		// check if file exists
		if (!enduro_helpers.file_exists_sync(config_file)) {

			// uses default config if no configuration is specified
			global.config = extend(true, config, default_config)
			resolve()
		} else {

			// Reads the configuration file
			fs.readFile(config_file, function read (err, data) {
				if (err) {
					logger.err_block(err)
					return reject()
				}

				// Parses json file
				local_config = JSON.parse(data)
				// Extend loaded file with default configuration
				global.config = extend(true, config, default_config, local_config)

				resolve()
			})
		}
	})
}

module.exports = new enduro_configurator()
<commit_msg>typo fix<commit_after>// * ———————————————————————————————————————————————————————— * //
// * 	project configurator
// *	reads the configuration file and sets the variables
// * ———————————————————————————————————————————————————————— * //
var enduro_configurator = function () {}

// vendor dependencies
var fs = require('fs')
var extend = require('extend')

// local dependencies
var enduro_helpers = require(ENDURO_FOLDER + '/libs/flat_utilities/enduro_helpers')

// default public config
var public_default_config = {
	project_name: 'Enduro project',
	project_slug: 'en',
	render_templates: true,
	juicebox_enabled: true,
}

var secret_default_config = {}

// * ———————————————————————————————————————————————————————— * //
// * 	read configurtion file
// *
// *	@return {promise} - empty promise
// * ———————————————————————————————————————————————————————— * //
enduro_configurator.prototype.read_config = function () {

	var CONFIG_PATH = CMD_FOLDER + '/enduro.json'
	var SECRET_CONFIG_PATH = CMD_FOLDER + '/enduro_secret.json'

	return Promise.all([
		read_config_file(CONFIG_PATH, public_default_config),
		read_config_file(SECRET_CONFIG_PATH, secret_default_config)
	])
	.then(() => {
		global.config.variables = {}
		global.config.variables.S3_KEY = (global.config.secret && global.config.secret.s3 && global.config.secret.s3.S3_KEY) || process.env.S3_KEY
		global.config.variables.S3_SECRET = (global.config.secret && global.config.secret.s3 && global.config.secret.s3.S3_SECRET) || process.env.S3_SECRET

		global.config.variables.s3_enabled = (global.config.project_name && global.config.variables.S3_KEY && global.config.variables.S3_SECRET)
		global.config.variables.juicebox_enabled = global.config.variables.s3_enabled && config.juicebox_enabled && !flags.nojuice
		return Promise.resolve()
	})
}

function read_config_file (config_file, default_config) {
	return new Promise(function (resolve, reject) {

		// check if file exists
		if (!enduro_helpers.file_exists_sync(config_file)) {

			// uses default config if no configuration is specified
			global.config = extend(true, config, default_config)
			resolve()
		} else {

			// Reads the configuration file
			fs.readFile(config_file, function read (err, data) {
				if (err) {
					logger.err_block(err)
					return reject()
				}

				// Parses json file
				local_config = JSON.parse(data)
				// Extend loaded file with default configuration
				global.config = extend(true, config, default_config, local_config)

				resolve()
			})
		}
	})
}

module.exports = new enduro_configurator()
<|endoftext|>


<commit_before>const yt = require('ytdl-core');
const streamy = require("stream");
const fs = require('fs');
const request = require("request");
const spawn = require("child_process").spawn

module.exports = Player;

function Player(message) {
	var that = this;

	this.message = message;
	this.channel = message.channel;
	this.voicechannel = message.member.voiceChannel;
	this.playlist = [];
	this.current = {};
	this.pid = null;
	this.stream = new streamy.Writable();

	this.connect = function() {
		this.voicechannel
			.join()
			.then(connection => {
				var looper = function() {

					//Get a new song playing on the stream
					that.play();
					console.dir(that.playlist);

					//Start playing that stream.
					const dispatcher = connection.playStream(that.stream);

					//When the stream ends, restart the "looper", which gets a new song on the stream
					dispatcher.on('end', () => {
						looper();
					});
				}
				looper();
			});
	}

	this.play = function() {
		this.current = this.playlist.shift();
		if(typeof this.current == "undefined") this.stop();

		//Make an ffmpeg stream
		let ffmpeg = spawn('ffmpeg', [
			'-i', 'pipe:0',
			'-f', 'wav',
			'pipe:1'
		]);

		this.pid = ffmpeg.pid;

		//Send the correct input to the ffmpeg stream
		switch (this.current.type) {

			//Stream from YouTube
			case "youtube":
				yt(this.current.url, {audioonly: true})
					.pipe(ffmpeg.stdin);

				break;

			//Stream from a local file
			case "local":
				fs.createReadStream(this.current.url)
					.pipe(ffmpeg.stdin);

				break;

			//Stream from the internet!
			case "http":
			case "https":
				request(this.current.url)
					.pipe(ffmpeg.stdin);

				break;
			default:
				this.channel.send(`${this.current.type} is not a valid audio provider.`);
				this.play();
		}

		this.stream = ffmpeg.stdout;

		ffmpeg.stderr.setEncoding('utf8');
		ffmpeg.stderr.on('data', function(data) {
			if(/^execvp\(\)/.test(data)) {
				console.log('failed to start ' + argv.ffmpeg);
				that.play();
			}
		});
	}

	this.add = function(type, url, title, thumb) {
		//Push a JSON string into the array
		this.playlist.push({
			type: type,
			url: url,
			title: title,
			thumb_url: thumb
		});

		//If the bot is not playing, enter the channel and start playing
		if (!this.voicechannel.connection) {
			this.connect();
		}
	}

	this.skip = function() {
		if (this.pid) process.kill(this.pid, "SIGINT");
		this.pid = null;
		this.stream.destroy();
	}

	this.stop = function() {
		this.playlist = []
		this.skip();
		if (this.voicechannel && this.voicechannel.connection) this.voicechannel.leave();
	}
}

process.on("unhandledRejection", function(err) {
	console.error("Uncaught Promise Error: \n" + err.stack);
});

process.on("uncaughtException", function(err) {
	console.error("Uncaught Exception Error: \n" + err.stack);
});
<commit_msg>return<commit_after>const yt = require('ytdl-core');
const streamy = require("stream");
const fs = require('fs');
const request = require("request");
const spawn = require("child_process").spawn

module.exports = Player;

function Player(message) {
	var that = this;

	this.message = message;
	this.channel = message.channel;
	this.voicechannel = message.member.voiceChannel;
	this.playlist = [];
	this.current = {};
	this.pid = null;
	this.stream = new streamy.Writable();

	this.connect = function() {
		this.voicechannel
			.join()
			.then(connection => {
				var looper = function() {

					//Get a new song playing on the stream
					that.play();
					console.dir(that.playlist);

					//Start playing that stream.
					const dispatcher = connection.playStream(that.stream);

					//When the stream ends, restart the "looper", which gets a new song on the stream
					dispatcher.on('end', () => {
						looper();
					});
				}
				looper();
			});
	}

	this.play = function() {
		this.current = this.playlist.shift();
		if(typeof this.current == "undefined") return this.stop();

		//Make an ffmpeg stream
		let ffmpeg = spawn('ffmpeg', [
			'-i', 'pipe:0',
			'-f', 'wav',
			'pipe:1'
		]);

		this.pid = ffmpeg.pid;

		//Send the correct input to the ffmpeg stream
		switch (this.current.type) {

			//Stream from YouTube
			case "youtube":
				yt(this.current.url, {audioonly: true})
					.pipe(ffmpeg.stdin);

				break;

			//Stream from a local file
			case "local":
				fs.createReadStream(this.current.url)
					.pipe(ffmpeg.stdin);

				break;

			//Stream from the internet!
			case "http":
			case "https":
				request(this.current.url)
					.pipe(ffmpeg.stdin);

				break;
			default:
				this.channel.send(`${this.current.type} is not a valid audio provider.`);
				this.play();
		}

		this.stream = ffmpeg.stdout;

		ffmpeg.stderr.setEncoding('utf8');
		ffmpeg.stderr.on('data', function(data) {
			if(/^execvp\(\)/.test(data)) {
				console.log('failed to start ' + argv.ffmpeg);
				that.play();
			}
		});
	}

	this.add = function(type, url, title, thumb) {
		//Push a JSON string into the array
		this.playlist.push({
			type: type,
			url: url,
			title: title,
			thumb_url: thumb
		});

		//If the bot is not playing, enter the channel and start playing
		if (!this.voicechannel.connection) {
			this.connect();
		}
	}

	this.skip = function() {
		if (this.pid) process.kill(this.pid, "SIGINT");
		this.pid = null;
		this.stream.destroy();
	}

	this.stop = function() {
		this.playlist = []
		this.skip();
		if (this.voicechannel && this.voicechannel.connection) this.voicechannel.leave();
	}
}

process.on("unhandledRejection", function(err) {
	console.error("Uncaught Promise Error: \n" + err.stack);
});

process.on("uncaughtException", function(err) {
	console.error("Uncaught Exception Error: \n" + err.stack);
});
<|endoftext|>


<commit_before>// Install UrlRouting in the root object, so other modules can install routes
// for Root without having to define getChildElement again.

UrlRouting.draw(this, {});

Root.inject({
	getChildElement: function(name) {
		// TODO: Fix Helma bug where mappings are returned before subnodes.
		// e.g. this.get('Users') and this.users should not return the same!
		// WORKAROUND: Fetch from pure children list first, then if not found
		// try properties too (e.g. resources, etc)
		var obj = this.children.get(name);
		if (!obj) {
			obj = this.base(name);
			if (!obj)
				obj = UrlRouting.handle(this, name);
		}
		return obj;
	}
});<commit_msg>Check routes before internal mappings to give full control over weird fact that Helma returns mappings as children (it should not...).<commit_after>// Install UrlRouting in the root object, so other modules can install routes
// for Root without having to define getChildElement again.

UrlRouting.draw(this, {});

Root.inject({
	getChildElement: function(name) {
		// TODO: Fix Helma bug where mappings are returned before subnodes.
		// e.g. this.get('Users') and this.users should not return the same!
		// WORKAROUND: Fetch from pure children list first, then if not found
		// try properties too (e.g. resources, etc)
		var obj = this.children.get(name);
		if (!obj) {
			// Try url routes first, this.base as last, to really offer multiple
			// ways to interfere with Helma returning internal mappings.
			obj = UrlRouting.handle(this, name);
			if (!obj)
				obj = this.base(name);
		}
		return obj;
	}
});<|endoftext|>