<commit_before>const marked = require('marked');
const toc = require('markdown-toc');
const highlight = require('highlight.js');
const Base = require('./base');

module.exports = class extends Base {
  get relation() {
    return {
      tag: think.Model.MANY_TO_MANY,
      cate: think.Model.MANY_TO_MANY,
      user: {
        type: think.Model.BELONG_TO,
        // fKey: 'user_id',
        // key: 'display_name',
        field: 'id,name,display_name'
      }
    };
  }

  /**
   * 添加文章
   * @param {[type]} data [description]
   * @param {[type]} ip   [description]
   */
  addPost(data) {
    let create_time = think.datetime();
    data = Object.assign({
      type: 0,
      status: 0,
      create_time,
      update_time: create_time,
      is_public: 1
    }, data);

    return this.where({ pathname: data.pathname }).thenAdd(data);
  }

  async savePost(data) {
    let info = await this.where({ id: data.id }).find();
    if (think.isEmpty(info)) {
      return Promise.reject(new Error('POST_NOT_EXIST'));
    }
    data.update_time = think.datetime();
    return this.where({ id: data.id }).update(data);
  }

  async deletePost(post_id) {
    //await this.model('post_cate').delete({post_id});
    //await this.model('post_tag').delete({post_id});
    return this.where({ id: post_id }).delete();
  }

  /**
   * get count posts
   * @param  {Number} userId []
   * @return {Promise}        []
   */
  getCount(userId) {
    if (userId) {
      return this.where({ user_id: userId }).count();
    }
    return this.count();
  }
  /**
   * get latest posts
   * @param  {Number} nums []
   * @return {}      []
   */
  getLatest(user_id, nums = 10) {
    let where = {
      create_time: { '<=': think.datetime() },
      is_public: 1, //公开
      type: 0, //文章
      status: 3, //已经发布
    };
    if (user_id) { where.user_id = user_id; }
    return this.order('id DESC')
      .where(where)
      .limit(nums)
      .setRelation(false)
      .order('create_time DESC')
      .select();
  }

  async afterUpdate(data, options) {
    await super.afterUpdate(data, options);
    return this.clearCache();
  }

  async afterDelete(data, options) {
    await super.afterDelete(data, options);
    return this.clearCache();
  }

  async afterAdd(data, options) {
    await super.afterAdd(data, options);
    return this.clearCache();
  }

  async clearCache() {
    think.logger.debug('clear cache');
    await think.cache('post_1', null);
    await think.cache('lastPostList', null);
  }

  /**
   * 更新所有文章的摘要信息并重新保存到数据库
   *
   * @returns {Promise.<void>}
   */
  async updateAllPostSummaries() {
    // get all posts' id and mark down content
    const posts = await this.field('id, markdown_content').setRelation(false).select();
    const allPromises = [];

    if (posts.length > 0) {
      for (let i = 0; i < posts.length; i++) {
        const item = posts[i];
        const summary = await this.getSummary(item.markdown_content);

        allPromises.push(this.where({ id: item.id }).update({ summary }))
      }

      await Promise.all(allPromises)
    }
  }

  /**
   * 渲染 markdown
   * 摘要为部分内容时不展示 TOC
   * 文章正文设置为手动指定 TOC 时不显示
   * 页面不自动生成 TOC 除非是手动指定了
   */
  async getContentAndSummary(data) {
    const options = await this.model('options').getOptions();
    const postTocManual = options.postTocManual === '1';
    const auto_summary = parseInt(options.auto_summary);

    let showToc;
    if (!postTocManual) {
      showToc = data.type / 1 === 0;
    } else {
      showToc = /(?:^|[\r\n]+)\s*\s*[\r\n]+/i.test(data.markdown_content);
    }
    data.content = await this.markdownToHtml(data.markdown_content, { toc: showToc, highlight: true });
    data.summary = await this.getSummary(data.markdown_content, auto_summary)

    return data;
  }

  /**
   * 渲染 markdown 并返回摘要内容
   * 区别于 getContentAndSummary 方法，此方法只处理和返回摘要
   *
   * @param markdown_content MarkDown 内容
   * @param summary_length 摘要长度（可为空）
   * @return {string}
   */
  async getSummary(markdown_content, summary_length) {
    let summary;

    if (!summary_length) {
      const options = await this.model('options').getOptions();
      summary_length = parseInt(options.auto_summary);
    }

    const hasMoreTag = /(?:^|[\r\n]+)\s*\s*[\r\n]+/i.test(markdown_content);

    if (hasMoreTag || summary_length === 0) {
      summary = markdown_content.split('')[0];
      summary = await this.markdownToHtml(summary, { toc: false, highlight: true });
      summary.replace(/<[>]*>/g, '');

    } else {
      summary = await this.markdownToHtml(markdown_content, { toc: false, highlight: true });
      // 过滤掉 HTML 标签 及换行等 并截取所需的长度
      // 增加过滤 svg 内容
      summary = summary
        .replace(/[\n\r\t]/g, '')
        .replace(/<svg[ >].*?<\/svg>/g, '')
        .replace(/<\/?[^>]*>/g, '')
        .substr(0, summary_length) + '...';
    }

    return summary;
  }

  /**
   * markdown to html
   * @return {string}
   */
  async markdownToHtml(content, option = { toc: true, highlight: true }) {

    // 使用包含 MathJax 解析的 Markdown 引擎解析 MD 文本
    let markedWithMathJax = think.service('marked-with-mathjax');
    let markedContent = await markedWithMathJax.render(content);

    /**
     * 增加 TOC 目录
     */
    if (option.toc) {
      let tocContent = marked(toc(content).content).replace(/([^<>]+)<\/a>/g, (a, b, c) => {
        return `<a href="#${this.generateTocName(c)}">${c}</a>`;
      });

      markedContent = markedContent.replace(/<h(\d)[^<>]*>(.*?)<\/h\1>/g, (a, b, c) => {
        return `<h${b}><a id="${this.generateTocName(c)}" class="anchor" href="#${this.generateTocName(c)}"></a>${c}</h${b}>`;
      });
      markedContent = `<div class="toc">${tocContent}</div>${markedContent}`;
    }

    /**
     * 增加代码高亮
     */
    if (option.highlight) {
      markedContent = markedContent.replace(/
([\s\S]+?)<\/code><\/pre>/mg, (a, language, text) => {
        text = text.replace(/'/g, '\'')
          .replace(/>/g, '>')
          .replace(/</g, '<')
          .replace(/"/g, '"')
          .replace(/&/g, '&');
        var result = highlight.highlightAuto(text, language ? [language] : undefined);
        return `<pre><code class="hljs lang-${result.language}">${result.value}</code></pre>`;
      });
    }

    return markedContent;
  }

  /**
   * 获取文章创建时间
   *
   * @param data
   * @returns {*}
   */
  getPostTime(data) {
    data.update_time = think.datetime();
    if (!data.create_time) {
      data.create_time = data.update_time;
    } else {
      data.create_time = think.datetime(data.create_time);
    }
    return data;
  }

  /**
   * generate toc name
   * @param  {String} name []
   * @return {String}      []
   */
  generateTocName(name) {
    name = name.trim()
      .replace(/\s+/g, '')
      .replace(/\)/g, '')
      .replace(/[(,]/g, '-')
      .toLowerCase();
    if (/^[\w-]+$/.test(name)) {
      return name;
    }
    return `toc-${think.md5(name).slice(0, 3)}`;
  }
}
<commit_msg>fix: fix #774<commit_after>const marked = require('marked');
const toc = require('markdown-toc');
const highlight = require('highlight.js');
const Base = require('./base');

module.exports = class extends Base {
  get relation() {
    return {
      tag: think.Model.MANY_TO_MANY,
      cate: think.Model.MANY_TO_MANY,
      user: {
        type: think.Model.BELONG_TO,
        // fKey: 'user_id',
        // key: 'display_name',
        field: 'id,name,display_name'
      }
    };
  }

  /**
   * 添加文章
   * @param {[type]} data [description]
   * @param {[type]} ip   [description]
   */
  addPost(data) {
    let create_time = think.datetime();
    data = Object.assign({
      type: 0,
      status: 0,
      create_time,
      update_time: create_time,
      is_public: 1
    }, data);

    return this.where({ pathname: data.pathname }).thenAdd(data);
  }

  async savePost(data) {
    let info = await this.where({ id: data.id }).find();
    if (think.isEmpty(info)) {
      return Promise.reject(new Error('POST_NOT_EXIST'));
    }
    data.update_time = think.datetime();
    return this.where({ id: data.id }).update(data);
  }

  async deletePost(post_id) {
    //await this.model('post_cate').delete({post_id});
    //await this.model('post_tag').delete({post_id});
    return this.where({ id: post_id }).delete();
  }

  /**
   * get count posts
   * @param  {Number} userId []
   * @return {Promise}        []
   */
  getCount(userId) {
    if (userId) {
      return this.where({ user_id: userId }).count();
    }
    return this.count();
  }
  /**
   * get latest posts
   * @param  {Number} nums []
   * @return {}      []
   */
  getLatest(user_id, nums = 10) {
    let where = {
      create_time: { '<=': think.datetime() },
      is_public: 1, //公开
      type: 0, //文章
      status: 3, //已经发布
    };
    if (user_id) { where.user_id = user_id; }
    return this.order('id DESC')
      .where(where)
      .limit(nums)
      .setRelation(false)
      .order('create_time DESC')
      .select();
  }

  async afterUpdate(data, options) {
    await super.afterUpdate(data, options);
    return this.clearCache();
  }

  async afterDelete(data, options) {
    await super.afterDelete(data, options);
    return this.clearCache();
  }

  async afterAdd(data, options) {
    await super.afterAdd(data, options);
    return this.clearCache();
  }

  async clearCache() {
    think.logger.debug('clear cache');
    await think.cache('post_1', null);
    await think.cache('lastPostList', null);
  }

  /**
   * 更新所有文章的摘要信息并重新保存到数据库
   *
   * @returns {Promise.<void>}
   */
  async updateAllPostSummaries() {
    // get all posts' id and mark down content
    const posts = await this.field('id, markdown_content').setRelation(false).select();
    const allPromises = [];

    if (posts.length > 0) {
      for (let i = 0; i < posts.length; i++) {
        const item = posts[i];
        const summary = await this.getSummary(item.markdown_content);

        allPromises.push(this.where({ id: item.id }).update({ summary }))
      }

      await Promise.all(allPromises)
    }
  }

  /**
   * 渲染 markdown
   * 摘要为部分内容时不展示 TOC
   * 文章正文设置为手动指定 TOC 时不显示
   * 页面不自动生成 TOC 除非是手动指定了
   */
  async getContentAndSummary(data) {
    const options = await this.model('options').getOptions();
    const postTocManual = options.postTocManual === '1';
    const auto_summary = parseInt(options.auto_summary);

    let showToc;
    if (!postTocManual) {
      showToc = data.type / 1 === 0;
    } else {
      showToc = /(?:^|[\r\n]+)\s*\s*[\r\n]+/i.test(data.markdown_content);
    }
    data.content = await this.markdownToHtml(data.markdown_content, { toc: showToc, highlight: true });
    data.summary = await this.getSummary(data.markdown_content, auto_summary)

    return data;
  }

  /**
   * 渲染 markdown 并返回摘要内容
   * 区别于 getContentAndSummary 方法，此方法只处理和返回摘要
   *
   * @param markdown_content MarkDown 内容
   * @param summary_length 摘要长度（可为空）
   * @return {string}
   */
  async getSummary(markdown_content, summary_length) {
    let summary;

    if (!summary_length) {
      const options = await this.model('options').getOptions();
      summary_length = parseInt(options.auto_summary);
    }

    const hasMoreTag = /(?:^|[\r\n]+)\s*\s*[\r\n]+/i.test(markdown_content);

    if (hasMoreTag || summary_length === 0) {
      summary = markdown_content.split('')[0];
      summary = await this.markdownToHtml(summary, { toc: false, highlight: true });
      summary.replace(/<[>]*>/g, '');

    } else {
      summary = await this.markdownToHtml(markdown_content, { toc: false, highlight: true });
      // 过滤掉 HTML 标签 及换行等 并截取所需的长度
      // 增加过滤 svg 内容
      summary = summary
        .replace(/[\n\r\t]/g, '')
        .replace(/<svg[ >].*?<\/svg>/g, '')
        .replace(/<\/?[^>]*>/g, '')
        .substr(0, summary_length) + '...';
    }

    return summary;
  }

  /**
   * markdown to html
   * @return {string}
   */
  async markdownToHtml(content, option = { toc: true, highlight: true }) {

    // 使用包含 MathJax 解析的 Markdown 引擎解析 MD 文本
    let markedWithMathJax = think.service('marked-with-mathjax');
    let markedContent = await markedWithMathJax.render(content);

    /**
     * 增加 TOC 目录
     */
    if (option.toc) {
      let tocContent = marked(toc(content).content).replace(/(.+)?<\/a>/g, (a, b, c) => {
        return `<a href="#${this.generateTocName(c)}">${c}</a>`;
      });

      markedContent = markedContent.replace(/<h(\d)[^<>]*>(.*?)<\/h\1>/g, (a, b, c) => {
        return `<h${b}><a id="${this.generateTocName(c)}" class="anchor" href="#${this.generateTocName(c)}"></a>${c}</h${b}>`;
      });
      markedContent = `<div class="toc">${tocContent}</div>${markedContent}`;
    }

    /**
     * 增加代码高亮
     */
    if (option.highlight) {
      markedContent = markedContent.replace(/
([\s\S]+?)<\/code><\/pre>/mg, (a, language, text) => {
        text = text.replace(/'/g, '\'')
          .replace(/>/g, '>')
          .replace(/</g, '<')
          .replace(/"/g, '"')
          .replace(/&/g, '&');
        var result = highlight.highlightAuto(text, language ? [language] : undefined);
        return `<pre><code class="hljs lang-${result.language}">${result.value}</code></pre>`;
      });
    }

    return markedContent;
  }

  /**
   * 获取文章创建时间
   *
   * @param data
   * @returns {*}
   */
  getPostTime(data) {
    data.update_time = think.datetime();
    if (!data.create_time) {
      data.create_time = data.update_time;
    } else {
      data.create_time = think.datetime(data.create_time);
    }
    return data;
  }

  /**
   * generate toc name
   * @param  {String} name []
   * @return {String}      []
   */
  generateTocName(name) {
    name = name.trim()
      .replace(/\s+/g, '')
      .replace(/\)/g, '')
      .replace(/[(,]/g, '-')
      .toLowerCase();
    if (/^[\w-]+$/.test(name)) {
      return name;
    }
    return `toc-${think.md5(name).slice(0, 3)}`;
  }
}
<|endoftext|>


<commit_before>/*
 * @author: Benjamin Oertel (https://github.com/boertel)
 * @date: 01/01/2012
 *
*/
(function () {
    "Barbe:nomunge";
    var Barbe = {
        html: {},
        templates: {},
        settings: {
            template: {
                render: Mustache.render,
                compile: undefined,
                type: ['text/html']
            },
            /*
             template: {
                 render: function (self, context, partials) {
                     self.render(context, partials);
                 }
                 compile: hogan.compile(str),
                 type: ['text/html']
             }
             */
            ajax: $.ajax,
            loader: {
                className: "barbe-loader",
                id: "barbe_loader"
            }
        },

        /**
         * Initalize template in a dictionary: add the render function to create the final result.
         * @param name         {string} name of the template
         * @param str_template {string} template itself
         * @param [anchor]     {string} id of the anchor
         */
        add: function (name, str_template, anchor) {
            if (Barbe.html.hasOwnProperty(name)) {
                throw "[Barbe] You've already got a template by the name: \"" + name + "\"";
            }
            else {
                if (Barbe.settings.template.compile !== undefined) {
                    Barbe.html[name] = Barbe.settings.template.compile(str_template);
                } else {
                    Barbe.html[name] = str_template;
                }
                Barbe.templates[name] = {};

                if (typeof anchor !== "undefined") {
                    var element = document.getElementById(anchor);
                    if (element !== null) {
                        Barbe.templates[name].anchor = element;
                    }
                }
                Barbe.templates[name].render = function (data) {
                    data = data || {};
                    var html = Barbe.settings.template.render(Barbe.html[name], data, Barbe.html);
                    if (Barbe.templates[name].anchor !== undefined) {
                        Barbe.templates[name].anchor.innerHTML = html;
                    }
                    return html;
                };

            }
        },

        /**
         * Parse the html to collect templates defined by <script type="<Barbe.settings.template.type>" id="" [data-anchor=""]></script>
         */
        grab: function () {
            scripts = document.scripts || document.getElementsByTagName('script');
            for(var i = 0, len = scripts.length; i < len; i++) {
                var s = scripts[i];
                if (Barbe.settings.template.type.indexOf(s.type) !== -1) {
                    Barbe.add(s.id, s.innerHTML, s.getAttribute("data-anchor"));
                }
            }
        }
    };

    /**
     * Constructor
     * @param template       {string} template name
     * @param provider.data  {object} data that populates the template
     * @param provider.url   {string} url of the api
     * @param provider.*     {*}      parameters for the ajax function
     * @param [args.anchor]  {string} id of the anchor (overwrite the one defined on the template script tag)
     */
    Barbe.View = function (template, provider, args) {
        if (template === undefined || Barbe.templates[template] === undefined) {
            throw "[Barbe] template #" + template + " not found.";
        }
        this.template = Barbe.templates[template].render;
        this.anchor = Barbe.templates[template].anchor;
        this.options = {};

        var anchor;

        if (typeof args === "string") {
            anchor = args;
        } else if (typeof args !== "undefined") {
            anchor = args.anchor;
            delete args.anchor;
            this.options = args;
        }

        if (anchor !== undefined) {
            this.anchor = document.getElementById(anchor);
            if (this.anchor === null) {
                throw "[Barbe] anchor #" + anchor + " not found.";
            } else {
                Barbe.templates[template].anchor = this.anchor;
            }
        }

        this.provider = provider || {};
    };

    /**
     * Populate the template with the data. Create a dumb object {array: data} if data is an array
     * @param response {object} data that populates the template
     */
    Barbe.View.prototype.render = function (response) {
        // Mustache doesn't like array as data, so we have to create
        // a dumb object named "array" that contained the array
        if (Object.prototype.toString.call(response) === '[object Array]') {
            response = {
                array: response
            };
        }

        this.view = this.template(response);
        return this.view;
    };

    /**
     *  Render the template with the response and attach it to the anchor
     *  @params response {object}       api response or data for the template
     *  @params callback {castAnchor}   function called after
     */
    Barbe.View.prototype.castAnchor = function (response, callback) {
        // TODO move this to the render function
        this.loader && this.loader.remove();
        var rendered = this.render(response);
        callback && callback.call(this, rendered);
    };

    /**
     * Process the ajax call
     * @param callback {function} function executed when the ajax call successed and the template has been populated
     */
    Barbe.View.prototype.ajax = function (callback) {
        var that = this;

        var success = this.provider.success;
        var monkeySuccess = function (response) {
            if (success !== undefined) {
                response = success.call(that, response);
            }
            that.castAnchor.call(that, response, callback);
        };

        that.ajaxParams = this.provider;
        that.ajaxParams.success = monkeySuccess;
        Barbe.settings.ajax(that.ajaxParams);
    };

    /**
     * Run Barbe to populate the template and attach it the anchor
     * @param callback {function} function executed when the ajax call successed and the template has been populated
     */
    Barbe.View.prototype.grow = function (callback) {
        if (this.provider.url !== undefined) {
            if (Barbe.settings.loader !== false) {
                this.loader = new Barbe.Loader(this.anchor);
            }
            this.ajax.call(this, callback);
        } else {
            var response = this.provider.data;
            if (this.provider.success !== undefined) {
                response = this.provider.success && this.provider.success(this.provider.data);
            }
            this.castAnchor(response, callback);
        }
    };

    /**
     * Constructor:
     * @param anchor {Node} Element where the loader is added
     */
    Barbe.Loader = function (anchor) {
        this.anchor = anchor;
        this.div = document.createElement("div");
        this.div.className = Barbe.settings.className;
        this.div.id = Barbe.settings.id;
        // Clean up the anchor
        while (this.anchor.hasChildNodes()) {
            this.anchor.removeChild(this.anchor.lastChild);
        }
        this.anchor.appendChild(this.div);
    };

    /**
     * Remove the loader from the anchor
     */
    Barbe.Loader.prototype.remove = function () {
        this.anchor.removeChild(this.div);
    };

    window.Barbe = Barbe;
    Barbe.grab();
})();
<commit_msg>grab when dom is loaded<commit_after>/*
 * @author: Benjamin Oertel (https://github.com/boertel)
 * @date: 01/01/2012
 *
*/
(function () {
    "Barbe:nomunge";
    var Barbe = {
        html: {},
        templates: {},
        settings: {
            template: {
                render: Mustache.render,
                compile: undefined,
                type: ['text/html']
            },
            /*
             template: {
                 render: function (self, context, partials) {
                     self.render(context, partials);
                 }
                 compile: hogan.compile(str),
                 type: ['text/html']
             }
             */
            ajax: $.ajax,
            loader: {
                className: "barbe-loader",
                id: "barbe_loader"
            }
        },

        /**
         * Initalize template in a dictionary: add the render function to create the final result.
         * @param name         {string} name of the template
         * @param str_template {string} template itself
         * @param [anchor]     {string} id of the anchor
         */
        add: function (name, str_template, anchor) {
            if (Barbe.html.hasOwnProperty(name)) {
                throw "[Barbe] You've already got a template by the name: \"" + name + "\"";
            }
            else {
                if (Barbe.settings.template.compile !== undefined) {
                    Barbe.html[name] = Barbe.settings.template.compile(str_template);
                } else {
                    Barbe.html[name] = str_template;
                }
                Barbe.templates[name] = {};

                if (typeof anchor !== "undefined") {
                    var element = document.getElementById(anchor);
                    if (element !== null) {
                        Barbe.templates[name].anchor = element;
                    }
                }
                Barbe.templates[name].render = function (data) {
                    data = data || {};
                    var html = Barbe.settings.template.render(Barbe.html[name], data, Barbe.html);
                    if (Barbe.templates[name].anchor !== undefined) {
                        Barbe.templates[name].anchor.innerHTML = html;
                    }
                    return html;
                };

            }
        },

        /**
         * Parse the html to collect templates defined by <script type="<Barbe.settings.template.type>" id="" [data-anchor=""]></script>
         */
        grab: function () {
            scripts = document.scripts || document.getElementsByTagName('script');
            for(var i = 0, len = scripts.length; i < len; i++) {
                var s = scripts[i];
                if (Barbe.settings.template.type.indexOf(s.type) !== -1) {
                    Barbe.add(s.id, s.innerHTML, s.getAttribute("data-anchor"));
                }
            }
        }
    };

    /**
     * Constructor
     * @param template       {string} template name
     * @param provider.data  {object} data that populates the template
     * @param provider.url   {string} url of the api
     * @param provider.*     {*}      parameters for the ajax function
     * @param [args.anchor]  {string} id of the anchor (overwrite the one defined on the template script tag)
     */
    Barbe.View = function (template, provider, args) {
        if (template === undefined || Barbe.templates[template] === undefined) {
            throw "[Barbe] template #" + template + " not found.";
        }
        this.template = Barbe.templates[template].render;
        this.anchor = Barbe.templates[template].anchor;
        this.options = {};

        var anchor;

        if (typeof args === "string") {
            anchor = args;
        } else if (typeof args !== "undefined") {
            anchor = args.anchor;
            delete args.anchor;
            this.options = args;
        }

        if (anchor !== undefined) {
            this.anchor = document.getElementById(anchor);
            if (this.anchor === null) {
                throw "[Barbe] anchor #" + anchor + " not found.";
            } else {
                Barbe.templates[template].anchor = this.anchor;
            }
        }

        this.provider = provider || {};
    };

    /**
     * Populate the template with the data. Create a dumb object {array: data} if data is an array
     * @param response {object} data that populates the template
     */
    Barbe.View.prototype.render = function (response) {
        // Mustache doesn't like array as data, so we have to create
        // a dumb object named "array" that contained the array
        if (typeof response === "undefined") {
            response = this.provider.data;
        }
        if (this.provider.url === undefined && this.provider.success !== undefined) {
            response = this.provider.success(response);
        }

        if (Object.prototype.toString.call(response) === '[object Array]') {
            response = {
                array: response
            };
        }

        this.view = this.template(response);
        return this.view;
    };

    /**
     *  Render the template with the response and attach it to the anchor
     *  @params response {object}       api response or data for the template
     *  @params callback {castAnchor}   function called after
     */
    Barbe.View.prototype.castAnchor = function (response, callback) {
        // TODO move this to the render function
        this.loader && this.loader.remove();
        var rendered = this.render(response);
        callback && callback.call(this, rendered);
    };

    /**
     * Process the ajax call
     * @param callback {function} function executed when the ajax call successed and the template has been populated
     */
    Barbe.View.prototype.ajax = function (callback) {
        var that = this;

        var provider = this.provider.success;
        var monkeySuccess = function (response) {
            if (provider !== undefined) {
                response = provider.call(that, response);
            }
            that.castAnchor.call(that, response, callback);
        };

        that.ajaxParams = this.provider;
        that.ajaxParams.success = monkeySuccess;
        Barbe.settings.ajax(that.ajaxParams);
    };

    /**
     * Run Barbe to populate the template and attach it the anchor
     * @param callback {function} function executed when the ajax call successed and the template has been populated
     */
    Barbe.View.prototype.grow = function (callback) {
        if (this.provider.url !== undefined) {
            if (Barbe.settings.loader !== false) {
                this.loader = new Barbe.Loader(this.anchor);
            }
            this.ajax.call(this, callback);
        } else {
            this.castAnchor(this.provider.data, callback);
        }
    };

    /**
     * Constructor:
     * @param anchor {Node} Element where the loader is added
     */
    Barbe.Loader = function (anchor) {
        this.anchor = anchor;
        this.div = document.createElement("div");
        this.div.className = Barbe.settings.loader.className;
        this.div.id = Barbe.settings.loader.id;
        // Clean up the anchor
        while (this.anchor.hasChildNodes()) {
            this.anchor.removeChild(this.anchor.lastChild);
        }
        this.anchor.appendChild(this.div);
    };

    /**
     * Remove the loader from the anchor
     */
    Barbe.Loader.prototype.remove = function () {
        this.anchor.removeChild(this.div);
    };

    window.Barbe = Barbe;

    document.addEventListener('DOMContentLoaded', function () {
        Barbe.grab();
    }, true);

})();
<|endoftext|>


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

const execa = require('execa')
const crypto = require('crypto')

const secureRandom = (length = 10) => crypto.randomBytes(length).toString('hex')

const findContainerId = node => {
  const cmd = `
    docker ps \
      --filter "status=running" \
      --filter "label=com.docker.compose.project=kafkajs" \
      --filter "label=com.docker.compose.service=${node}" \
      --no-trunc \
      -q
  `
  const containerId = execa.shellSync(cmd).stdout.toString('utf-8')
  console.log(`${node}: ${containerId}`)
  return containerId
}

const waitForNode = containerId => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-topics.sh --zookeeper zk:2181 --list 2> /dev/null"
    sleep 5
  `

  execa.shellSync(cmd)
  console.log(`Kafka container ${containerId} is running`)
}

const createTopic = (containerId, topicName) => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-topics.sh --create --if-not-exists --topic ${topicName} --replication-factor 1 --partitions 2 --zookeeper zk:2181 2> /dev/null"
  `

  return execa.shellSync(cmd).stdout.toString('utf-8')
}

const consumerGroupDescribe = containerId => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --new-consumer --group test-group-${secureRandom()} --describe > /dev/null 2>&1"
    sleep 1
  `

  return execa.shellSync(cmd).stdout.toString('utf-8')
}

console.log('\nFinding container ids...')
const kafka1ContainerId = findContainerId('kafka1')
const kafka2ContainerId = findContainerId('kafka2')
const kafka3ContainerId = findContainerId('kafka3')

console.log('\nWaiting for nodes...')
waitForNode(kafka1ContainerId)
waitForNode(kafka2ContainerId)
waitForNode(kafka3ContainerId)

console.log('\nAll nodes up:')
console.log(
  execa.shellSync(`HOST_IP=${process.env.HOST_IP} docker-compose ps`).stdout.toString('utf-8')
)

console.log('\nCreating default topics...')
createTopic(kafka1ContainerId, 'test-topic-already-exists')

console.log('\nWarming up Kafka...')

const totalRandomTopics = 10
console.log(`  -> creating ${totalRandomTopics} random topics...`)
Array(totalRandomTopics)
  .fill()
  .forEach(() => {
    createTopic(kafka1ContainerId, `test-topic-${secureRandom()}`)
  })

console.log('  -> running consumer describe')
consumerGroupDescribe(kafka1ContainerId)
<commit_msg>Fix CI consumer group describe<commit_after>#!/usr/bin/env node

const execa = require('execa')
const crypto = require('crypto')

const secureRandom = (length = 10) => crypto.randomBytes(length).toString('hex')

const findContainerId = node => {
  const cmd = `
    docker ps \
      --filter "status=running" \
      --filter "label=com.docker.compose.project=kafkajs" \
      --filter "label=com.docker.compose.service=${node}" \
      --no-trunc \
      -q
  `
  const containerId = execa.shellSync(cmd).stdout.toString('utf-8')
  console.log(`${node}: ${containerId}`)
  return containerId
}

const waitForNode = containerId => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-topics.sh --zookeeper zk:2181 --list 2> /dev/null"
    sleep 5
  `

  execa.shellSync(cmd)
  console.log(`Kafka container ${containerId} is running`)
}

const createTopic = (containerId, topicName) => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-topics.sh --create --if-not-exists --topic ${topicName} --replication-factor 1 --partitions 2 --zookeeper zk:2181 2> /dev/null"
  `

  return execa.shellSync(cmd).stdout.toString('utf-8')
}

const consumerGroupDescribe = containerId => {
  const cmd = `
    docker exec \
      ${containerId} \
      bash -c "JMX_PORT=9998 /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka1:9092 --group test-group-${secureRandom()} --describe > /dev/null 2>&1"
    sleep 1
  `
  return execa.shellSync(cmd).stdout.toString('utf-8')
}

console.log('\nFinding container ids...')
const kafka1ContainerId = findContainerId('kafka1')
const kafka2ContainerId = findContainerId('kafka2')
const kafka3ContainerId = findContainerId('kafka3')

console.log('\nWaiting for nodes...')
waitForNode(kafka1ContainerId)
waitForNode(kafka2ContainerId)
waitForNode(kafka3ContainerId)

console.log('\nAll nodes up:')
console.log(
  execa.shellSync(`HOST_IP=${process.env.HOST_IP} docker-compose ps`).stdout.toString('utf-8')
)

console.log('\nCreating default topics...')
createTopic(kafka1ContainerId, 'test-topic-already-exists')

console.log('\nWarming up Kafka...')

const totalRandomTopics = 10
console.log(`  -> creating ${totalRandomTopics} random topics...`)
Array(totalRandomTopics)
  .fill()
  .forEach(() => {
    createTopic(kafka1ContainerId, `test-topic-${secureRandom()}`)
  })

console.log('  -> running consumer describe')
consumerGroupDescribe(kafka1ContainerId)
<|endoftext|>


<commit_before>/* eslint-disable func-names */

var yeoman = require('yeoman-generator');
var objectAssign = require('object-assign');

var merge = objectAssign.bind(null, {});
var stringify = function stringify(obj) { return JSON.stringify(obj, null, 2); };
var parse = JSON.parse.bind(JSON);
var concat = function concat(arr1, arr2, arr3) { return [].concat(arr1, arr2, arr3); };
var prefixConfigs = function prefixConfigs(name) { return 'eslint-config-' + name; };
var prefixPlugins = function prefixPlugins(name) { return 'eslint-plugin-' + name; };
var endline = function endline(str) { return str + '\n'; };

module.exports = yeoman.generators.Base.extend({
  constructor: function() {
    yeoman.generators.Base.apply(this, arguments);
    this.argument('configs', { type: Array, required: false,
      desc: endline('Configs list: "yo eslint-init airbnb"'),
    });
    this.argument('plugins', { type: Array, required: false,
      desc: endline('Plugins list: "yo eslint-init -p require-path-exists"'),
    });
  },
  writing: {
    app: function() {
      var config = this.options.config;
      var configs = this.configs || config.configs || [];
      var plugins = this.plugins || config.plugins || [];
      this.devDepsToInstall = concat(
        ['eslint'],
        configs.map(prefixConfigs),
        plugins.map(prefixPlugins)
      );
      this.fs.write(
        this.destinationPath('.eslintrc.json'),
        endline(stringify({
          extends: (configs.length === 1) ? configs[0] : configs,
          plugins: plugins,
        }))
      );
    },
  },
  conflicts: function conflicts() {
    // it’s not "install" because generated project can use "prepublish" script
    // and then babel should already exists in the generated project
    var skipInstall = this.options['skip-install'];
    var needInstall = !skipInstall;
    if (needInstall) {
      this.npmInstall(this.devDepsToInstall, { 'save-dev': true });
    }
  },
});
<commit_msg>implement thing<commit_after>/* eslint-disable func-names */

var yeoman = require('yeoman-generator');
var objectAssign = require('object-assign');

var merge = objectAssign.bind(null, {});
var stringify = function stringify(obj) { return JSON.stringify(obj, null, 2); };
var concat = function concat(arr1, arr2, arr3) { return [].concat(arr1, arr2, arr3); };
var prefix = function prefix(predicate) { return function(item) { return predicate + item; }};
var endline = function endline(str) { return str + '\n'; };
var truncateExtends = function truncateExtends(obj) {
  if (obj.extends && obj.extends.length === 1) {
    obj.extends = obj.extends[0]
  }
  return obj;
};
var maybeStr2arr = function maybeStr2arr(input) {
  if (typeof input === 'boolean') return;
  return typeof input === 'string' ? [input] : input;
}

module.exports = yeoman.generators.Base.extend({
  constructor: function() {
    yeoman.generators.Base.apply(this, arguments);
    this.argument('extends', { type: Array, required: false,
      desc: endline('Extends list: "yo eslint-init airbnb"'),
    });
    this.option('plugins', { type: String, required: false, alias: 'p',
      desc: endline('Plugins list: "yo eslint-init --plugins require-path-exists" or "yo eslint-init -p require-path-exists"'),
    });
  },
  writing: {
    app: function() {
      var cliConfig = {};

      if (this.extends) {
        cliConfig.extends = this.extends;
      }

      var plugins = this.options.plugins || this.options.p;
      if (typeof plugins === 'boolean') {
        this.log('Maybe you forgot double dash: `-plugins` instead of `--plugins`');
      }
      if (plugins) {
        cliConfig.plugins = (typeof plugins === 'string') ? plugins.split(',') : plugins;
      }

      var resultConfig = merge(cliConfig, this.options.config);
      this.fs.write(
        this.destinationPath('.eslintrc.json'),
        endline(stringify(truncateExtends(resultConfig)))
      );
      this.devDepsToInstall = concat(
        ['eslint'],
        (maybeStr2arr(resultConfig.extends) || []).map(prefix('eslint-config-')),
        (maybeStr2arr(resultConfig.plugins) || []).map(prefix('eslint-plugin-'))
      );
    },
  },
  install: function() {
    var skipInstall = this.options['skip-install'];
    var needInstall = !skipInstall;
    if (needInstall) {
      this.npmInstall(this.devDepsToInstall, { 'save-dev': true });
    }
  },
});
<|endoftext|>


<commit_before>/* JenkinsWrapper */

var jenkinsapi = require('jenkins-api'),
lamp = require('./lampsWrapper.js');

var localConfig;
var prevStatus;
var jenkins;

module.exports = {
	name : function() {
		return "jenkinsbuild";
	},
	type : function() {
		return "input";
	},
	init: function (config) {
		localConfig = config;
		console.log("Initialising the %s service", module.exports.name());
                console.log("Watched builds : ", localConfig.watched);
		jenkins = jenkinsapi.init("https://" + config.username + ":" + config.apiKey + "@" + config.url);

		// and call all the input services!
		checkStatus();
	}
}

function checkStatus() {
	console.log("Calling %s", module.exports.name());

	var building = false;

        for (i = 0; i < localConfig.watched.length ; i++) {
            var buildName = localConfig.watched[i];
            console.log("Check for build ",buildName);
            var builds = jenkins.last_build_info(buildName, function(err, data) {

                if (err){
                    console.log(err);
                } else {
                    building |= data.building;

                }
            });
        }

        console.log("Build running :",building);
        updateStatus(building);

        setTimeout(function() {
                checkStatus();
        }, localConfig.interval * 1000);
}

function updateStatus(status) {

    var success = false;

    if(status || prevStatus !== status) {
        if (status) {
            // build started
            console.log("Change build lamp to on");
            success = lamps.change(module.exports.name(), function(lamp) {
                return lamp.yellow(10000).blink();
            });
        } else {
            // build started
            console.log("Change build lamp to off");
            success = lamps.change(module.exports.name(), function(lamp) {
                return lamp.off();
            });
        }
    }
    if (success) {
        prevStatus = status;
    }
}

<commit_msg>] Buh ]<commit_after>/* JenkinsWrapper */

var jenkinsapi = require('jenkins-api'),
lamps = require('./lampsWrapper.js');

var localConfig;
var prevStatus;
var jenkins;

module.exports = {
	name : function() {
		return "jenkinsbuild";
	},
	type : function() {
		return "input";
	},
	init: function (config) {
		localConfig = config;
		console.log("Initialising the %s service", module.exports.name());
                console.log("Watched builds : ", localConfig.watched);
		jenkins = jenkinsapi.init("https://" + config.username + ":" + config.apiKey + "@" + config.url);

		// and call all the input services!
		checkStatus();
	}
}

function checkStatus() {
	console.log("Calling %s", module.exports.name());

	var building = false;

        for (i = 0; i < localConfig.watched.length ; i++) {
            var buildName = localConfig.watched[i];
            console.log("Check for build ",buildName);
            var builds = jenkins.last_build_info(buildName, function(err, data) {

                if (err){
                    console.log(err);
                } else {
                    building |= data.building;

                }
            });
        }

        console.log("Build running :",building);
        updateStatus(building);

        setTimeout(function() {
                checkStatus();
        }, localConfig.interval * 1000);
}

function updateStatus(status) {

    var success = false;

    if(status || prevStatus !== status) {
        if (status) {
            // build started
            console.log("Change build lamp to on");
            success = lamps.change(module.exports.name(), function(lamp) {
                return lamp.yellow(10000).blink();
            });
        } else {
            // build started
            console.log("Change build lamp to off");
            success = lamps.change(module.exports.name(), function(lamp) {
                return lamp.off();
            });
        }
    }
    if (success) {
        prevStatus = status;
    }
}

<|endoftext|>


<commit_before>
var http = require("https"),
    querystring = require("querystring"),
    EventEmitter = require('events').EventEmitter;

var GithubApi = function (state) {
    EventEmitter.call(this);
    this.state = state;
};

GithubApi.prototype = Object.create(EventEmitter.prototype);

GithubApi.findCurrentSprint = function (sprints) {
    var nearest = null;
    sprints.forEach(function (sprint) {
        if(!nearest || new Date(sprint.due_on) < new Date(nearest.due_on)) {
            nearest = sprint;
        }
    });
    return nearest;
};

GithubApi.prototype.getUser = function (cb) {
    return this.load("/user", cb);
};

GithubApi.prototype.listProjects = function (cb) {
    return this.load("/user/repos", cb);
};
GithubApi.prototype.listOrgProjects = function (name, cb) {
    return this.load("/orgs/" + name + "/repos", cb);
};
GithubApi.prototype.getProject = function (name, cb) {
    return this.load("/repos/" + name, cb);
};

GithubApi.prototype.allStories = function (project, cb) {
    return this.load("/repos/" + project + "/issues", cb);
};

GithubApi.prototype.allLabels = function (project, cb) {
    return this.load("/repos/" + project + "/labels", cb);
};

GithubApi.prototype.listSpints = function (project, cb) {
    return this.load("/repos/" + project + "/milestones?state=open", cb);
};

GithubApi.prototype.dashboardStories = function (project, sprint, cb) {
    return this.load("/repos/" + project + "/issues" + (sprint?"?milestone="+sprint:""), cb);
};

GithubApi.prototype.updateStory = function (project, story, data, cb) {
    return this.update("/repos/" + project + "/issues/" + story, data, cb);
};

GithubApi.prototype.createStory = function (project, data, cb) {
    return this.create("/repos/" + project + "/issues", data, cb);
};

GithubApi.prototype.load = function (path, cb) {
    return this.request("GET", path).on("success", cb);
};

GithubApi.prototype.update = function (path, data, cb) {
    return this.request("PATCH", path, JSON.stringify(data)).on("success", cb);
};

GithubApi.prototype.create = function (path, data, cb) {
    return this.request("POST", path, JSON.stringify(data)).on("success", cb);
};

GithubApi.prototype.getToken = function (cb) {
    if(!this.state.code) {
        throw new Error('Not connected');
    }

    return this.request("POST", "/login/oauth/access_token", querystring.stringify({
            code: this.state.code,
            client_id: process.client_id,
            client_secret: process.client_secret
        }), {
            hostname: "github.com"
        }).on("success", cb);
};

GithubApi.prototype.request = function (method, uri, data, options, headers, cb) {
    var request, self = this;

    console.log('-call', method, uri);

    options = options || {};
    options.headers = headers || {};
    options.path = uri;
    options.method = method;

    if (!options.hostname) {
        options.hostname = "api.github.com";
    }
    if (!options.headers.Accept) {
        options.headers.Accept = "application/json";
    }
    if (data) {
        options.headers["Content-Length"] = data.length;
    }
    if (this.state && this.state.token) {
        options.headers.Authorization = "token " + this.state.token;
    }

    request = http.request(options, function(res) {
        var data = "";
        res.on("data", function (buff) {
            data += buff;
        });
        res.on("end", function () {
            if (res.statusCode == 200) {
                self.emit("success", JSON.parse(data));
            } else {
                console.log("error from github", res.statusCode, JSON.parse(data));
                self.emit("error", res.statusCode, JSON.parse(data));
            }
        });

    }).on('error', function(e) {
        self.emit("error", e);
    });
    if (data) {
        request.write(data);
    }
    request.end();
    return this;
};

function requestApi (req, res, next) {
    return new GithubApi(req.session.state).on("error", function (code, message) {
        next(err);
    });
}

/* binding */
GithubApi.requestApi = requestApi;
module.exports = GithubApi;
<commit_msg>fix error on github exception<commit_after>
var http = require("https"),
    querystring = require("querystring"),
    EventEmitter = require('events').EventEmitter;

var GithubApi = function (state) {
    EventEmitter.call(this);
    this.state = state;
};

GithubApi.prototype = Object.create(EventEmitter.prototype);

GithubApi.findCurrentSprint = function (sprints) {
    var nearest = null;
    sprints.forEach(function (sprint) {
        if(!nearest || new Date(sprint.due_on) < new Date(nearest.due_on)) {
            nearest = sprint;
        }
    });
    return nearest;
};

GithubApi.prototype.getUser = function (cb) {
    return this.load("/user", cb);
};

GithubApi.prototype.listProjects = function (cb) {
    return this.load("/user/repos", cb);
};
GithubApi.prototype.listOrgProjects = function (name, cb) {
    return this.load("/orgs/" + name + "/repos", cb);
};
GithubApi.prototype.getProject = function (name, cb) {
    return this.load("/repos/" + name, cb);
};

GithubApi.prototype.allStories = function (project, cb) {
    return this.load("/repos/" + project + "/issues", cb);
};

GithubApi.prototype.allLabels = function (project, cb) {
    return this.load("/repos/" + project + "/labels", cb);
};

GithubApi.prototype.listSpints = function (project, cb) {
    return this.load("/repos/" + project + "/milestones?state=open", cb);
};

GithubApi.prototype.dashboardStories = function (project, sprint, cb) {
    return this.load("/repos/" + project + "/issues" + (sprint?"?milestone="+sprint:""), cb);
};

GithubApi.prototype.updateStory = function (project, story, data, cb) {
    return this.update("/repos/" + project + "/issues/" + story, data, cb);
};

GithubApi.prototype.createStory = function (project, data, cb) {
    return this.create("/repos/" + project + "/issues", data, cb);
};

GithubApi.prototype.load = function (path, cb) {
    return this.request("GET", path).on("success", cb);
};

GithubApi.prototype.update = function (path, data, cb) {
    return this.request("PATCH", path, JSON.stringify(data)).on("success", cb);
};

GithubApi.prototype.create = function (path, data, cb) {
    return this.request("POST", path, JSON.stringify(data)).on("success", cb);
};

GithubApi.prototype.getToken = function (cb) {
    if(!this.state.code) {
        throw new Error('Not connected');
    }

    return this.request("POST", "/login/oauth/access_token", querystring.stringify({
            code: this.state.code,
            client_id: process.client_id,
            client_secret: process.client_secret
        }), {
            hostname: "github.com"
        }).on("success", cb);
};

GithubApi.prototype.request = function (method, uri, data, options, headers, cb) {
    var request, self = this;

    console.log('-call', method, uri);

    options = options || {};
    options.headers = headers || {};
    options.path = uri;
    options.method = method;

    if (!options.hostname) {
        options.hostname = "api.github.com";
    }
    if (!options.headers.Accept) {
        options.headers.Accept = "application/json";
    }
    if (data) {
        options.headers["Content-Length"] = data.length;
    }
    if (this.state && this.state.token) {
        options.headers.Authorization = "token " + this.state.token;
    }

    request = http.request(options, function(res) {
        var data = "";
        res.on("data", function (buff) {
            data += buff;
        });
        res.on("end", function () {
            if (res.statusCode == 200) {
                self.emit("success", JSON.parse(data));
            } else {
                console.log("error from github", res.statusCode, JSON.parse(data));
                self.emit("error", res.statusCode, JSON.parse(data));
            }
        });

    }).on('error', function(e) {
        self.emit("error", e);
    });
    if (data) {
        request.write(data);
    }
    request.end();
    return this;
};

function requestApi (req, res, next) {
    return new GithubApi(req.session.state).on("error", function (code, message) {
         res.json(code, message);
    });
}

/* binding */
GithubApi.requestApi = requestApi;
module.exports = GithubApi;
<|endoftext|>


<commit_before>var _ = require('lib/underscore')._;
var Answer = require('models/answer');

var Response = new Ti.App.joli.model({
	table : 'responses',
	columns : {
		id : 'INTEGER PRIMARY KEY',
		survey_id : 'INTEGER',
		web_id : 'INTEGER',
		status : 'TEXT'
	},

	methods : {
		createRecord : function(surveyID, status, answersData) {
			var record = this.newRecord({
				survey_id : surveyID,
				status : status
			});
			record.save();
			_(answersData).each(function(answer) {
				Answer.createRecord(answer, record.id);
			});
			Ti.API.info("Resp ID is " + record.id);
			return true;
		},

		validate : function(answersData, status) {
			var errors = {};
			_(answersData).each(function(answerData) {
				var answerErrors = Answer.validate(answerData, status);
				if (!_.isEmpty(answerErrors)) {
					errors[answerData.question_id] = answerErrors;
				}
			});
			return errors;
		}
	},
	objectMethods : {
		prepRailsParams : function() {
			var answers = Answer.findBy('response_id', this.id);
			var answer_attributes = {}
			_(answers).each(function(answer, index) {
				answer_attributes[index] = {};
				answer_attributes[index]['question_id'] = answer.question_id;
				if (answer.hasChoices())
					answer_attributes[index]['option_ids'] = answer.optionIDs();
				else
					answer_attributes[index]['content'] = answer.content;
			});
			return answer_attributes;
		},

		sync : function() {
			var url = Ti.App.Properties.getString('server_url') + '/api/responses';
			var self = this;
			this.synced = false;
			var params = {};
			if (self.web_id)
				params['id'] = self.web_id;
			params['answers_attributes'] = this.prepRailsParams();
			params['status'] = this.status;
			params['survey_id'] = this.survey_id;
			var client = Ti.Network.createHTTPClient({
				// function called when the response data is available
				onload : function(e) {
					Ti.API.info("Synced response successfully: " + this.responseText);
					self.has_error = false;
					self.synced = true;
					Ti.App.fireEvent('response.sync', {
						survey_id : self.survey_id
					});
					if (self.status == "complete") {
						var answers = self.answers();
						_(answers).each(function(answer) {
							answer.destroy();
						});
						self.destroy();
					} else {
						var received_response = JSON.parse(this.responseText);
						self.fromArray({
							'id' : self.id,
							'survey_id' : self.survey_id,
							'web_id' : received_response['id'],
							'status' : received_response['status'],
						});
						// self.web_id = received_response['id'];
						// self.status = received_response['status'];
						Ti.API.info("before save WEB ID: " + self.web_id);
						self.save()
						Ti.API.info("after save WEB ID: " + self.web_id);
					}
				},
				// function called when an error occurs, including a timeout
				onerror : function(e) {
					Ti.API.info("Erroneous Response: " + this.responseText);
					self.has_error = true;
					self.synced = true;
					Ti.App.fireEvent('response.sync', {
						survey_id : self.survey_id
					});
				},
				timeout : 5000 // in milliseconds
			});

			var method = self.web_id ? "PUT" : "POST";
			url += self.web_id ? "/" + self.web_id : "";
			url += ".json";
			Ti.API.info("method: " + method);
			client.open(method, url);
			client.setRequestHeader("Content-Type", "application/json");
			client.send(JSON.stringify(params));
		},

		answers : function() {
			return Answer.findBy('response_id', this.id)
		}
	}
});

Ti.App.joli.models.initialize();
module.exports = Response;

<commit_msg>Removed id from params in put request to responses update<commit_after>var _ = require('lib/underscore')._;
var Answer = require('models/answer');

var Response = new Ti.App.joli.model({
	table : 'responses',
	columns : {
		id : 'INTEGER PRIMARY KEY',
		survey_id : 'INTEGER',
		web_id : 'INTEGER',
		status : 'TEXT'
	},

	methods : {
		createRecord : function(surveyID, status, answersData) {
			var record = this.newRecord({
				survey_id : surveyID,
				status : status
			});
			record.save();
			_(answersData).each(function(answer) {
				Answer.createRecord(answer, record.id);
			});
			Ti.API.info("Resp ID is " + record.id);
			return true;
		},

		validate : function(answersData, status) {
			var errors = {};
			_(answersData).each(function(answerData) {
				var answerErrors = Answer.validate(answerData, status);
				if (!_.isEmpty(answerErrors)) {
					errors[answerData.question_id] = answerErrors;
				}
			});
			return errors;
		}
	},
	objectMethods : {
		prepRailsParams : function() {
			var answers = Answer.findBy('response_id', this.id);
			var answer_attributes = {}
			_(answers).each(function(answer, index) {
				answer_attributes[index] = {};
				answer_attributes[index]['question_id'] = answer.question_id;
				if (answer.hasChoices())
					answer_attributes[index]['option_ids'] = answer.optionIDs();
				else
					answer_attributes[index]['content'] = answer.content;
			});
			return answer_attributes;
		},

		sync : function() {
			var url = Ti.App.Properties.getString('server_url') + '/api/responses';
			var self = this;
			this.synced = false;
			var params = {};
			params['answers_attributes'] = this.prepRailsParams();
			params['status'] = this.status;
			params['survey_id'] = this.survey_id;
			var client = Ti.Network.createHTTPClient({
				// function called when the response data is available
				onload : function(e) {
					Ti.API.info("Synced response successfully: " + this.responseText);
					self.has_error = false;
					self.synced = true;
					Ti.App.fireEvent('response.sync', {
						survey_id : self.survey_id
					});
					if (self.status == "complete") {
						var answers = self.answers();
						_(answers).each(function(answer) {
							answer.destroy();
						});
						self.destroy();
					} else {
						var received_response = JSON.parse(this.responseText);
						self.fromArray({
							'id' : self.id,
							'survey_id' : self.survey_id,
							'web_id' : received_response['id'],
							'status' : received_response['status'],
						});
						// self.web_id = received_response['id'];
						// self.status = received_response['status'];
						Ti.API.info("before save WEB ID: " + self.web_id);
						self.save()
						Ti.API.info("after save WEB ID: " + self.web_id);
					}
				},
				// function called when an error occurs, including a timeout
				onerror : function(e) {
					Ti.API.info("Erroneous Response: " + this.responseText);
					self.has_error = true;
					self.synced = true;
					Ti.App.fireEvent('response.sync', {
						survey_id : self.survey_id
					});
				},
				timeout : 5000 // in milliseconds
			});

			var method = self.web_id ? "PUT" : "POST";
			url += self.web_id ? "/" + self.web_id : "";
			url += ".json";
			Ti.API.info("method: " + method);
			client.open(method, url);
			client.setRequestHeader("Content-Type", "application/json");
			client.send(JSON.stringify(params));
		},

		answers : function() {
			return Answer.findBy('response_id', this.id)
		}
	}
});

Ti.App.joli.models.initialize();
module.exports = Response;

<|endoftext|>


<commit_before>// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

var render = (index) => document.write(
  '
' + index + '
'
)
var renderList = (index) => {
  document.write('
PC

')
  for (var i = 0; i < 10; i++) {
    render((index * 10) + i);
  }
  document.write('
')
}
for (var i = 0; i < 10; i++) {
  renderList(i)
}

$(document).keydown(function (e) {
  var $current = $(":focus");
  if (e.which === 37) {
    $current.prev().focus();
  } else if (e.which === 39) {
    $current.next().focus();
  }
  // var index = $(":focus").index() + 1;
  // console.log(index);
  // if (e.which === 37) {
  //   $('div :nth-child(' + (index - 1) + ')').focus();
  // } else if (e.which === 39) {
  //   $('div :nth-child(' + (index + 1) + ')').focus();
  // }
});<commit_msg>Vertical nav prototype<commit_after>// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

var render = (index) => document.write(
  '
' + index + '
'
)
var renderList = (index) => {
  document.write('
PC

')
  for (var i = 0; i < 20; i++) {
    render((index * 20) + i);
  }
  document.write('
')
}
for (var i = 0; i < 10; i++) {
  renderList(i)
}

$(document).keydown(function (e) {
  var $current = $(":focus");
  switch (e.which) {
    case 37:
      $current.prev().focus();
      break;
    case 38:
      $current.parent().prev().prev().children().first().focus();
      break;
    case 39:
      $current.next().focus();
      break;
    case 40:
      $current.parent().next().next().children().first().focus();
      break;
    default:
      break;
  }
  // var index = $(":focus").index() + 1;
  // console.log(index);
  // if (e.which === 37) {
  //   $('div :nth-child(' + (index - 1) + ')').focus();
  // } else if (e.which === 39) {
  //   $('div :nth-child(' + (index + 1) + ')').focus();
  // }
});<|endoftext|>


<commit_before>var React = require('react');
var ObjectLoader = require('../components/ObjectLoader.react');
var CollectionLoader = require('../components/CollectionLoader.react');
var Collection = require('../components/Collection.react');
var ObjectTest = require('../components/Object.react');

var exampleConfig = {
  name: "Parents",
  idAttr: "id",
  basePath: "http://localhost:8083/api/",
  endpoint: "sample",
  storeType: "unique"
};

var BasicLoaderExamples = React.createClass({
  render() {
    return (

CollectionLoader

        <CollectionLoader {...exampleConfig}>
          <Collection handleSelect={this.props.handleSelect}/>
        </CollectionLoader>

ObjectLoader

        <ObjectLoader {...exampleConfig}
          objectId={this.props.objectId}>
          <ObjectTest/>
        </ObjectLoader>

    );
  }
});

module.exports = BasicLoaderExamples;
<commit_msg>Switched back shared<commit_after>var React = require('react');
var ObjectLoader = require('../components/ObjectLoader.react');
var CollectionLoader = require('../components/CollectionLoader.react');
var Collection = require('../components/Collection.react');
var ObjectTest = require('../components/Object.react');

var exampleConfig = {
  name: "Parents",
  idAttr: "id",
  basePath: "http://localhost:8083/api/",
  endpoint: "sample",
  storeType: "shared"
};

var BasicLoaderExamples = React.createClass({
  render() {
    return (

CollectionLoader

        <CollectionLoader {...exampleConfig}>
          <Collection handleSelect={this.props.handleSelect}/>
        </CollectionLoader>

ObjectLoader

        <ObjectLoader {...exampleConfig}
          objectId={this.props.objectId}>
          <ObjectTest/>
        </ObjectLoader>

    );
  }
});

module.exports = BasicLoaderExamples;
<|endoftext|>


<commit_before>Elm.Native.Keyboard = {};
Elm.Native.Keyboard.make = function(elm) {

    elm.Native = elm.Native || {};
    elm.Native.Keyboard = elm.Native.Keyboard || {};
    if (elm.Native.Keyboard.values) return elm.Native.Keyboard.values;

    // Duplicated from Native.Signal
    function send(node, timestep, changed) {
        var kids = node.kids;
        for (var i = kids.length; i--; ) {
            kids[i].recv(timestep, changed, node.id);
        }
    }

    var Signal = Elm.Signal.make(elm);
    var NList = Elm.Native.List.make(elm);
    var Utils = Elm.Native.Utils.make(elm);

    var downEvents = Signal.constant(null);
    var upEvents = Signal.constant(null);
    var blurEvents = Signal.constant(null);

    elm.addListener([downEvents.id], document, 'keydown', function down(e) {
        elm.notify(downEvents.id, e);
    });

    elm.addListener([upEvents.id], document, 'keyup', function up(e) {
        elm.notify(upEvents.id, e);
    });

    elm.addListener([blurEvents.id], window, 'blur', function blur(e) {
        elm.notify(blurEvents.id, null);
    });

    function state(alt, meta, keyCodes) {
        return {
            alt: alt,
            meta: meta,
            keyCodes: keyCodes
        };
    }
    var emptyState = state(false, false, NList.Nil);

    function KeyMerge(down, up, blur) {
        var args = [down,up,blur];
        this.id = Utils.guid();
        // Ignore starting values here
        this.value = emptyState;
        this.kids = [];

        var n = args.length;
        var count = 0;
        var isChanged = false;

        this.recv = function(timestep, changed, parentID) {
            ++count;
            if (changed) {
                // We know this a change must only be one of the following cases
                if (parentID === down.id && !A2(NList.member, down.value.keyCode, this.value.keyCodes)) {
                    isChanged = true;
                    var v = down.value;
                    var newCodes = NList.Cons(v.keyCode, this.value.keyCodes);
                    this.value = state(v.altKey, v.metaKey, newCodes);
                }
                else if (parentID === up.id) {
                    isChanged = true;
                    var v = up.value;
                    var notEq = function(kc) { return kc !== v.keyCode };
                    var newCodes = A2(NList.keepIf, notEq, this.value.keyCodes);
                    this.value = state(v.altKey, v.metaKey, newCodes);
                }
                else if (parentID === blur.id) {
                    isChanged = true;
                    this.value = emptyState;
                }
            }
            if (count == n) {
                send(this, timestep, isChanged);
                isChanged = false;
                count = 0;
            }
        };

        for (var i = n; i--; ) {
            args[i].kids.push(this);
            args[i].defaultNumberOfKids += 1;
        }
    }

    var keyMerge = new KeyMerge(downEvents,upEvents,blurEvents);

    // select a part of a keyMerge and dropRepeats the result
    function keySignal(f) {
        var signal = A2(Signal.map, f, keyMerge);
        // must set the default number of kids to make it possible to filter
        // these signals if they are not actually used.
        keyMerge.defaultNumberOfKids += 1;
        signal.defaultNumberOfKids = 1;
        var filtered = Signal.dropRepeats(signal);
        filtered.defaultNumberOfKids = 0;
        return filtered;
    }

    // break keyMerge into parts
    var keysDown = keySignal(function getKeyCodes(v) {
        return v.keyCodes;
    });
    var alt = keySignal(function getKeyCodes(v) {
        return v.alt;
    });
    var meta = keySignal(function getKeyCodes(v) {
        return v.meta;
    });

    function dir(up, down, left, right) {
        function toDirections(state) {
            var keyCodes = state.keyCodes;
            var x = 0, y = 0;
            while (keyCodes.ctor === "::") {
                switch (keyCodes._0) {
                case left : --x; break;
                case right: ++x; break;
                case up   : ++y; break;
                case down : --y; break;
                }
                keyCodes = keyCodes._1;
            }
            return { _:{}, x:x, y:y };
        }
        return keySignal(toDirections);
    }

    function is(key) {
        return keySignal(function(v) {
            return A2( NList.member, key, v.keyCodes );
        });
    }

    var lastPressed = A2(Signal.map, function(e) {
        return e ? e.keyCode : 0;
    }, downEvents);
    downEvents.defaultNumberOfKids += 1;

    return elm.Native.Keyboard.values = {
        isDown:is,
        alt: alt,
        meta: meta,
        directions:F4(dir),
        keysDown:keysDown,
        lastPressed:lastPressed
    };

};
<commit_msg>elm -> localRuntime in Keyboard.js<commit_after>Elm.Native.Keyboard = {};
Elm.Native.Keyboard.make = function(localRuntime) {

    localRuntime.Native = localRuntime.Native || {};
    localRuntime.Native.Keyboard = localRuntime.Native.Keyboard || {};
    if (localRuntime.Native.Keyboard.values)
    {
        return localRuntime.Native.Keyboard.values;
    }

    // Duplicated from Native.Signal
    function send(node, timestep, changed) {
        var kids = node.kids;
        for (var i = kids.length; i--; ) {
            kids[i].recv(timestep, changed, node.id);
        }
    }

    var Signal = Elm.Signal.make(localRuntime);
    var NList = Elm.Native.List.make(localRuntime);
    var Utils = Elm.Native.Utils.make(localRuntime);

    var downEvents = Signal.constant(null);
    var upEvents = Signal.constant(null);
    var blurEvents = Signal.constant(null);

    localRuntime.addListener([downEvents.id], document, 'keydown', function down(e) {
        localRuntime.notify(downEvents.id, e);
    });

    localRuntime.addListener([upEvents.id], document, 'keyup', function up(e) {
        localRuntime.notify(upEvents.id, e);
    });

    localRuntime.addListener([blurEvents.id], window, 'blur', function blur(e) {
        localRuntime.notify(blurEvents.id, null);
    });

    function state(alt, meta, keyCodes) {
        return {
            alt: alt,
            meta: meta,
            keyCodes: keyCodes
        };
    }
    var emptyState = state(false, false, NList.Nil);

    function KeyMerge(down, up, blur) {
        var args = [down,up,blur];
        this.id = Utils.guid();
        // Ignore starting values here
        this.value = emptyState;
        this.kids = [];

        var n = args.length;
        var count = 0;
        var isChanged = false;

        this.recv = function(timestep, changed, parentID) {
            ++count;
            if (changed)
            {
                // We know this a change must only be one of the following cases
                if (parentID === down.id && !A2(NList.member, down.value.keyCode, this.value.keyCodes))
                {
                    isChanged = true;
                    var v = down.value;
                    var newCodes = NList.Cons(v.keyCode, this.value.keyCodes);
                    this.value = state(v.altKey, v.metaKey, newCodes);
                }
                else if (parentID === up.id)
                {
                    isChanged = true;
                    var v = up.value;
                    var notEq = function(kc) { return kc !== v.keyCode };
                    var newCodes = A2(NList.keepIf, notEq, this.value.keyCodes);
                    this.value = state(v.altKey, v.metaKey, newCodes);
                }
                else if (parentID === blur.id)
                {
                    isChanged = true;
                    this.value = emptyState;
                }
            }
            if (count == n)
            {
                send(this, timestep, isChanged);
                isChanged = false;
                count = 0;
            }
        };

        for (var i = n; i--; ) {
            args[i].kids.push(this);
            args[i].defaultNumberOfKids += 1;
        }
    }

    var keyMerge = new KeyMerge(downEvents,upEvents,blurEvents);

    // select a part of a keyMerge and dropRepeats the result
    function keySignal(f) {
        var signal = A2(Signal.map, f, keyMerge);
        // must set the default number of kids to make it possible to filter
        // these signals if they are not actually used.
        keyMerge.defaultNumberOfKids += 1;
        signal.defaultNumberOfKids = 1;
        var filtered = Signal.dropRepeats(signal);
        filtered.defaultNumberOfKids = 0;
        return filtered;
    }

    // break keyMerge into parts
    var keysDown = keySignal(function getKeyCodes(v) {
        return v.keyCodes;
    });
    var alt = keySignal(function getKeyCodes(v) {
        return v.alt;
    });
    var meta = keySignal(function getKeyCodes(v) {
        return v.meta;
    });

    function dir(up, down, left, right) {
        function toDirections(state) {
            var keyCodes = state.keyCodes;
            var x = 0, y = 0;
            while (keyCodes.ctor === "::") {
                switch (keyCodes._0) {
                case left : --x; break;
                case right: ++x; break;
                case up   : ++y; break;
                case down : --y; break;
                }
                keyCodes = keyCodes._1;
            }
            return { _:{}, x:x, y:y };
        }
        return keySignal(toDirections);
    }

    function is(key) {
        return keySignal(function(v) {
            return A2( NList.member, key, v.keyCodes );
        });
    }

    var lastPressed = A2(Signal.map, function(e) {
        return e ? e.keyCode : 0;
    }, downEvents);
    downEvents.defaultNumberOfKids += 1;

    return localRuntime.Native.Keyboard.values = {
        isDown:is,
        alt: alt,
        meta: meta,
        directions:F4(dir),
        keysDown:keysDown,
        lastPressed:lastPressed
    };

};
<|endoftext|>


<commit_before>'use strict';

/**
* ESLint rules for variable declarations.
*
* @namespace rules
*/
var rules = {};

/**
* Allow variables to be initialized either during declaration or otherwise.
*
* @name init-declarations
* @memberof rules
* @type {number}
* @default 0
* @see [init-declarations]{@link http://eslint.org/docs/rules/init-declarations}
*/
rules[ 'init-declarations' ] = 0;

/**
* Address IE8 bug in which the `catch` clause can overwrite a variable in the outer scope.
*
* @name no-catch-shadow
* @memberof rules
* @type {number}
* @default 2
* @see [no-catch-shadow]{@link http://eslint.org/docs/rules/no-catch-shadow}
*/
rules[ 'no-catch-shadow' ] = 2;

/**
* Never allow variables to be deleted; only properties.
*
* @name no-delete-var
* @memberof rules
* @type {number}
* @default 2
* @see [no-delete-var]{@link http://eslint.org/docs/rules/no-delete-var}
*/
rules[ 'no-delete-var' ] = 2;

/**
* Never allow a label to share a name with a variable.
*
* @name no-label-var
* @memberof no-label-var
* @type {number}
* @default 2
* @see [no-label-var]{@link http://eslint.org/docs/rules/no-label-var}
*/
rules[ 'no-label-var' ] = 2;

/**
* Never allow reassignment of restricted names.
*
* @name no-shadow-restricted-names
* @memberof rules
* @type {number}
* @default 2
* @see {@link http://eslint.org/docs/rules/no-shadow-restricted-names}
*/
rules[ 'no-shadow-restricted-names' ] = 2;

/**
* Allow shadowing of variable names in a local scope.
*
* @name no-shadow
* @memberof rules
* @type {number}
* @default 0
* @see [no-shadow]{@link http://eslint.org/docs/rules/no-shadow}
*/
rules[ 'no-shadow' ] = 0;

/**
* Never allow a variable to be initialized as `undefined`.
*
* @name no-undef-init
* @memberof rules
* @type {number}
* @default 2
* @see [no-undef-init]{@link http://eslint.org/docs/rules/no-undef-init}
*/
rules[ 'no-undef-init' ] = 2;

/**
* Never allow undeclared variables.
*
* @name no-undef
* @memberof rules
* @type {number}
* @default 2
* @see [no-undef]{@link http://eslint.org/docs/rules/no-undef}
*/
rules[ 'no-undef' ] = 2;

/**
* Never allow the use of `undefined`.
*
* @name no-undefined
* @memberof rules
* @type {number}
* @default 2
* @see [no-undefined]{@link http://eslint.org/docs/rules/no-undefined}
*/
rules[ 'no-undefined' ] = 2;

/**
* Never allow unused variables, except for function arguments preceding a used argument.
*
* @name no-unused-vars
* @memberof rules
* @type {number}
* @see [no-unused-vars]{@link http://eslint.org/docs/rules/no-unused-vars}
*/
rules[ 'no-unused-vars' ] = [ 2, {
	'vars': 'all',
	'args': 'after-used'
}];

/**
* Never allow a variable to be used before being declared (except for function declarations).
*
* @name no-use-before-define
* @memberof rules
* @type {Array}
* @default [ 2, 'nofunc' ]
* @see [no-use-before-define]{@link http://eslint.org/docs/rules/no-use-before-define}
*/
rules[ 'no-use-before-define' ] = [ 2, 'nofunc' ];

// EXPORTS //

module.exports = rules;
<commit_msg>Update rules for variable declarations<commit_after>'use strict';

/**
* ESLint rules for variable declarations.
*
* @namespace rules
*/
var rules = {};

/**
* Allow variables to be initialized either during declaration or otherwise.
*
* @name init-declarations
* @memberof rules
* @type {string}
* @default 'off'
* @see [init-declarations]{@link http://eslint.org/docs/rules/init-declarations}
*
* @example
* // Okay...
* var x;
* var y;
*
* x = 5;
* y = 10;
*
* @example
* // Okay...
* var y = 10;
* var x = 5;
*/
rules[ 'init-declarations' ] = 'off';

/**
* Address IE8 bug in which the `catch` clause can overwrite a variable in the outer scope.
*
* @name no-catch-shadow
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-catch-shadow]{@link http://eslint.org/docs/rules/no-catch-shadow}
*
* @example
* // Bad...
* var err = 'x';
* try {
*     throw new Error( 'beep' );
* } catch( err ) {
*     // Do something...
* }
*
* @example
* // Good...
* var err = 'x';
* try {
*     throw new Error( 'beep' );
* } catch( error ) {
*     // Do something...
* }
*/
rules[ 'no-catch-shadow' ] = 'error';

/**
* Never allow variables to be deleted; only properties.
*
* @name no-delete-var
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-delete-var]{@link http://eslint.org/docs/rules/no-delete-var}
*
* @example
* // Bad...
* var x = 5;
* delete x;
*/
rules[ 'no-delete-var' ] = 'error';

/**
* Never allow a label to share a name with a variable.
*
* @name no-label-var
* @memberof no-label-var
* @type {string}
* @default 'error'
* @see [no-label-var]{@link http://eslint.org/docs/rules/no-label-var}
*
* @example
* // Bad...
* var x = 'beep';
* x: while( true ) {
*     break x;
* }
*
* @example
* // Okay...
* var x = 'beep';
* y : while( true ) {
*     break y;
* }
*/
rules[ 'no-label-var' ] = 'error';

/**
* Never allow usage of specific global variable names.
*
* @name no-restricted-globals
* @memberof rules
* @type {Array}
* @see [no-restricted-globals]{@link http://eslint.org/docs/rules/no-restricted-globals}
*/
rules[ 'no-restricted-globals' ] = [ 'error', 'event', 'fdescribe' ];

/**
* Never allow reassignment of restricted names.
*
* @name no-shadow-restricted-names
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-shadow-restricted-names]{@link http://eslint.org/docs/rules/no-shadow-restricted-names}
*
* @example
* // Bad...
* function NaN(){}
*/
rules[ 'no-shadow-restricted-names' ] = 'error';

/**
* Allow shadowing of variable names in a local scope.
*
* @name no-shadow
* @memberof rules
* @type {string}
* @default 'off'
* @see [no-shadow]{@link http://eslint.org/docs/rules/no-shadow}
*
* @example
* // Okay...
* var x = 'beep';
* function foo() {
*     var x = 'boop';
* }
*/
rules[ 'no-shadow' ] = 'off';

/**
* Never allow a variable to be initialized as `undefined`.
*
* @name no-undef-init
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-undef-init]{@link http://eslint.org/docs/rules/no-undef-init}
*
* @example
* // Bad...
* var x = undefined;
*
* @example
* // Good...
* var x;
*/
rules[ 'no-undef-init' ] = 'error';

/**
* Never allow undeclared variables.
*
* @name no-undef
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-undef]{@link http://eslint.org/docs/rules/no-undef}
*
* @example
* // Bad...
* x = 5;
*
* @example
* // Good...
* var x = 5;
*/
rules[ 'no-undef' ] = 'error';

/**
* Never allow the use of `undefined`.
*
* @name no-undefined
* @memberof rules
* @type {string}
* @default 'error'
* @see [no-undefined]{@link http://eslint.org/docs/rules/no-undefined}
*
* @example
* // Bad...
* var x = undefined;
*
* @example
* // Bad...
* var undefined = 'beep';
*
* @example
* // Good...
* var x;
*
* @example
* // Good...
* var undef = 'beep';
*/
rules[ 'no-undefined' ] = 'error';

/**
* Never allow unused variables, except for function arguments preceding a used argument.
*
* @name no-unused-vars
* @memberof rules
* @type {Array}
* @see [no-unused-vars]{@link http://eslint.org/docs/rules/no-unused-vars}
*
* @example
* // Bad...
* var unused = 5;
*
* @example
* // Bad...
* function foo( a, b, c ) {
*     return 5;
* }
*
* @example
* // Good...
* function foo( a, b, c ) {
*     return c;
* }
*/
rules[ 'no-unused-vars' ] = [ 'error', {
	'vars': 'all',
	'args': 'after-used',
	'caughtErrors': 'all'
}];

/**
* Never allow a variable to be used before being declared (except for function declarations).
*
* @name no-use-before-define
* @memberof rules
* @type {Array}
* @see [no-use-before-define]{@link http://eslint.org/docs/rules/no-use-before-define}
*
* @example
* // Bad...
* x = 5;
* var x;
*
* @example
* // Good...
* var x;
* x = 5;
*
* @example
* // Okay...
* function bar() {
*     return foo();
*     function foo(){}
* }
*/
rules[ 'no-use-before-define' ] = [ 'error', {
	'functions': false,
	'classes': true
}];

// EXPORTS //

module.exports = rules;
<|endoftext|>


<commit_before>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var path  = require('path');

var Packages = {
  main:  [
    'alt',
    'classnames',
    'debug',
    'es6-shim',
    'react',
    'react-router',
    'whatwg-fetch'
  ],
  dev: [
    'autoprefixer-loader',
    'babel-core',
    'babel-loader',
    'css-loader',
    'file-loader',
    'html-webpack-plugin',
    'node-libs-browser',
    'react-hot-loader',
    'style-loader',
    'webpack',
    'webpack-dev-server'
  ]
};

module.exports = yeoman.generators.Base.extend({

  askForApp: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'React.js' + chalk.red(' ❤ ') + ' Alt  '
    ));
    this.log(chalk.magenta(
      'Out of the box I include React.js, react-router, Alt, all backed by webpack to build your app.'
    ));

    var root = this.destinationPath();

    var prompts = [{
      name: 'app',
      message: 'What\'s the name of the app?',
      default: path.basename(root)
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;
      this.app = props.app;
      done();
    }.bind(this));
  },

  askForLicense: function() {
    var done = this.async();

    var prompts = [{
      type: 'list',
      name: 'license',
      message: 'Which license you\'d like to use?',
      choices: [{
        name: 'Apache License 2.0',
        value: 'Apache-2.0'
      }, {
        name: 'BSD 2-clause "Simplified" License',
        value: 'BSD-2-Clause'
      }, {
        name: 'Eclipse Public License 1.0',
        value: 'EPL-1.0'
      }, {
        name: 'GNU General Public License v3.0',
        value: 'GPL-3.0'
      }, {
        name: 'GNU Lesser General Public License v3.0',
        valeu: 'LGPL-3.0'
      }, {
        name: 'MIT License',
        value: 'MIT'
      }, {
        name: 'Mozilla Public License 2.0',
        value: 'MPL-2.0'
      }],
      default: 0
    }];

    this.prompt(prompts, function (answers) {
      this.license = answers.license;
      done();
    }.bind(this));

  },

  askForPreprocessor: function () {
    var done = this.async();

    var prompts = [{
      type: 'list',
      name: 'preprocessor',
      message: 'How\'d you like to pre-process stylesheets?',
      choices: [{
        name: 'Sass',
        value: 'sass'
      }, {
        name: 'Less',
        value: 'less'
      }],
      default: 0
    }];

    this.prompt(prompts, function (answers) {
      var preprocessor = answers.preprocessor;

      function use(item) {
        return preprocessor && preprocessor.indexOf(item) !== -1;
      }

      // pre-processor for style sheets.
      if (use('less')) {
        this.preprocessor = { name: 'less', ext: '/\.less$/' };
      } else {
        this.preprocessor = { name: 'sass', ext: '/\.scss$/' };
      }

      done();
    }.bind(this));
  },

  installApp: function() {
    this.fs.copy(
      this.templatePath('index.html'),
      this.destinationPath('index.html')
    );
    this.fs.copy(
      this.templatePath(path.join('scripts', 'shared')),
      this.destinationPath(path.join('scripts', 'shared'))
    );
    this.fs.copy(
      this.templatePath(path.join('scripts', 'views')),
      this.destinationPath(path.join('scripts', 'views'))
    );
    this.fs.copyTpl(
      this.templatePath(path.join('scripts', 'bootstrap.jsx')),
      this.destinationPath(path.join('scripts', 'bootstrap.jsx')),
      { preprocessor: this.preprocessor.name }
    );
  },

  installAssets: function() {
    this.fs.copy(
      this.templatePath(path.join('assets', 'favicon.ico')),
      this.destinationPath(path.join('assets', 'favicon.ico'))
    );
    this.fs.copy(
      this.templatePath(path.join('assets', 'app.' + this.preprocessor.name)),
      this.destinationPath(path.join('assets', 'app.' + this.preprocessor.name))
    );
  },

  finalize: function() {
    this.fs.copyTpl(
      this.templatePath('webpack.config.js'),
      this.destinationPath('webpack.config.js'),
      { preprocessor: this.preprocessor }
    );

    this.fs.copyTpl(
      this.templatePath('package.json'),
      this.destinationPath('package.json'),
      {
        app: this.app,
        license: this.license
      }
    );

    this.fs.copy(
      this.templatePath('editorconfig'),
      this.destinationPath('.editorconfig')
    );
  },

  install: function () {
    if (this.preprocessor.name === 'less') {
      Packages.dev.push('less');
      Packages.dev.push('less-loader');
    } else {
      Packages.dev.push('node-sass');
      Packages.dev.push('sass-loader');
    }

    this.npmInstall(Packages.main, {save: true});
    this.npmInstall(Packages.dev, {saveDev: true});
  }
});
<commit_msg>fix scss ext<commit_after>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var path  = require('path');

var Packages = {
  main:  [
    'alt',
    'classnames',
    'debug',
    'es6-shim',
    'react',
    'react-router',
    'whatwg-fetch'
  ],
  dev: [
    'autoprefixer-loader',
    'babel-core',
    'babel-loader',
    'css-loader',
    'file-loader',
    'html-webpack-plugin',
    'node-libs-browser',
    'react-hot-loader',
    'style-loader',
    'webpack',
    'webpack-dev-server'
  ]
};

module.exports = yeoman.generators.Base.extend({

  askForApp: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'React.js' + chalk.red(' ❤ ') + ' Alt  '
    ));
    this.log(chalk.magenta(
      'Out of the box I include React.js, react-router, Alt, all backed by webpack to build your app.'
    ));

    var root = this.destinationPath();

    var prompts = [{
      name: 'app',
      message: 'What\'s the name of the app?',
      default: path.basename(root)
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;
      this.app = props.app;
      done();
    }.bind(this));
  },

  askForLicense: function() {
    var done = this.async();

    var prompts = [{
      type: 'list',
      name: 'license',
      message: 'Which license you\'d like to use?',
      choices: [{
        name: 'Apache License 2.0',
        value: 'Apache-2.0'
      }, {
        name: 'BSD 2-clause "Simplified" License',
        value: 'BSD-2-Clause'
      }, {
        name: 'Eclipse Public License 1.0',
        value: 'EPL-1.0'
      }, {
        name: 'GNU General Public License v3.0',
        value: 'GPL-3.0'
      }, {
        name: 'GNU Lesser General Public License v3.0',
        valeu: 'LGPL-3.0'
      }, {
        name: 'MIT License',
        value: 'MIT'
      }, {
        name: 'Mozilla Public License 2.0',
        value: 'MPL-2.0'
      }],
      default: 0
    }];

    this.prompt(prompts, function (answers) {
      this.license = answers.license;
      done();
    }.bind(this));

  },

  askForPreprocessor: function () {
    var done = this.async();

    var prompts = [{
      type: 'list',
      name: 'preprocessor',
      message: 'How\'d you like to pre-process stylesheets?',
      choices: [{
        name: 'Sass',
        value: 'sass'
      }, {
        name: 'Less',
        value: 'less'
      }],
      default: 0
    }];

    this.prompt(prompts, function (answers) {
      var preprocessor = answers.preprocessor;

      function use(item) {
        return preprocessor && preprocessor.indexOf(item) !== -1;
      }

      // pre-processor for style sheets.
      if (use('less')) {
        this.preprocessor = { name: 'less', ext: '/\.less$/' };
      } else {
        this.preprocessor = { name: 'sass', ext: '/\.scss$/' };
      }

      done();
    }.bind(this));
  },

  installApp: function() {
    this.fs.copy(
      this.templatePath('index.html'),
      this.destinationPath('index.html')
    );
    this.fs.copy(
      this.templatePath(path.join('scripts', 'shared')),
      this.destinationPath(path.join('scripts', 'shared'))
    );
    this.fs.copy(
      this.templatePath(path.join('scripts', 'views')),
      this.destinationPath(path.join('scripts', 'views'))
    );
    this.fs.copyTpl(
      this.templatePath(path.join('scripts', 'bootstrap.jsx')),
      this.destinationPath(path.join('scripts', 'bootstrap.jsx')),
      { preprocessor: this.preprocessor.name }
    );
  },

  installAssets: function() {
    this.fs.copy(
      this.templatePath(path.join('assets', 'favicon.ico')),
      this.destinationPath(path.join('assets', 'favicon.ico'))
    );
    var ext = (this.preprocessor.name === 'less') ? 'less' : 'scss';
    this.fs.copy(
      this.templatePath(path.join('assets', 'app.' + ext)),
      this.destinationPath(path.join('assets', 'app.' + ext))
    );
  },

  finalize: function() {
    this.fs.copyTpl(
      this.templatePath('webpack.config.js'),
      this.destinationPath('webpack.config.js'),
      { preprocessor: this.preprocessor }
    );

    this.fs.copyTpl(
      this.templatePath('package.json'),
      this.destinationPath('package.json'),
      {
        app: this.app,
        license: this.license
      }
    );

    this.fs.copy(
      this.templatePath('editorconfig'),
      this.destinationPath('.editorconfig')
    );
  },

  install: function () {
    if (this.preprocessor.name === 'less') {
      Packages.dev.push('less');
      Packages.dev.push('less-loader');
    } else {
      Packages.dev.push('node-sass');
      Packages.dev.push('sass-loader');
    }

    this.npmInstall(Packages.main, {save: true});
    this.npmInstall(Packages.dev, {saveDev: true});
  }
});
<|endoftext|>