<commit_before>$(function() {
    var item_id = $("#comments").attr("data-id");
    // var commentsTmpl =  '
'+
    //                     '    '+
    //                     '
'+
    //                     '            <time pubdate datetime="${time}">${timeSince(time)}</time>';
    // if (loggedIn) {
    //     commentsTmpl += '            {{if username}}
'+
    //                     '
'+
    //                     '                    {{if owner}}
Delete
{{/if}}'+
    //                     '
Reply
'+
    //                     '                    {{if username != 0}}
PM User
{{/if}}'+
    //                     '
Report
'+
    //                     '
'+
    //                     '
{{/if}}';
    // }

    // commentsTmpl +=     '
'+
    //                     '        '+
    //                     '            {{if owner}}'+
    //                     '                 You'+
    //                     '            {{else username}}'+
    //                     '                {{if username == 0}}'+
    //                     '                    [deleted user]'+
    //                     '                {{else}}'+
    //                     '                     ${username}'+
    //                     '                {{/if}}'+
    //                     '            {{else}}'+
    //                     '                [comment removed]'+
    //                     '            {{/if}}'+
    //                     '        '+
    //                     '    '+
    //                     '
'+
    //                     '        {{if username}}'+
    //                     '            {{html comment}}'+
    //                     '        {{/if}}'+
    //                     '    {{if replies}}'+
    //                     '        {{tmpl(replies) "commentsTmpl"}}'+
    //                     '    {{/if}}'+
    //                     '
'+
    //                     '
';

    var commentsTmpl =  '
'+
                        '    {{if username}}'+
                        '        '+
                        '            '+
                        '        '+
                        '
'+
                        '            {{if username != 0}}'+
                        '                ${username}'+
                        '            {{else}}'+
                        '                [deleted user]'+
                        '            {{/if}}'+
                        '            <time class="small dark" pubdate datetime="${time}">${timeSince(time)}</time>'+
                        '
'+
                        '                 Reply '+
                        '                {{if owner}} ·  Delete{{/if}}'+
                        '
'+
                        '
'+
                        '                {{html comment}}'+
                        '
'+
                        '
'+
                        '    {{else}}'+
                        '
'+
                        '            [comment removed]'+
                        '
'+
                        '    {{/if}}'+
                        '    {{if replies}}
'+
                        '       {{tmpl(replies) "commentsTmpl"}}'+
                        '
{{/if}}'+
                        '
';

    // Need to compile template so it can be used recursively
    $.template("commentsTmpl", commentsTmpl);

    $.get("/files/ajax/comments.php", {"action": "get", "id": item_id}, function(data) {
        renderComment(data);
    }, "json");

    function renderComment(json, submit) {
        if (json.status == true) {
            var comments = json.comments;

            if (submit) {
                $.tmpl("commentsTmpl", comments).hide().prependTo("#comments_container").slideDown();
            } else {
                $('#comments_container .comments_loading').hide();
                $.tmpl("commentsTmpl", comments).prependTo("#comments_container");

                if (document.location.hash && document.location.hash.substring(0, 9) == "#comment-") {
                    highlight(document.location.hash);
                    target = $(document.location.hash);
                    var wheight = $(window).height();
                    var pos = target.offset().top - (wheight / 2) + target.height();
                    $('body, html').animate({ scrollTop: pos }, 400);
                }
            }

            $('a[href^="http://"]:has(img), a[href^="https://"]:has(img)').addClass('hide-external');
        }
    }

    // Hash tag highlight
    function highlight(elemId){
        $(elemId).addClass('highlight');
    }
    if (document.location.hash) {
        highlight(document.location.hash);
    }

    // Menu handlers
    var mainEditor = $('.wysiwyg')[0];
    $('#comments').on('click', '.comment-reply', function(e) {
        e.preventDefault();

        var parent = $(this).closest('.content').siblings(".replies");
        if (!parent.length) {
            $(this).closest('.comment').append($('
', {class: 'replies clr'}));
            var parent = $(this).closest('.content').siblings(".replies");
        }

        // Check for existing editor
        var tmp = parent.children('form');
        if (tmp.length) {
            newEditor = tmp;
        } else {
            var newEditor = $(mainEditor).clone();
            var submitButton = $('<input>', {class: 'submit button right', type: 'submit', value: 'Submit'});
            var cancelButton = $('', {class: 'cancel right', href: '#', text: 'Cancel'});
            var $form = $("<form>").append(newEditor).append(submitButton).append(cancelButton);

            if (parent.find('article').length)
                $(parent.find('article')[0]).before($form);
            else
                parent.append($form);

            $('.suggest').autosuggest();
        }

        newEditor.children('textarea').focus();

        var wheight = $(window).height();
        var pos = newEditor.offset().top - (wheight / 2) + newEditor.height();
        $('body, html').animate({ scrollTop: pos }, 400);
    }).on('click', '.comment-delete', function(e) {
        e.preventDefault();
        $article = $(this).closest('article');
        var comment_id = $article.attr('data-id');

        $.post('/files/ajax/comments.php?action=delete', {"id": comment_id}, function(data) {
            if (data.status) {
                $article.slideUp(function() { $(this).remove(); });
                //update counter
                var $responses = $('#comments > h2');
                var tmp = $responses.text().replace(/(\d+)+/g, function(match, number) {
                    return parseInt(number)-1;
                });
                $responses.text(tmp);
            } else {
                alert("There appears to be a problem deleting this comment");
            }
        }, 'json');
    });

    // WYSIYG controls
    $('#comments').on('click', '.cancel', function(e) {
        e.preventDefault();
        var parent = $(this).closest('form').slideUp(200, function() { $(this).remove() });
    }).on('submit', 'form', function(e) {
        e.preventDefault();

        var $article = $(this).closest('article');

        var parent_id = $article.attr("data-id");
        if (!parent_id)
            parent_id = 0;

        var $parent = $(this).closest('form');
        var body = $parent.find('textarea').val();

        $parent.children('.msg').remove();

        $.post('/files/ajax/comments.php?action=add', {"id": item_id, "parent": parent_id, "body": body},
            function(data) {
                if (data.status) {
                    var msg = $('
', {class: 'hide msg msg-good'}).append($('', {class: 'icon-good'})).append("Comment submitted");
                    var newComment = $.tmpl("commentsTmpl", data.comment);

                    if (parent_id === 0) {
                        msg.hide().prependTo($parent).slideDown();
                        $parent.find('textarea').val('');
                        $parent = $('#comments_container');
                        newComment.hide().prependTo($parent).slideDown();
                    } else {
                        msg.prependTo(newComment);
                        $parent.after(newComment);
                        $parent.remove();
                    }

                    //update counter
                    var $responses = $('#comments > h2');
                    var tmp = $responses.text().replace(/(\d+)+/g, function(match, number) {
                        return parseInt(number)+1;
                    });
                    $responses.text(tmp);
                } else {
                    alert("An error!");
                }
            },
            'json');
    });
});
<commit_msg>Fix for #133<commit_after>$(function() {
    var item_id = $("#comments").attr("data-id");
    // var commentsTmpl =  '
'+
    //                     '    '+
    //                     '
'+
    //                     '            <time pubdate datetime="${time}">${timeSince(time)}</time>';
    // if (loggedIn) {
    //     commentsTmpl += '            {{if username}}
'+
    //                     '
'+
    //                     '                    {{if owner}}
Delete
{{/if}}'+
    //                     '
Reply
'+
    //                     '                    {{if username != 0}}
PM User
{{/if}}'+
    //                     '
Report
'+
    //                     '
'+
    //                     '
{{/if}}';
    // }

    // commentsTmpl +=     '
'+
    //                     '        '+
    //                     '            {{if owner}}'+
    //                     '                 You'+
    //                     '            {{else username}}'+
    //                     '                {{if username == 0}}'+
    //                     '                    [deleted user]'+
    //                     '                {{else}}'+
    //                     '                     ${username}'+
    //                     '                {{/if}}'+
    //                     '            {{else}}'+
    //                     '                [comment removed]'+
    //                     '            {{/if}}'+
    //                     '        '+
    //                     '    '+
    //                     '
'+
    //                     '        {{if username}}'+
    //                     '            {{html comment}}'+
    //                     '        {{/if}}'+
    //                     '    {{if replies}}'+
    //                     '        {{tmpl(replies) "commentsTmpl"}}'+
    //                     '    {{/if}}'+
    //                     '
'+
    //                     '
';

    var commentsTmpl =  '
'+
                        '    {{if username}}'+
                        '        '+
                        '            '+
                        '        '+
                        '
'+
                        '            {{if username != 0}}'+
                        '                ${username}'+
                        '            {{else}}'+
                        '                [deleted user]'+
                        '            {{/if}}'+
                        '            <time class="small dark" pubdate datetime="${time}">${timeSince(time)}</time>'+
                        '
'+
                        '                 Reply '+
                        '                {{if owner}} ·  Delete{{/if}}'+
                        '
'+
                        '
'+
                        '                {{html comment}}'+
                        '
'+
                        '
'+
                        '    {{else}}'+
                        '
'+
                        '            [comment removed]'+
                        '
'+
                        '    {{/if}}'+
                        '    {{if replies}}
'+
                        '       {{tmpl(replies) "commentsTmpl"}}'+
                        '
{{/if}}'+
                        '
';

    // Need to compile template so it can be used recursively
    $.template("commentsTmpl", commentsTmpl);

    $.get("/files/ajax/comments.php", {"action": "get", "id": item_id}, function(data) {
        renderComment(data);
    }, "json");

    function renderComment(json, submit) {
        if (json.status == true) {
            var comments = json.comments;

            if (submit) {
                $.tmpl("commentsTmpl", comments).hide().prependTo("#comments_container").slideDown();
            } else {
                $('#comments_container .comments_loading').hide();
                $.tmpl("commentsTmpl", comments).prependTo("#comments_container");

                if (document.location.hash && document.location.hash.substring(0, 9) == "#comment-") {
                    highlight(document.location.hash);
                    target = $(document.location.hash);
                    var wheight = $(window).height();
                    var pos = target.offset().top - (wheight / 2) + target.height();
                    $('body, html').animate({ scrollTop: pos }, 400);
                }
            }

            $('a[href^="http://"]:has(img), a[href^="https://"]:has(img)').addClass('hide-external');
        }
    }

    // Hash tag highlight
    function highlight(elemId){
        $(elemId).addClass('highlight');
    }
    if (document.location.hash) {
        highlight(document.location.hash);
    }

    // Menu handlers
    var mainEditor = $('.wysiwyg')[0];
    $('#comments').on('click', '.comment-reply', function(e) {
        e.preventDefault();

        var parent = $(this).closest('.content').siblings(".replies");
        if (!parent.length) {
            $(this).closest('.comment').append($('
', {class: 'replies clr'}));
            var parent = $(this).closest('.content').siblings(".replies");
        }

        // Check for existing editor
        var tmp = parent.children('form');
        if (tmp.length) {
            newEditor = tmp;
        } else {
            var newEditor = $(mainEditor).clone();
            var submitButton = $('<input>', {class: 'submit button right', type: 'submit', value: 'Submit'});
            var cancelButton = $('', {class: 'cancel right', href: '#', text: 'Cancel'});
            var $form = $("<form>").append(newEditor).append(submitButton).append(cancelButton);

            if (parent.find('article').length)
                $(parent.find('article')[0]).before($form);
            else
                parent.append($form);

            $('.suggest').autosuggest();
        }

        newEditor.children('textarea').focus();

        var wheight = $(window).height();
        var pos = newEditor.offset().top - (wheight / 2) + newEditor.height();
        $('body, html').animate({ scrollTop: pos }, 400);
    }).on('click', '.comment-delete', function(e) {
        e.preventDefault();
        $article = $(this).closest('article');
        var comment_id = $article.attr('data-id');

        $.post('/files/ajax/comments.php?action=delete', {"id": comment_id}, function(data) {
            if (data.status) {
                $article.slideUp(function() { $(this).remove(); });
                //update counter
                var $responses = $('#comments > h2');
                var tmp = $responses.text().replace(/(\d+)+/, function(match, number) {
                    return parseInt(number)-1;
                });
                $responses.text(tmp);
            } else {
                alert("There appears to be a problem deleting this comment");
            }
        }, 'json');
    });

    // WYSIYG controls
    $('#comments').on('click', '.cancel', function(e) {
        e.preventDefault();
        var parent = $(this).closest('form').slideUp(200, function() { $(this).remove() });
    }).on('submit', 'form', function(e) {
        e.preventDefault();

        var $article = $(this).closest('article');

        var parent_id = $article.attr("data-id");
        if (!parent_id)
            parent_id = 0;

        var $parent = $(this).closest('form');
        var body = $parent.find('textarea').val();

        $parent.children('.msg').remove();

        $.post('/files/ajax/comments.php?action=add', {"id": item_id, "parent": parent_id, "body": body},
            function(data) {
                if (data.status) {
                    var msg = $('
', {class: 'hide msg msg-good'}).append($('', {class: 'icon-good'})).append("Comment submitted");
                    var newComment = $.tmpl("commentsTmpl", data.comment);

                    if (parent_id === 0) {
                        msg.hide().prependTo($parent).slideDown();
                        $parent.find('textarea').val('');
                        $parent = $('#comments_container');
                        newComment.hide().prependTo($parent).slideDown();
                    } else {
                        msg.prependTo(newComment);
                        $parent.after(newComment);
                        $parent.remove();
                    }

                    //update counter
                    var $responses = $('#comments > h2');
                    var tmp = $responses.text().replace(/(\d+)+/, function(match, number) {
                        return parseInt(number)+1;
                    });
                    $responses.text(tmp);
                } else {
                    alert("An error!");
                }
            },
            'json');
    });
});
<|endoftext|>


<commit_before>'use strict';

const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const path = require('path');
const resolve = require('resolve');
const concatBundle = require('./concat-bundle');
const buildDebugMacroPlugin = require('./build-debug-macro-plugin');
const buildStripClassCallcheckPlugin = require('./build-strip-class-callcheck-plugin');
const injectBabelHelpers = require('./transforms/inject-babel-helpers');

const PRE_BUILT_TARGETS = [
  'last 1 Chrome versions',
  'last 1 Firefox versions',
  'last 1 Safari versions',
];

const paths = {};
const absolutePaths = {};

function add(paths, name, path) {
  Object.defineProperty(paths, name, {
    configurable: false,
    get: function() {
      return path;
    },
  });
}

add(paths, 'prod', 'vendor/ember/ember.js');
add(paths, 'debug', 'vendor/ember/ember.js');
add(paths, 'testing', 'vendor/ember/ember-testing.js');
add(paths, 'jquery', 'vendor/ember/jquery/jquery.js');

add(
  absolutePaths,
  'templateCompiler',
  path.join(__dirname, '..', 'dist', 'ember-template-compiler.js')
);

module.exports = {
  init() {
    this._super.init && this._super.init.apply(this, arguments);

    if ('ember' in this.project.bowerDependencies()) {
      // TODO: move this to a throw soon.
      this.ui.writeWarnLine(
        'Ember.js is now provided by node_module `ember-source`, please remove it from bower'
      );
    }

    // resets `this.root` to the correct location by default ember-cli
    // considers `__dirname` here to be the root, but since our main entry
    // point is within a subfolder we need to correct that
    this.root = path.join(__dirname, '..');

    // Updates the vendor tree to point to dist, so we get the correct tree in
    // treeForVendor
    this.treePaths.vendor = 'dist';
  },

  name: 'ember-source',
  paths,
  absolutePaths,

  transpileTree(tree, isProduction) {
    let emberCliBabel = this.addons.find(a => a.name === 'ember-cli-babel');

    let parentOptions = this.parent && this.parent.options;
    let appOptions = this.app && this.app.options;
    let babelOptions = (parentOptions || appOptions || {}).babel;

    // We want to enable async/generator helpers if we are developing locally,
    // but not for any other project.
    let isEmberSource = this.project.name() === 'ember-source';

    let options = {
      'ember-cli-babel': {
        disableDebugTooling: true,
        disableEmberModulesAPIPolyfill: true,
      },
      babel: Object.assign({}, babelOptions, {
        loose: true,
        plugins: [
          injectBabelHelpers(isEmberSource),
          buildDebugMacroPlugin(!isProduction),
          [
            require.resolve('@babel/plugin-transform-block-scoping'),
            { throwIfClosureRequired: true },
          ],
          [require.resolve('@babel/plugin-transform-object-assign')],
        ],
      }),
    };

    if (isProduction) {
      options.babel.plugins.push(buildStripClassCallcheckPlugin());
    }

    return emberCliBabel.transpileTree(tree, options);
  },

  buildEmberBundles(tree, isProduction) {
    let packages = this.transpileTree(new Funnel(tree, { srcDir: 'packages' }), isProduction);

    let dependencies = this.transpileTree(
      new Funnel(tree, { srcDir: 'dependencies' }),
      isProduction
    );

    let headerFiles = new Funnel(tree, { srcDir: 'header' });

    let exclude = isProduction ? ['ember-testing/**'] : [];

    let emberFiles = new MergeTrees([new Funnel(packages, { exclude }), dependencies, headerFiles]);

    let emberTestingFiles = new MergeTrees([
      new Funnel(packages, {
        include: [
          '@ember/debug/lib/**',
          '@ember/debug/index.js',
          'ember-testing/index.js',
          'ember-testing/lib/**',
        ],
      }),
      headerFiles,
    ]);

    return new MergeTrees([
      concatBundle(emberFiles, {
        outputFile: 'ember.js',
        footer: "require('ember');",
      }),

      concatBundle(emberTestingFiles, {
        outputFile: 'ember-testing.js',
        footer: `
          var testing = require('ember-testing');
          Ember.Test = testing.Test;
          Ember.Test.Adapter = testing.Adapter;
          Ember.Test.QUnitAdapter = testing.QUnitAdapter;
          Ember.setupForTesting = testing.setupForTesting;
        `,
      }),
    ]);
  },

  treeForVendor(tree) {
    let jqueryPath;

    try {
      jqueryPath = path.dirname(
        resolve.sync('jquery/package.json', { basedir: this.project.root })
      );
    } catch (error) {
      jqueryPath = path.dirname(require.resolve('jquery/package.json'));
    }

    let jquery = new Funnel(jqueryPath + '/dist', {
      destDir: 'ember/jquery',
      files: ['jquery.js'],
    });

    let templateCompiler = new Funnel(tree, {
      destDir: 'ember',
      include: ['ember-template-compiler.js', 'ember-template-compiler.map'],
    });

    let ember;
    let targets = (this.project && this.project.targets && this.project.targets.browsers) || [];

    const isProduction = process.env.EMBER_ENV === 'production';

    if (
      !isProduction &&
      (PRE_BUILT_TARGETS.every(target => targets.includes(target)) &&
        targets.length === PRE_BUILT_TARGETS.length)
    ) {
      ember = new Funnel(tree, {
        destDir: 'ember',
        include: ['ember.debug.js', 'ember.debug.map', 'ember-testing.js', 'ember-testing.map'],
        getDestinationPath(path) {
          return path.replace('ember.debug.', 'ember.');
        },
      });
    } else {
      ember = new Funnel(this.buildEmberBundles(tree, isProduction), {
        destDir: 'ember',
      });
    }

    return new MergeTrees([ember, templateCompiler, jquery]);
  },
};
<commit_msg>[BUGFIX release] Require Octane features when using Octane preview.<commit_after>'use strict';

const MergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const path = require('path');
const resolve = require('resolve');
const concatBundle = require('./concat-bundle');
const buildDebugMacroPlugin = require('./build-debug-macro-plugin');
const buildStripClassCallcheckPlugin = require('./build-strip-class-callcheck-plugin');
const injectBabelHelpers = require('./transforms/inject-babel-helpers');

const PRE_BUILT_TARGETS = [
  'last 1 Chrome versions',
  'last 1 Firefox versions',
  'last 1 Safari versions',
];

const paths = {};
const absolutePaths = {};

function add(paths, name, path) {
  Object.defineProperty(paths, name, {
    configurable: false,
    get: function() {
      return path;
    },
  });
}

add(paths, 'prod', 'vendor/ember/ember.js');
add(paths, 'debug', 'vendor/ember/ember.js');
add(paths, 'testing', 'vendor/ember/ember-testing.js');
add(paths, 'jquery', 'vendor/ember/jquery/jquery.js');

add(
  absolutePaths,
  'templateCompiler',
  path.join(__dirname, '..', 'dist', 'ember-template-compiler.js')
);

module.exports = {
  init() {
    this._super.init && this._super.init.apply(this, arguments);

    if ('ember' in this.project.bowerDependencies()) {
      // TODO: move this to a throw soon.
      this.ui.writeWarnLine(
        'Ember.js is now provided by node_module `ember-source`, please remove it from bower'
      );
    }

    // resets `this.root` to the correct location by default ember-cli
    // considers `__dirname` here to be the root, but since our main entry
    // point is within a subfolder we need to correct that
    this.root = path.join(__dirname, '..');

    // Updates the vendor tree to point to dist, so we get the correct tree in
    // treeForVendor
    this.treePaths.vendor = 'dist';
  },

  name: 'ember-source',
  paths,
  absolutePaths,

  included() {
    this._super.included.apply(this, arguments);

    const { has } = require('@ember/edition-utils');

    if (has('octane')) {
      let optionalFeatures = this.project.addons.find(a => a.name === '@ember/optional-features');
      let optionalFeaturesMissing = optionalFeatures !== undefined;
      let missingFeatures = [];

      if (optionalFeaturesMissing) {
        missingFeatures.push(
          `* the @ember/optional-features addon is missing, run \`ember install @ember/optional-features\` to install it`
        );
      }

      if (optionalFeaturesMissing || optionalFeatures.isFeatureEnabled('jquery-integration')) {
        missingFeatures.push(
          `* The jquery-integration optional feature should be disabled under Octane, run \`ember feature:disable jquery-integration\` to disable it`
        );
      }

      if (
        optionalFeaturesMissing ||
        optionalFeatures.isFeatureEnabled('application-template-wrapper')
      ) {
        missingFeatures.push(
          `* The application-template-wrapper optional feature should be disabled under Octane, run \`ember feature:disable application-template-wrapper\` to disable it`
        );
      }

      if (
        optionalFeaturesMissing ||
        !optionalFeatures.isFeatureEnabled('template-only-glimmer-component')
      ) {
        missingFeatures.push(
          `* The template-only-glimmer-component optional feature should be enabled under Octane, run \`ember feature:enabled template-only-glimmer-component\` to enable it`
        );
      }

      if (missingFeatures.length > 0) {
        let intro = `You have configured your application to indicate that it is using the 'octane' edition (via \`setEdition('octane')\`), but the appropriate Octane features were not enabled:`;

        const SilentError = require('silent-error');
        throw new SilentError(`${intro}\n\n${missingFeatures.join('\n\t')}`);
      }
    }
  },

  transpileTree(tree, isProduction) {
    let emberCliBabel = this.addons.find(a => a.name === 'ember-cli-babel');

    let parentOptions = this.parent && this.parent.options;
    let appOptions = this.app && this.app.options;
    let babelOptions = (parentOptions || appOptions || {}).babel;

    // We want to enable async/generator helpers if we are developing locally,
    // but not for any other project.
    let isEmberSource = this.project.name() === 'ember-source';

    let options = {
      'ember-cli-babel': {
        disableDebugTooling: true,
        disableEmberModulesAPIPolyfill: true,
      },
      babel: Object.assign({}, babelOptions, {
        loose: true,
        plugins: [
          injectBabelHelpers(isEmberSource),
          buildDebugMacroPlugin(!isProduction),
          [
            require.resolve('@babel/plugin-transform-block-scoping'),
            { throwIfClosureRequired: true },
          ],
          [require.resolve('@babel/plugin-transform-object-assign')],
        ],
      }),
    };

    if (isProduction) {
      options.babel.plugins.push(buildStripClassCallcheckPlugin());
    }

    return emberCliBabel.transpileTree(tree, options);
  },

  buildEmberBundles(tree, isProduction) {
    let packages = this.transpileTree(new Funnel(tree, { srcDir: 'packages' }), isProduction);

    let dependencies = this.transpileTree(
      new Funnel(tree, { srcDir: 'dependencies' }),
      isProduction
    );

    let headerFiles = new Funnel(tree, { srcDir: 'header' });

    let exclude = isProduction ? ['ember-testing/**'] : [];

    let emberFiles = new MergeTrees([new Funnel(packages, { exclude }), dependencies, headerFiles]);

    let emberTestingFiles = new MergeTrees([
      new Funnel(packages, {
        include: [
          '@ember/debug/lib/**',
          '@ember/debug/index.js',
          'ember-testing/index.js',
          'ember-testing/lib/**',
        ],
      }),
      headerFiles,
    ]);

    return new MergeTrees([
      concatBundle(emberFiles, {
        outputFile: 'ember.js',
        footer: "require('ember');",
      }),

      concatBundle(emberTestingFiles, {
        outputFile: 'ember-testing.js',
        footer: `
          var testing = require('ember-testing');
          Ember.Test = testing.Test;
          Ember.Test.Adapter = testing.Adapter;
          Ember.Test.QUnitAdapter = testing.QUnitAdapter;
          Ember.setupForTesting = testing.setupForTesting;
        `,
      }),
    ]);
  },

  treeForVendor(tree) {
    let jqueryPath;

    try {
      jqueryPath = path.dirname(
        resolve.sync('jquery/package.json', { basedir: this.project.root })
      );
    } catch (error) {
      jqueryPath = path.dirname(require.resolve('jquery/package.json'));
    }

    let jquery = new Funnel(jqueryPath + '/dist', {
      destDir: 'ember/jquery',
      files: ['jquery.js'],
    });

    let templateCompiler = new Funnel(tree, {
      destDir: 'ember',
      include: ['ember-template-compiler.js', 'ember-template-compiler.map'],
    });

    let ember;
    let targets = (this.project && this.project.targets && this.project.targets.browsers) || [];

    const isProduction = process.env.EMBER_ENV === 'production';

    if (
      !isProduction &&
      (PRE_BUILT_TARGETS.every(target => targets.includes(target)) &&
        targets.length === PRE_BUILT_TARGETS.length)
    ) {
      ember = new Funnel(tree, {
        destDir: 'ember',
        include: ['ember.debug.js', 'ember.debug.map', 'ember-testing.js', 'ember-testing.map'],
        getDestinationPath(path) {
          return path.replace('ember.debug.', 'ember.');
        },
      });
    } else {
      ember = new Funnel(this.buildEmberBundles(tree, isProduction), {
        destDir: 'ember',
      });
    }

    return new MergeTrees([ember, templateCompiler, jquery]);
  },
};
<|endoftext|>


<commit_before>var UISwitch = function(element, options) {
    if (typeof options.enabled === 'undefined') {
        options.enabled = true;
    }

    if (typeof options.activatedColor === 'undefined') {
        options.activatedColor = '#4bd963';
    }

    if (typeof options.deactivatedColor === 'undefined') {
        options.deactivatedColor = '#ffffff';
    }

    if (typeof options.transitionTime === 'undefined') {
        options.transitionTime = 2500;
    }

    if (typeof options.disabledOpacity === 'undefined') {
        options.disabledOpacity = 0.5;
    }

    this._enabled = options.enabled;
    this._activatedColor = options.activatedColor;
    this._deactivatedColor = options.deactivatedColor;
    this._transitionTime = options.transitionTime;
    this._disabledOpacity = options.disabledOpacity;
};

Object.defineProperty(UISwitch.prototype, 'enabled', {
    get: function() {
        return this._enabled;
    },
    set: function(enabled) {
        this._enabled = enabled;
    }
});

Object.defineProperty(UISwitch.prototype, 'activatedColor', {
    get: function() {
        return this._activatedColor;
    },
    set: function(activatedColor) {
        this._activatedColor = activatedColor;
    }
});

Object.defineProperty(UISwitch.prototype, 'deactivatedColor', {
    get: function() {
        return this._deactivatedColor;
    },
    set: function(deactivatedColor) {
        this._deactivatedColor = deactivatedColor;
    }
});

Object.defineProperty(UISwitch.prototype, 'transitionTime', {
    get: function() {
        return this._transitionTime;
    },
    set: function(transitionTime) {
        this._transitionTime = transitionTime;
    }
});

Object.defineProperty(UISwitch.prototype, 'className', {
    get: function() {
        return this._className;
    },
    set: function(className) {
        this._className = className;
    }
});

Object.defineProperty(UISwitch.prototype, 'disabledOpacity', {
    get: function() {
        return this._disabledOpacity;
    },
    set: function(disabledOpacity) {
        this._disabledOpacity = disabledOpacity;
    }
});
<commit_msg>Added type check for element.<commit_after>var UISwitch = function(element, options) {
    if (typeof element.type === ‘undefined’ || element.type !== ‘checkbox’) {
        throw new Error("'element' must be a checkbox");
    }

    if (typeof options.enabled === 'undefined') {
        options.enabled = true;
    }

    if (typeof options.activatedColor === 'undefined') {
        options.activatedColor = '#4bd963';
    }

    if (typeof options.deactivatedColor === 'undefined') {
        options.deactivatedColor = '#ffffff';
    }

    if (typeof options.transitionTime === 'undefined') {
        options.transitionTime = 2500;
    }

    if (typeof options.disabledOpacity === 'undefined') {
        options.disabledOpacity = 0.5;
    }

    this._enabled = options.enabled;
    this._activatedColor = options.activatedColor;
    this._deactivatedColor = options.deactivatedColor;
    this._transitionTime = options.transitionTime;
    this._disabledOpacity = options.disabledOpacity;
};

Object.defineProperty(UISwitch.prototype, 'enabled', {
    get: function() {
        return this._enabled;
    },
    set: function(enabled) {
        this._enabled = enabled;
    }
});

Object.defineProperty(UISwitch.prototype, 'activatedColor', {
    get: function() {
        return this._activatedColor;
    },
    set: function(activatedColor) {
        this._activatedColor = activatedColor;
    }
});

Object.defineProperty(UISwitch.prototype, 'deactivatedColor', {
    get: function() {
        return this._deactivatedColor;
    },
    set: function(deactivatedColor) {
        this._deactivatedColor = deactivatedColor;
    }
});

Object.defineProperty(UISwitch.prototype, 'transitionTime', {
    get: function() {
        return this._transitionTime;
    },
    set: function(transitionTime) {
        this._transitionTime = transitionTime;
    }
});

Object.defineProperty(UISwitch.prototype, 'className', {
    get: function() {
        return this._className;
    },
    set: function(className) {
        this._className = className;
    }
});

Object.defineProperty(UISwitch.prototype, 'disabledOpacity', {
    get: function() {
        return this._disabledOpacity;
    },
    set: function(disabledOpacity) {
        this._disabledOpacity = disabledOpacity;
    }
});
<|endoftext|>


<commit_before>/* jshint esversion:6, node: true */

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}));

// parse application/json
app.use(bodyParser.json());

// index
app.get('/', function (req, res) {
	res.send('hello world i am a secret bot');
});

// for facebook verification
app.get('/webhook/', function (req, res) {
	if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
		res.send(req.query['hub.challenge']);
	} else {
		res.send('Error, wrong token');
	}
});

// to post data
app.post('/webhook/', function (req, res) {
	var results;

	let messaging_events = req.body.entry[0].messaging;
	for (let i = 0; i < messaging_events.length; i++) {
		let event = req.body.entry[0].messaging[i];
		let sender = event.sender.id;

		if (event.message && event.message.text) {
			let text = event.message.text;
			if (text === 'Generic') {
				sendGenericMessage(sender);
				continue;
			}

			else if (text == 'cookies'){
				var headers = {
				    'Authorization': 'bearer fd887ce5-7b15-4c1e-93a0-dc91ce883ec6'
				};

				var options = {
				    url: 'https://www.loblaws.ca/ecommerce/v2/loblaw/products/search?q=apple&page=0&pageSize=10&sort=recommended&filters=category:LSL001006000000',
				    headers: headers
				};
				function callback(error, response, body) {
				    if (!error && response.statusCode == 200) {
				        //console.log(body);
				        var resp = JSON.parse(body);
				        results = resp["searchResults"];
				        console.log(results[0]);
				        console.log(results.products[0].productName);

				        sendProductMessage(sender, results);
				    }
				}

				request(options, callback);

			}
			sendTextMessage(sender, "echo: " + text.substring(0, 200));
		}
		if (event.postback) {
			let text = JSON.stringify(event.postback);
			sendTextMessage(sender, "Postback received: "+text.substring(0, 200), token);
			continue;
		}
	}
	res.sendStatus(200);
});

// recommended to inject access tokens as environmental variables, e.g.
const token = process.env.PAGE_ACCESS_TOKEN;
//const token = "<PAGE_ACCESS_TOKEN>"

function sendTextMessage(sender, text) {
	let messageData = { text:text };

	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

function sendGenericMessage(sender) {
	let messageData = {
		"attachment": {
			"type": "template",
			"payload": {
				"template_type": "generic",
				"elements": [{
					"title": "First card",
					"subtitle": "Element #1 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/rift.png",
					"buttons": [{
						"type": "web_url",
						"url": "https://www.messenger.com",
						"title": "web url"
					}, {
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for first element in a generic bubble",
					}],
				}, {
					"title": "Second card",
					"subtitle": "Element #2 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
					"buttons": [{
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for second element in a generic bubble",
					}],
				}]
			}
		}
	};

	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

/*
	* Results is the api response
	* Makes a carouel displaying tile, description, and image
*/
function sendProductMessage(sender, results) {
	let messageData = {
		"attachment": {
			"type": "template",
			"payload": {
				"template_type": "generic",
				"elements": loadElements(results.products) //Load the products into an object that messenger api can handle
				/*"elements": [{
					"title": results.products[0].productName,
					"subtitle": results.products[0].description,
					"image_url": results.products[0].primaryImage,
					"buttons": [{
						"type": "web_url",
						"url": "https://www.messenger.com",
						"title": "web url"
					}, {
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for first element in a generic bubble",
					}],
				}, {
					"title": "Second card",
					"subtitle": "Element #2 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
					"buttons": [{
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for second element in a generic bubble",
					}],
				}] */
			}
		}
	};

	//Send message
	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

/*
	* Load products into an array that can be handled by messenger api
	* Makes carousel as long as number of responses
*/
function loadElements(products){
	var elements = []; //Create blank array

	console.log("Length: " + products.length);

	for (var i = 0; i < products.length; i++){
		var element = {
			"title": products[i].productName, //Sets title
			"subtitle": products[i].description, //Sets description
			"image_url": products[i].primaryImage, //Sets image
		};

		elements.push(element); //Add the element to the array
	}

	return elements;
}

// Start the server
app.listen(app.get('port'), function() {
	console.log('running on port', app.get('port'));
});
<commit_msg>Add picture handler<commit_after>/* jshint esversion:6, node: true */

'use strict';

const action_handler = require('./action_handler.js');

const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}));

// parse application/json
app.use(bodyParser.json());

// index
app.get('/', function (req, res) {
	res.send('hello world i am a secret bot');
});

// for facebook verification
app.get('/webhook/', function (req, res) {
	if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
		res.send(req.query['hub.challenge']);
	} else {
		res.send('Error, wrong token');
	}
});

// to post data
app.post('/webhook/', function (req, res) {
	var results;

	let messaging_events = req.body.entry[0].messaging;
	for (let i = 0; i < messaging_events.length; i++) {
		let event = req.body.entry[0].messaging[i];
		let sender = event.sender.id;

		if (event.message && event.message.text) {
			let text = event.message.text;
			if (text === 'Generic') {
				sendGenericMessage(sender);
				continue;
			}

			else if (text == 'cookies'){
				var headers = {
				    'Authorization': 'bearer fd887ce5-7b15-4c1e-93a0-dc91ce883ec6'
				};

				var options = {
				    url: 'https://www.loblaws.ca/ecommerce/v2/loblaw/products/search?q=apple&page=0&pageSize=10&sort=recommended&filters=category:LSL001006000000',
				    headers: headers
				};
				function callback(error, response, body) {
				    if (!error && response.statusCode == 200) {
				        //console.log(body);
				        var resp = JSON.parse(body);
				        results = resp["searchResults"];
				        console.log(results[0]);
				        console.log(results.products[0].productName);

				        sendProductMessage(sender, results);
				    }
				}

				request(options, callback);

			}
			sendTextMessage(sender, "echo: " + text.substring(0, 200));
		}
		if (event.postback) {
			let text = JSON.stringify(event.postback);
			sendTextMessage(sender, "Postback received: "+text.substring(0, 200), token);
			continue;
		}
	}
	res.sendStatus(200);
});

// To handle picture receive.
app.post('/webhook/', function (req, res) {
	var results;
	let messaging_events = req.body.entry[0].messaging;

	for (let i = 0; i < messaging_events.length; i++) {
		let event = req.body.entry[0].messaging[i];
		let sender = event.sender.id;

		if (event.message && event.message.attachment && event.message.attachment.type === 'image') {
			let image_url = event.message.attachment.paylod.url;

			action_handler.handlePicture(image_url, sender);
		}
	}

	res.sendStatus(200);
});

// recommended to inject access tokens as environmental variables, e.g.
const token = process.env.PAGE_ACCESS_TOKEN;
//const token = "<PAGE_ACCESS_TOKEN>"

function sendTextMessage(sender, text) {
	let messageData = { text:text };

	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

function sendGenericMessage(sender) {
	let messageData = {
		"attachment": {
			"type": "template",
			"payload": {
				"template_type": "generic",
				"elements": [{
					"title": "First card",
					"subtitle": "Element #1 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/rift.png",
					"buttons": [{
						"type": "web_url",
						"url": "https://www.messenger.com",
						"title": "web url"
					}, {
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for first element in a generic bubble",
					}],
				}, {
					"title": "Second card",
					"subtitle": "Element #2 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
					"buttons": [{
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for second element in a generic bubble",
					}],
				}]
			}
		}
	};

	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

/*
	* Results is the api response
	* Makes a carouel displaying tile, description, and image
*/
function sendProductMessage(sender, results) {
	let messageData = {
		"attachment": {
			"type": "template",
			"payload": {
				"template_type": "generic",
				"elements": loadElements(results.products) //Load the products into an object that messenger api can handle
				/*"elements": [{
					"title": results.products[0].productName,
					"subtitle": results.products[0].description,
					"image_url": results.products[0].primaryImage,
					"buttons": [{
						"type": "web_url",
						"url": "https://www.messenger.com",
						"title": "web url"
					}, {
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for first element in a generic bubble",
					}],
				}, {
					"title": "Second card",
					"subtitle": "Element #2 of an hscroll",
					"image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
					"buttons": [{
						"type": "postback",
						"title": "Postback",
						"payload": "Payload for second element in a generic bubble",
					}],
				}] */
			}
		}
	};

	//Send message
	request({
		url: 'https://graph.facebook.com/v2.6/me/messages',
		qs: {access_token:token},
		method: 'POST',
		json: {
			recipient: {id:sender},
			message: messageData,
		}
	}, function(error, response, body) {
		if (error) {
			console.log('Error sending messages: ', error);
		} else if (response.body.error) {
			console.log('Error: ', response.body.error);
		}
	});
}

/*
	* Load products into an array that can be handled by messenger api
	* Makes carousel as long as number of responses
*/
function loadElements(products){
	var elements = []; //Create blank array

	console.log("Length: " + products.length);

	for (var i = 0; i < products.length; i++){
		var element = {
			"title": products[i].productName, //Sets title
			"subtitle": products[i].description, //Sets description
			"image_url": products[i].primaryImage, //Sets image
		};

		elements.push(element); //Add the element to the array
	}

	return elements;
}

// Start the server
app.listen(app.get('port'), function() {
	console.log('running on port', app.get('port'));
});
<|endoftext|>


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

var Step = require("step"),
    http = require("http"),
    https = require("https"),
    xml2js = require("xml2js");

var xrd2jrd = function(str, callback) {
    Step(
        function() {
            var parser = new xml2js.Parser();
            parser.parseString(str, this);
        },
        function(err, doc) {
            var Link, jrd = {}, i, prop, l;
            if (err) {
                callback(err, null);
            } else {
                if (doc.hasOwnProperty("Link")) {
                    Link = doc.Link;
                    jrd.links = [];
                    if (Array.isArray(Link)) {
                        for (i = 0; i < Link.length; i++) {
                            l = {};
                            for (prop in Link[i]["@"]) {
                                if (Link[i]["@"].hasOwnProperty(prop)) {
                                    l[prop] = Link[i]["@"][prop];
                                }
                            }
                            jrd.links.push(l);
                        }
                    } else {
                        l = {};
                        for (prop in Link["@"]) {
                            if (Link["@"].hasOwnProperty(prop)) {
                                l[prop] = Link["@"][prop];
                            }
                        }
                        jrd.links.push(l);
                    }
                }
                callback(null, jrd);
            }
        }
    );
};

var webfinger = function(address, callback) {
    callback(new Error("Not yet implemented"), null);
};

var xrdHandler = function(callback) {
    return function(res) {

        var body = "";

        if (res.statusCode !== 200) {
            callback(new Error("Bad response code: " + res.statusCode), null);
            return;
        }

        if (!res.headers["content-type"] || res.headers["content-type"].substr(0, 19) != "application/xrd+xml") {
            callback(new Error("Bad content type: " + res.headers["content-type"]), null);
            return;
        }

        res.setEncoding('utf8');

        res.on('data', function (chunk) {
            body = body + chunk;
        });

        res.on("error", function(err) {
            callback(err, null);
        });

        res.on("end", function() {
            xrd2jrd(body, function(err, doc) {
                if (err) {
                    callback(err, null);
                } else {
                    callback(null, doc);
                }
            });
        });
    };
};

var jrdHandler = function(callback) {
    return function(res) {

        var body = "";

        if (res.statusCode !== 200) {
            callback(new Error("Bad response code: " + res.statusCode), null);
            return;
        }

        if (!res.headers["content-type"] || res.headers["content-type"].substr(0, 16) != "application/json") {
            callback(new Error("Bad content type: " + res.headers["content-type"]), null);
            return;
        }

        res.setEncoding('utf8');

        res.on('data', function (chunk) {
            body = body + chunk;
        });

        res.on("error", function(err) {
            callback(err, null);
        });

        res.on("end", function() {
            var jrd;
            try {
                jrd = JSON.parse(body);
                callback(null, jrd);
            } catch (err) {
                callback(err, null);
            }
        });
    };
};

var httpHostMeta = function(address, callback) {

    var options = {
        host: address,
        port: 80,
        path: "/.well-known/host-meta",
        method: "GET"
    };

    var req = http.request(options, xrdHandler(callback));

    req.on('error', function(err) {
        callback(err, null);
    });

    req.end();
};

var httpHostMetaJSON = function(address, callback) {

    var options = {
        host: address,
        port: 80,
        path: "/.well-known/host-meta.json",
        method: "GET"
    };

    var req = http.request(options, jrdHandler(callback));

    req.on('error', function(err) {
        callback(err, null);
    });

    req.end();
};

var httpsHostMeta = function(address, callback) {
    var options = {
        host: address,
        port: 443,
        path: "/.well-known/host-meta",
        method: "GET"
    };

    var req = https.request(options, xrdHandler(callback));

    req.on('error', function(err) {
        callback(err, null);
    });

    req.end();
};

var httpsHostMetaJSON = function(address, callback) {

    var options = {
        host: address,
        port: 443,
        path: "/.well-known/host-meta.json",
        method: "GET"
    };

    var req = https.request(options, jrdHandler(callback));

    req.on('error', function(err) {
        callback(err, null);
    });

    req.end();
};

var hostmeta = function(address, callback) {
    Step(
        function() {
            httpsHostMetaJSON(address, this);
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpsHostMeta(address, this);
            }
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpHostMetaJSON(address, this);
            }
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpHostMeta(address, this);
            }
        },
        callback
    );
};

var discover = function(address, callback) {
    if (address.indexOf("@") !== -1) {
        webfinger(address, callback);
    } else {
        hostmeta(address, callback);
    }
};

exports.xrd2jrd = xrd2jrd;
exports.webfinger = webfinger;
exports.hostmeta = hostmeta;
exports.discover = discover;
<commit_msg>Rearrange to handle redirects correctly<commit_after>// index.js
//
// main module for Webfinger
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var Step = require("step"),
    http = require("http"),
    https = require("https"),
    xml2js = require("xml2js"),
    url = require("url");

var xrd2jrd = function(str, callback) {
    Step(
        function() {
            var parser = new xml2js.Parser();
            parser.parseString(str, this);
        },
        function(err, doc) {
            var Link, jrd = {}, i, prop, l;
            if (err) {
                callback(err, null);
            } else {
                if (doc.hasOwnProperty("Link")) {
                    Link = doc.Link;
                    jrd.links = [];
                    if (Array.isArray(Link)) {
                        for (i = 0; i < Link.length; i++) {
                            l = {};
                            for (prop in Link[i]["@"]) {
                                if (Link[i]["@"].hasOwnProperty(prop)) {
                                    l[prop] = Link[i]["@"][prop];
                                }
                            }
                            jrd.links.push(l);
                        }
                    } else {
                        l = {};
                        for (prop in Link["@"]) {
                            if (Link["@"].hasOwnProperty(prop)) {
                                l[prop] = Link["@"][prop];
                            }
                        }
                        jrd.links.push(l);
                    }
                }
                callback(null, jrd);
            }
        }
    );
};

var webfinger = function(address, callback) {
    callback(new Error("Not yet implemented"), null);
};

var jrd = function(body, callback) {
    var result;
    try {
        result = JSON.parse(body);
        callback(null, result);
    } catch (err) {
        callback(err, null);
    }
};

var request = function(module, options, mimeType, parse, callback) {

    var req = module.request(options, function(res) {

        var body = "";

        res.setEncoding('utf8');

        res.on('data', function (chunk) {
            body = body + chunk;
        });

        res.on("error", function(err) {
            callback(err, null);
        });

        res.on("end", function() {

            if (res.statusCode > 300 && res.statusCode < 400 && res.headers.location) {

                options = url.parse(res.headers.location);
                request(((options.protocol == "https:") ? https : http), options, mimeType, parse, callback);
                return;

            } else if (res.statusCode !== 200) {
                callback(new Error("Bad response code: " + res.statusCode + ":" + body), null);
                return;

            }

            if (!res.headers["content-type"] || res.headers["content-type"].substr(0, mimeType.length) != mimeType) {
                callback(new Error("Bad content type: " + res.headers["content-type"]), null);
                return;
            }

            parse(body, callback);
        });
    });

    req.on('error', function(err) {
        callback(err, null);
    });

    req.end();
};

var httpHostMeta = function(address, callback) {

    var options = {
        host: address,
        port: 80,
        path: "/.well-known/host-meta",
        method: "GET"
    };

    request(http, options, "application/xrd+xml", xrd2jrd, callback);
};

var httpHostMetaJSON = function(address, callback) {

    var options = {
        host: address,
        port: 80,
        path: "/.well-known/host-meta.json",
        method: "GET"
    };

    request(http, options, "application/json", jrd, callback);
};

var httpsHostMeta = function(address, callback) {
    var options = {
        host: address,
        port: 443,
        path: "/.well-known/host-meta",
        method: "GET"
    };

    request(https, options, "application/xrd+xml", xrd2jrd, callback);
};

var httpsHostMetaJSON = function(address, callback) {

    var options = {
        host: address,
        port: 443,
        path: "/.well-known/host-meta.json",
        method: "GET"
    };

    request(https, options, "application/json", jrd, callback);
};

var hostmeta = function(address, callback) {
    Step(
        function() {
            httpsHostMetaJSON(address, this);
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpsHostMeta(address, this);
            }
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpHostMetaJSON(address, this);
            }
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                httpHostMeta(address, this);
            }
        },
        function(err, jrd) {
            if (!err) {
                callback(null, jrd);
            } else {
                callback(new Error("Unable to get host-meta or host-meta.json"), null);
            }
        }
    );
};

var discover = function(address, callback) {
    if (address.indexOf("@") !== -1) {
        webfinger(address, callback);
    } else {
        hostmeta(address, callback);
    }
};

exports.xrd2jrd = xrd2jrd;
exports.webfinger = webfinger;
exports.hostmeta = hostmeta;
exports.discover = discover;
<|endoftext|>


<commit_before>import validator from 'validator';
import ValidationError from './errors';

const defaultConfig = {
    validator,
    validateOnSave: false,
};

function doValidation (validator, fnName, value, options) {
    // The argument can be a boolean for argumentless validation, or an
    // array of options passed to the validator
    return typeof options === 'boolean' ?
        validator[fnName](value) === options
        : validator[fnName](value, options);
}

export default function validationPlugin (bookshelf, config = defaultConfig) {
    var Plugin = {
        validationErrors () {
            const output = {};

            function addError (propName, errorName) {
                const propertyErrors = output[propName] || [];

                propertyErrors.push(errorName);
                output[propName] = propertyErrors;
            }

            // Validate each property with the given rule arguments
            for (const propName in this.validations) {
                if (!this.validations.hasOwnProperty(propName)) {
                    return null;
                }

                const propValue = this.get(propName);
                const validations = this.validations[propName];

                for (const validation of validations) {
                    const {
                        method: fnName,
                        options = true,
                        error,
                    } = validation;

                    const isValid = doValidation(
                        validator,
                        fnName,
                        propValue,
                        options
                    );

                    if (!isValid) {
                        const errorMsg = error ? error : method;

                        addError(propName, errorMsg);
                    }
                }
            }

            // Return null if every property is valid
            return Object.keys(output).length > 0 ? output : null;
        },
    };

    if (config.validateOnSave) {
        Plugin.initialize = function initialize () {
            if (typeof this.validateOnSave === 'function') {
                this.on('saving', this.validateOnSave);
            }
        };

        Plugin.validateOnSave = function validateOnSave () {
            const errors = this.validationErrors();

            if (errors == null) {
                return null;
            }

            throw new ValidationError(errors);
        };
    }

    bookshelf.Model = bookshelf.Model.extend(Plugin);
}
<commit_msg>Cover multiple argument types in the validator function.<commit_after>import validator from 'validator';
import ValidationError from './errors';

const defaultConfig = {
    validator,
    validateOnSave: false,
};

function doValidation (validator, fnName, value, args) {
    // The argument can be a boolean for argumentless validation,
    // a single argument or object, or an array of argument values
    if (typeof args === 'boolean') {
        return validator[fnName](value) === args;
    }

    if (!Array.isArray(args)) {
        return validator[fnName](value, args);
    }

    return validator[fnName](value, ...args);
}

export default function validationPlugin (bookshelf, config = defaultConfig) {
    var Plugin = {
        validationErrors () {
            const output = {};

            function addError (propName, errorName) {
                const propertyErrors = output[propName] || [];

                propertyErrors.push(errorName);
                output[propName] = propertyErrors;
            }

            // Validate each property with the given rule arguments
            for (const propName in this.validations) {
                if (!this.validations.hasOwnProperty(propName)) {
                    return null;
                }

                const propValue = this.get(propName);
                const validations = this.validations[propName];

                for (const validation of validations) {
                    const {
                        method: fnName,
                        args = true,
                        error,
                    } = validation;

                    const isValid = doValidation(
                        validator,
                        fnName,
                        propValue,
                        args
                    );

                    if (!isValid) {
                        const errorMsg = error ? error : method;

                        addError(propName, errorMsg);
                    }
                }
            }

            // Return null if every property is valid
            return Object.keys(output).length > 0 ? output : null;
        },
    };

    if (config.validateOnSave) {
        Plugin.initialize = function initialize () {
            if (typeof this.validateOnSave === 'function') {
                this.on('saving', this.validateOnSave);
            }
        };

        Plugin.validateOnSave = function validateOnSave () {
            const errors = this.validationErrors();

            if (errors == null) {
                return null;
            }

            throw new ValidationError(errors);
        };
    }

    bookshelf.Model = bookshelf.Model.extend(Plugin);
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Image, TextInput, TouchableWithoutFeedback, View } from 'react-native';

import PropTypes from 'prop-types';

import Flags from './resources/flags';
import PhoneNumber from './phoneNumber';
import styles from './styles';
import CountryPicker from './countryPicker';

export default class PhoneInput extends Component {
  constructor(props, context) {
    super(props, context);

    this.onChangePhoneNumber = this.onChangePhoneNumber.bind(this);
    this.onPressFlag = this.onPressFlag.bind(this);
    this.selectCountry = this.selectCountry.bind(this);
    this.getFlag = this.getFlag.bind(this);

    const iso2 = this.props.initialCountry;
    const countryData = PhoneNumber.getCountryDataByCode(iso2);

    this.state = {
      iso2,
      formattedNumber: countryData ? `+${countryData.dialCode}` : '',
      value: null,
    };
  }

  componentWillMount() {
    if (this.props.value) this.updateFlagAndFormatNumber(this.props.value);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.value !== this.state.value) {
      this.setState({ value: nextProps.value });
      this.updateFlagAndFormatNumber(nextProps.value);
    }
  }

  onChangePhoneNumber(number) {
    const actionAfterSetState = this.props.onChangePhoneNumber
      ? () => {
        this.props.onChangePhoneNumber(number);
      }
      : null;
    this.updateFlagAndFormatNumber(number, actionAfterSetState);
  }

  onPressFlag() {
    if (this.props.onPressFlag) this.props.onPressFlag();
    else {
      if (this.state.iso2) this.picker.selectCountry(this.state.iso2);
      this.picker.show();
    }
  }

  getPickerData() {
    return PhoneNumber.getAllCountries().map((country, index) => ({
      key: index,
      image: Flags.get(country.iso2),
      label: country.name,
      dialCode: `+${country.dialCode}`,
      iso2: country.iso2,
    }));
  }

  getCountryCode() {
    const countryData = PhoneNumber.getCountryDataByCode(this.state.iso2);
    return countryData.dialCode;
  }

  getAllCountries() {
    return PhoneNumber.getAllCountries();
  }

  getFlag(iso2) {
    return Flags.get(iso2);
  }

  getDialCode() {
    return PhoneNumber.getDialCode(this.state.formattedNumber);
  }

  getValue() {
    return this.state.formattedNumber;
  }

  getNumberType() {
    return PhoneNumber.getNumberType(this.state.formattedNumber, this.state.iso2);
  }

  selectCountry(iso2) {
    if (this.state.iso2 !== iso2) {
      const countryData = PhoneNumber.getCountryDataByCode(iso2);
      if (countryData) {
        this.setState(
          {
            iso2,
            formattedNumber: `+${countryData.dialCode}`,
          },
          () => {
            if (this.props.onSelectCountry) this.props.onSelectCountry(iso2);
          },
        );
      }
    }
  }

  isValidNumber() {
    return PhoneNumber.isValidNumber(this.state.formattedNumber, this.state.iso2);
  }

  updateFlagAndFormatNumber(number, actionAfterSetState = null) {
    console.log('====================================');
    console.log('+ updateFlagAndFormatNumber');

    let iso2 = this.props.initialCountry || 'us';
    let phoneNumber = number;

    console.log('iso2:', iso2);

    if (number) {
      if (phoneNumber[0] !== '+') phoneNumber = `+${phoneNumber}`;
      phoneNumber = this.possiblyEliminateZeroAfterCountryCode(phoneNumber);
      iso2 = PhoneNumber.getCountryCodeOfNumber(phoneNumber);
    }
    this.setState({ iso2, formattedNumber: phoneNumber }, actionAfterSetState);

    console.log('Fixing flag bug:', {
      iso2,
      number,
      formattedNumber: phoneNumber,
      initialCountry: this.props.initialCountry,
    });

    console.log('- updateFlagAndFormatNumber');
    console.log('====================================');
  }

  possiblyEliminateZeroAfterCountryCode(number) {
    const dialCode = PhoneNumber.getDialCode(number);
    return number.startsWith(`${dialCode}0`)
      ? dialCode + number.substr(dialCode.length + 1)
      : number;
  }

  focus() {
    this.inputPhone.focus();
  }

  render() {
    const TextComponent = this.props.textComponent || TextInput;
    return (
      <View style={[styles.container, this.props.style]}>
        <TouchableWithoutFeedback onPress={this.onPressFlag}>
          <Image
            source={Flags.get(this.state.iso2)}
            style={[styles.flag, this.props.flagStyle]}
            onPress={this.onPressFlag}
          />
        </TouchableWithoutFeedback>
        <View style={{ flex: 1, marginLeft: this.props.offset || 10 }}>
          <TextComponent
            ref={(ref) => {
              this.inputPhone = ref;
            }}
            autoCorrect={false}
            style={[styles.text, this.props.textStyle]}
            onChangeText={(text) => { this.onChangePhoneNumber(text); console.log('number changed to:', text); }}
            keyboardType="phone-pad"
            underlineColorAndroid="rgba(0,0,0,0)"
            value={this.state.formattedNumber}
            {...this.props.textProps}
          />
        </View>

        <CountryPicker
          ref={(ref) => {
            this.picker = ref;
          }}
          selectedCountry={this.state.iso2}
          onSubmit={this.selectCountry}
          buttonColor={this.props.pickerButtonColor}
          buttonTextStyle={this.props.pickerButtonTextStyle}
          itemStyle={this.props.itemStyle}
          cancelText={this.props.cancelText}
          cancelTextStyle={this.props.cancelTextStyle}
          confirmText={this.props.confirmText}
          confirmTextStyle={this.props.confirmTextStyle}
          pickerBackgroundColor={this.props.pickerBackgroundColor}
          itemStyle={this.props.pickerItemStyle}
        />
      </View>
    );
  }
}

PhoneInput.propTypes = {
  textComponent: PropTypes.func,
  initialCountry: PropTypes.string,
  onChangePhoneNumber: PropTypes.func,
  value: PropTypes.string,
  style: PropTypes.object,
  flagStyle: PropTypes.object,
  textStyle: PropTypes.object,
  offset: PropTypes.number,
  textProps: PropTypes.object,
  onSelectCountry: PropTypes.func,
  pickerButtonColor: PropTypes.string,
  pickerBackgroundColor: PropTypes.string,
  pickerItemStyle: PropTypes.object,
  cancelText: PropTypes.string,
  cancelTextStyle: PropTypes.object,
  confirmText: PropTypes.string,
  confirmTextTextStyle: PropTypes.object,
};
<commit_msg>Fix flag disappearance bug<commit_after>import React, { Component } from 'react';
import { Image, TextInput, TouchableWithoutFeedback, View } from 'react-native';

import PropTypes from 'prop-types';

import Flags from './resources/flags';
import PhoneNumber from './phoneNumber';
import styles from './styles';
import CountryPicker from './countryPicker';

export default class PhoneInput extends Component {
  constructor(props, context) {
    super(props, context);

    this.onChangePhoneNumber = this.onChangePhoneNumber.bind(this);
    this.onPressFlag = this.onPressFlag.bind(this);
    this.selectCountry = this.selectCountry.bind(this);
    this.getFlag = this.getFlag.bind(this);

    const iso2 = this.props.initialCountry;
    const countryData = PhoneNumber.getCountryDataByCode(iso2);

    this.state = {
      iso2,
      formattedNumber: countryData ? `+${countryData.dialCode}` : '',
      value: null,
    };
  }

  componentWillMount() {
    if (this.props.value) this.updateFlagAndFormatNumber(this.props.value);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.value !== this.state.value) {
      this.setState({ value: nextProps.value });
      this.updateFlagAndFormatNumber(nextProps.value);
    }
  }

  onChangePhoneNumber(number) {
    const actionAfterSetState = this.props.onChangePhoneNumber
      ? () => {
        this.props.onChangePhoneNumber(number);
      }
      : null;
    this.updateFlagAndFormatNumber(number, actionAfterSetState);
  }

  onPressFlag() {
    if (this.props.onPressFlag) this.props.onPressFlag();
    else {
      if (this.state.iso2) this.picker.selectCountry(this.state.iso2);
      this.picker.show();
    }
  }

  getPickerData() {
    return PhoneNumber.getAllCountries().map((country, index) => ({
      key: index,
      image: Flags.get(country.iso2),
      label: country.name,
      dialCode: `+${country.dialCode}`,
      iso2: country.iso2,
    }));
  }

  getCountryCode() {
    const countryData = PhoneNumber.getCountryDataByCode(this.state.iso2);
    return countryData.dialCode;
  }

  getAllCountries() {
    return PhoneNumber.getAllCountries();
  }

  getFlag(iso2) {
    return Flags.get(iso2);
  }

  getDialCode() {
    return PhoneNumber.getDialCode(this.state.formattedNumber);
  }

  getValue() {
    return this.state.formattedNumber;
  }

  getNumberType() {
    return PhoneNumber.getNumberType(this.state.formattedNumber, this.state.iso2);
  }

  selectCountry(iso2) {
    if (this.state.iso2 !== iso2) {
      const countryData = PhoneNumber.getCountryDataByCode(iso2);
      if (countryData) {
        this.setState(
          {
            iso2,
            formattedNumber: `+${countryData.dialCode}`,
          },
          () => {
            if (this.props.onSelectCountry) this.props.onSelectCountry(iso2);
          },
        );
      }
    }
  }

  isValidNumber() {
    return PhoneNumber.isValidNumber(this.state.formattedNumber, this.state.iso2);
  }

  updateFlagAndFormatNumber(number, actionAfterSetState = null) {
    let iso2 = this.props.initialCountry || 'us';
    let phoneNumber = number;

    if (number) {
      if (phoneNumber[0] !== '+') phoneNumber = `+${phoneNumber}`;
      phoneNumber = this.possiblyEliminateZeroAfterCountryCode(phoneNumber);
      iso2 = PhoneNumber.getCountryCodeOfNumber(phoneNumber);
    }
    this.setState({ iso2, formattedNumber: phoneNumber }, actionAfterSetState);
  }

  possiblyEliminateZeroAfterCountryCode(number) {
    const dialCode = PhoneNumber.getDialCode(number);
    return number.startsWith(`${dialCode}0`)
      ? dialCode + number.substr(dialCode.length + 1)
      : number;
  }

  focus() {
    this.inputPhone.focus();
  }

  render() {
    const TextComponent = this.props.textComponent || TextInput;
    return (
      <View style={[styles.container, this.props.style]}>
        <TouchableWithoutFeedback onPress={this.onPressFlag}>
          <Image
            source={Flags.get(this.state.iso2)}
            style={[styles.flag, this.props.flagStyle]}
            onPress={this.onPressFlag}
          />
        </TouchableWithoutFeedback>
        <View style={{ flex: 1, marginLeft: this.props.offset || 10 }}>
          <TextComponent
            ref={(ref) => {
              this.inputPhone = ref;
            }}
            autoCorrect={false}
            style={[styles.text, this.props.textStyle]}
            onChangeText={(text) => { this.onChangePhoneNumber(text); }}
            keyboardType="phone-pad"
            underlineColorAndroid="rgba(0,0,0,0)"
            value={this.state.formattedNumber}
            {...this.props.textProps}
          />
        </View>

        <CountryPicker
          ref={(ref) => {
            this.picker = ref;
          }}
          selectedCountry={this.state.iso2}
          onSubmit={this.selectCountry}
          buttonColor={this.props.pickerButtonColor}
          buttonTextStyle={this.props.pickerButtonTextStyle}
          itemStyle={this.props.itemStyle}
          cancelText={this.props.cancelText}
          cancelTextStyle={this.props.cancelTextStyle}
          confirmText={this.props.confirmText}
          confirmTextStyle={this.props.confirmTextStyle}
          pickerBackgroundColor={this.props.pickerBackgroundColor}
          itemStyle={this.props.pickerItemStyle}
        />
      </View>
    );
  }
}

PhoneInput.propTypes = {
  textComponent: PropTypes.func,
  initialCountry: PropTypes.string,
  onChangePhoneNumber: PropTypes.func,
  value: PropTypes.string,
  style: PropTypes.object,
  flagStyle: PropTypes.object,
  textStyle: PropTypes.object,
  offset: PropTypes.number,
  textProps: PropTypes.object,
  onSelectCountry: PropTypes.func,
  pickerButtonColor: PropTypes.string,
  pickerBackgroundColor: PropTypes.string,
  pickerItemStyle: PropTypes.object,
  cancelText: PropTypes.string,
  cancelTextStyle: PropTypes.object,
  confirmText: PropTypes.string,
  confirmTextTextStyle: PropTypes.object,
};
<|endoftext|>


<commit_before>/**
 * @fileoverview An ESLint plugin for linting ESLint plugins
 * @author Teddy Katz
 */

'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const fs = require('fs');
const path = require('path');
const packageMetadata = require('../package');
const PLUGIN_NAME = packageMetadata.name.replace(/^eslint-plugin-/, '');
const PLUGIN_VERSION = packageMetadata.version;

const configFilters = {
  all: () => true,
  recommended: rule => rule.meta.docs.recommended,
  rules: rule => rule.meta.docs.category === 'Rules',
  tests: rule => rule.meta.docs.category === 'Tests',
  'rules-recommended': rule => configFilters.recommended(rule) && configFilters.rules(rule),
  'tests-recommended': rule => configFilters.recommended(rule) && configFilters.tests(rule),
};

// ------------------------------------------------------------------------------
// Plugin Definition
// ------------------------------------------------------------------------------

/**
 * Loads a given rule from the filesystem and generates its documentation URL
 * @param {string} ruleName The name of the rule
 * @returns {Rule} The ESLint rule to export
 */
function loadRule (ruleName) {
  const rule = require(path.join(__dirname, 'rules', ruleName));

  rule.meta.docs.url =
    `https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/tree/v${PLUGIN_VERSION}/docs/rules/${ruleName}.md`;

  return rule;
}

// import all rules in lib/rules
const allRules = fs
  .readdirSync(`${__dirname}/rules`)
  .filter(fileName => fileName.endsWith('.js') && /^[^._]/.test(fileName))
  .map(fileName => fileName.replace(/\.js$/, ''))
  .reduce((rules, ruleName) => Object.assign(rules, { [ruleName]: loadRule(ruleName) }), {});

module.exports.rules = allRules;

module.exports.configs = Object.keys(configFilters).reduce((configs, configName) => {
  return Object.assign(configs, {
    [configName]: {
      plugins: ['eslint-plugin'],
      rules: Object.keys(allRules)
        .filter(ruleName => configFilters[configName](allRules[ruleName]))
        .reduce((rules, ruleName) => Object.assign(rules, { [`${PLUGIN_NAME}/${ruleName}`]: 'error' }), {}),
    },
  });
}, {});
<commit_msg>Revert "Update: add plugins: ['eslint-plugin'] in configs" (#76)<commit_after>/**
 * @fileoverview An ESLint plugin for linting ESLint plugins
 * @author Teddy Katz
 */

'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const fs = require('fs');
const path = require('path');
const packageMetadata = require('../package');
const PLUGIN_NAME = packageMetadata.name.replace(/^eslint-plugin-/, '');
const PLUGIN_VERSION = packageMetadata.version;

const configFilters = {
  all: () => true,
  recommended: rule => rule.meta.docs.recommended,
  rules: rule => rule.meta.docs.category === 'Rules',
  tests: rule => rule.meta.docs.category === 'Tests',
  'rules-recommended': rule => configFilters.recommended(rule) && configFilters.rules(rule),
  'tests-recommended': rule => configFilters.recommended(rule) && configFilters.tests(rule),
};

// ------------------------------------------------------------------------------
// Plugin Definition
// ------------------------------------------------------------------------------

/**
 * Loads a given rule from the filesystem and generates its documentation URL
 * @param {string} ruleName The name of the rule
 * @returns {Rule} The ESLint rule to export
 */
function loadRule (ruleName) {
  const rule = require(path.join(__dirname, 'rules', ruleName));

  rule.meta.docs.url =
    `https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/tree/v${PLUGIN_VERSION}/docs/rules/${ruleName}.md`;

  return rule;
}

// import all rules in lib/rules
const allRules = fs
  .readdirSync(`${__dirname}/rules`)
  .filter(fileName => fileName.endsWith('.js') && /^[^._]/.test(fileName))
  .map(fileName => fileName.replace(/\.js$/, ''))
  .reduce((rules, ruleName) => Object.assign(rules, { [ruleName]: loadRule(ruleName) }), {});

module.exports.rules = allRules;

module.exports.configs = Object.keys(configFilters).reduce((configs, configName) => {
  return Object.assign(configs, {
    [configName]: {
      rules: Object.keys(allRules)
        .filter(ruleName => configFilters[configName](allRules[ruleName]))
        .reduce((rules, ruleName) => Object.assign(rules, { [`${PLUGIN_NAME}/${ruleName}`]: 'error' }), {}),
    },
  });
}, {});
<|endoftext|>


<commit_before>module.exports = {
  'tokens': require('./tokens'),
  'parser': require('./parser')
};
<commit_msg>Update wrapper to include resolver<commit_after>module.exports = {
  'tokens': require('./tokens'),
  'parser': require('./parser'),
  'resolve': require('./resolve')
};
<|endoftext|>


<commit_before>describe('Filetree directive', function(){
  var $compile;
  var scope;
  var element;
  var httpBackend;
  var rootScope;
  var filesystemservice;
  var isolateScope;
  var dirs = [{
        "filepath": "/home/saurabh/dir1",
        "filename": "dir1",
        "group": "saurabh",
        "is_accessible": true,
        "perm": "-rw-rw-r--",
        "perm_string": "664",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      }, {
        "filepath": "/home/saurabh/dir2",
        "filename": "dir2",
        "group": "root",
        "is_accessible": false,
        "perm": "-rw-r--r--",
        "perm_string": "644",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      },
      {
        "filepath": "/home/saurabh/dir3",
        "filename": "dir3",
        "group": "saurabh",
        "is_accessible": true,
        "perm": "-rw-rw-r--",
        "perm_string": "664",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      }];

    var files = [{
          "filepath": "/home/saurabh/file1",
          "filename": "file1",
          "group": "saurabh",
          "is_accessible": true,
          "perm": "-rw-rw-r--",
          "perm_string": "664",
          "size": "4.0 KiB",
          "type": "dir"
        }, {
          "filepath": "/home/saurabh/file2",
          "filename": "file2",
          "group": "root",
          "is_accessible": false,
          "perm": "-rw-r--r--",
          "perm_string": "644",
          "size": "4.0 KiB",
          "type": "dir"
        }];

  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));
  beforeEach(module('oide.filesystemservice'));
  beforeEach(module('oide.templates'));
  beforeEach(module('oide.filetreedirective'));

  beforeEach(inject(function($rootScope, _$compile_, $httpBackend, FilesystemService){
    $compile = _$compile_;
    scope = $rootScope.$new();
    rootScope = $rootScope;
    httpBackend = $httpBackend;
    filesystemservice = FilesystemService;

    httpBackend.whenGET('/filebrowser/filetree/a/dir').respond(function(){
      return [200, dirs];
    });
    scope.$apply();
    var el = angular.element('

');
    element = $compile(el)(scope);
    scope.$digest();
    httpBackend.flush();

    // Get isolate scope
    isolateScope = element.isolateScope();
  }));

  describe('Filetreedirective controller tests', function(){
    it('should be initialized properly', function(){
      // Create spies
      spyOn(isolateScope, 'updateFiletree');
      spyOn(isolateScope, 'deletedFile');
      spyOn(isolateScope, 'pastedFiles');

      expect(isolateScope.leafLevel).toBe("file");
      expect(isolateScope.selectionDesc.noSelections).toBeTruthy();
      expect(isolateScope.selectionDesc.multipleSelections).not.toBeTruthy();
      expect(isolateScope.selectionDesc.dirSelected).not.toBeTruthy();
      expect(isolateScope.treeData.filetreeContents.length).toBe(3);
      // Refresh
      rootScope.$emit('refreshFiletree');
      expect(isolateScope.updateFiletree).toHaveBeenCalled();
      // Deleted File
      rootScope.$emit('deletedFile', dirs[0]);
      expect(isolateScope.deletedFile).toHaveBeenCalled();
      // Pasted File
      rootScope.$emit('pastedFiles', dirs[0].filepath);
      expect(isolateScope.pastedFiles).toHaveBeenCalled();
    });

    // These should be part of the E2E tests
    // it('should show files on expanding', function(){
    //   spyOn(isolateScope, 'getDirContents');
    //   spyOn(isolateScope, 'populatetreeContents');
    //   // Click to toggle
    //   element.find('i')['0'].click();
    //   expect(isolateScope.getDirContents).toHaveBeenCalled();
    // });

    it('should be able to get files for a folder', function(){
      spyOn(filesystemservice, 'getFiles');
      isolateScope.getDirContents(dirs[0], true);
      expect(filesystemservice.getFiles).toHaveBeenCalled();
    });

    it('should return the node given a filepath', function() {
      var node = isolateScope.getNodeFromPath('/home/saurabh/dir1', isolateScope.treeData.filetreeContents);
      // Expect node parameters to match
      expect(node.filepath).toBe('/home/saurabh/dir1');
      expect(node.filename).toBe('dir1');
      expect(node.group).toBe('saurabh');
      expect(node.is_accessible).toBeTruthy();
      expect(node.perm).toBe('-rw-rw-r--');
      expect(node.perm_string).toBe('664');
      expect(node.size).toBe('4.0 KiB');
    });

    it('should return null in case node doesnt exist', function(){
      var node = isolateScope.getNodeFromPath('/home/saurabh/dir111', isolateScope.treeData.filetreeContents);
      expect(node).not.toBeDefined();
    });

    it('should return file paths for a given directory', function(){
      httpBackend.expectGET(/\/filebrowser\/filetree\/a\/dir\?dirpath=.*/).respond(function(){
        return [200, files];
      });
      isolateScope.getDirContents(isolateScope.treeData.filetreeContents[0], true);
      httpBackend.flush();
      var node = isolateScope.getNodeFromPath(isolateScope.treeData.filetreeContents[0].filepath, isolateScope.treeData.filetreeContents);
      expect(node.children.length).toBe(2);
    });

  });

});
<commit_msg>add test to remove node from filetree<commit_after>describe('Filetree directive', function(){
  var $compile;
  var scope;
  var element;
  var httpBackend;
  var rootScope;
  var filesystemservice;
  var isolateScope;
  var dirs = [{
        "filepath": "/home/saurabh/dir1",
        "filename": "dir1",
        "group": "saurabh",
        "is_accessible": true,
        "perm": "-rw-rw-r--",
        "perm_string": "664",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      }, {
        "filepath": "/home/saurabh/dir2",
        "filename": "dir2",
        "group": "root",
        "is_accessible": false,
        "perm": "-rw-r--r--",
        "perm_string": "644",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      },
      {
        "filepath": "/home/saurabh/dir3",
        "filename": "dir3",
        "group": "saurabh",
        "is_accessible": true,
        "perm": "-rw-rw-r--",
        "perm_string": "664",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      },
      {
        "filepath": "/home/saurabh/dir4",
        "filename": "dir4",
        "group": "saurabh",
        "is_accessible": true,
        "perm": "-rw-rw-r--",
        "perm_string": "664",
        "size": "4.0 KiB",
        "type": "dir",
        "children": []
      }];

    var files = [{
          "filepath": "/home/saurabh/file1",
          "filename": "file1",
          "group": "saurabh",
          "is_accessible": true,
          "perm": "-rw-rw-r--",
          "perm_string": "664",
          "size": "4.0 KiB",
          "type": "dir"
        }, {
          "filepath": "/home/saurabh/file2",
          "filename": "file2",
          "group": "root",
          "is_accessible": false,
          "perm": "-rw-r--r--",
          "perm_string": "644",
          "size": "4.0 KiB",
          "type": "dir"
        },
        {
          "filepath": "/home/saurabh/dir4/file2",
          "filename": "file2",
          "group": "root",
          "is_accessible": false,
          "perm": "-rw-r--r--",
          "perm_string": "644",
          "size": "4.0 KiB",
          "type": "dir"
        }];

  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));
  beforeEach(module('oide.filesystemservice'));
  beforeEach(module('oide.templates'));
  beforeEach(module('oide.filetreedirective'));

  beforeEach(inject(function($rootScope, _$compile_, $httpBackend, FilesystemService){
    $compile = _$compile_;
    scope = $rootScope.$new();
    rootScope = $rootScope;
    httpBackend = $httpBackend;
    filesystemservice = FilesystemService;

    httpBackend.whenGET('/filebrowser/filetree/a/dir').respond(function(){
      return [200, dirs];
    });
    scope.$apply();
    var el = angular.element('

');
    element = $compile(el)(scope);
    scope.$digest();
    httpBackend.flush();

    // Get isolate scope
    isolateScope = element.isolateScope();
  }));

  describe('Filetreedirective controller tests', function(){
    it('should be initialized properly', function(){
      // Create spies
      spyOn(isolateScope, 'updateFiletree');
      spyOn(isolateScope, 'deletedFile');
      spyOn(isolateScope, 'pastedFiles');

      expect(isolateScope.leafLevel).toBe("file");
      expect(isolateScope.selectionDesc.noSelections).toBeTruthy();
      expect(isolateScope.selectionDesc.multipleSelections).not.toBeTruthy();
      expect(isolateScope.selectionDesc.dirSelected).not.toBeTruthy();
      expect(isolateScope.treeData.filetreeContents.length).toBe(4);
      // Refresh
      rootScope.$emit('refreshFiletree');
      expect(isolateScope.updateFiletree).toHaveBeenCalled();
      // Deleted File
      rootScope.$emit('deletedFile', dirs[0]);
      expect(isolateScope.deletedFile).toHaveBeenCalled();
      // Pasted File
      rootScope.$emit('pastedFiles', dirs[0].filepath);
      expect(isolateScope.pastedFiles).toHaveBeenCalled();
    });

    // These should be part of the E2E tests
    // it('should show files on expanding', function(){
    //   spyOn(isolateScope, 'getDirContents');
    //   spyOn(isolateScope, 'populatetreeContents');
    //   // Click to toggle
    //   element.find('i')['0'].click();
    //   expect(isolateScope.getDirContents).toHaveBeenCalled();
    // });

    it('should be able to get files for a folder', function(){
      spyOn(filesystemservice, 'getFiles');
      isolateScope.getDirContents(dirs[0], true);
      expect(filesystemservice.getFiles).toHaveBeenCalled();
    });

    it('should return the node given a filepath', function() {
      var node = isolateScope.getNodeFromPath('/home/saurabh/dir1', isolateScope.treeData.filetreeContents);
      // Expect node parameters to match
      expect(node.filepath).toBe('/home/saurabh/dir1');
      expect(node.filename).toBe('dir1');
      expect(node.group).toBe('saurabh');
      expect(node.is_accessible).toBeTruthy();
      expect(node.perm).toBe('-rw-rw-r--');
      expect(node.perm_string).toBe('664');
      expect(node.size).toBe('4.0 KiB');
    });

    it('should return null in case node doesnt exist', function(){
      var node = isolateScope.getNodeFromPath('/home/saurabh/dir111', isolateScope.treeData.filetreeContents);
      expect(node).not.toBeDefined();
    });

    it('should return file paths for a given directory', function(){
      httpBackend.expectGET(/\/filebrowser\/filetree\/a\/dir\?dirpath=.*/).respond(function(){
        return [200, files];
      });
      isolateScope.getDirContents(isolateScope.treeData.filetreeContents[0], true);
      httpBackend.flush();
      var node = isolateScope.getNodeFromPath(isolateScope.treeData.filetreeContents[0].filepath, isolateScope.treeData.filetreeContents);
      expect(node.children.length).toBe(3);
    });

    it('should remove a node from the filetree', function(){
      var node = isolateScope.treeData.filetreeContents[3];
      node.children[0] = files[2];
      var childNode = node.children[0];
      isolateScope.treeData.selectedNodes = [childNode];
      isolateScope.removeNodeFromFiletree(childNode);
      expect(isolateScope.treeData.filetreeContents[3].children.length).toBe(0);
      expect(isolateScope.treeData.selectedNodes.length).toBe(0);
    });

  });

});
<|endoftext|>