<commit_before>// Generated by CoffeeScript 1.9.0
(function() {
  var $, Api, ClassificationSummary, Classifier, ClassifyPage, DecisionTree, Dialog, DrawingTask, FieldGuide, MiniTutorial, StackOfPages, SubjectViewer, User, currentConfig, loginDialog, signupDialog,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    __hasProp = {}.hasOwnProperty,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  Dialog = require('zooniverse/controllers/dialog');

  loginDialog = require('zooniverse/controllers/login-dialog');

  signupDialog = require('zooniverse/controllers/signup-dialog');

  Classifier = require('./classifier');

  MiniTutorial = require('./mini-tutorial');

  SubjectViewer = require('./subject-viewer');

  DecisionTree = require('zooniverse-decision-tree');

  ClassificationSummary = require('./classification-summary');

  DrawingTask = require('./tasks/drawing');

  FieldGuide = require('./field-guide');

  currentConfig = require('zooniverse-readymade/current-configuration');

  User = require('zooniverse/models/user');

  $ = window.jQuery;

  StackOfPages = require('stack-of-pages');

  Api = require('zooniverse/lib/api');

  ClassifyPage = (function(_super) {
    __extends(ClassifyPage, _super);

    ClassifyPage.prototype.START_TUTORIAL = "zooniverse-readymade:classifier:start_tutorial";

    ClassifyPage.prototype.targetSubjectID = '';

    ClassifyPage.prototype.workflow = 'untitled_workflow';

    ClassifyPage.prototype.tasks = null;

    ClassifyPage.prototype.firstTask = '';

    ClassifyPage.prototype.tutorial = null;

    ClassifyPage.prototype.tutorialSteps = null;

    ClassifyPage.prototype.examples = null;

    ClassifyPage.prototype.classificationsSubmitted = 0;

    ClassifyPage.prototype.loginPromptEvery = 5;

    ClassifyPage.prototype.className = Classifier.prototype.className + " readymade-classify-page";

    ClassifyPage.prototype.template = require('./templates/classify-page');

    ClassifyPage.prototype.elements = {
      '.readymade-no-more-subjects-message': 'noMoreSubjectsMessage',
      '.readymade-subject-viewer-container': 'subjectViewerContainer',
      '.readymade-decision-tree-container': 'decisionTreeContainer',
      '.readymade-summary-container': 'summaryContainer',
      '.readymade-field-guide-container': 'fieldGuideContainer'
    };

    function ClassifyPage() {
      ClassifyPage.__super__.constructor.apply(this, arguments);
      if (this.tutorialSteps != null) {
        this.tutorial = new MiniTutorial({
          steps: this.tutorialSteps
        });
        $(this.tutorial.el).on(this.tutorial.CLOSE_EVENT, function() {
          var _ref;
          return (_ref = User.current) != null ? _ref.setPreference('tutorial_done', true) : void 0;
        });
        this.el.append(this.tutorial.el);
      }
      this.subjectViewer = new SubjectViewer;
      this.subjectViewerContainer.append(this.subjectViewer.el);
      this.decisionTree = new DecisionTree({
        taskTypes: {
          radio: require('./tasks/radio'),
          checkbox: require('./tasks/checkbox'),
          button: require('./tasks/button'),
          filter: require('./tasks/filter'),
          drawing: DrawingTask
        },
        tasks: this.tasks,
        firstTask: this.firstTask || Object.keys(this.tasks)[0]
      });
      this.listenTo(this.decisionTree.el, this.decisionTree.LOAD_TASK, (function(_this) {
        return function(e) {
          _this.subjectViewer.setTool(null, null);
          return _this.subjectViewer.setTaskIndex(e.detail.index);
        };
      })(this));
      this.listenTo(this.decisionTree.el, DrawingTask.prototype.SELECT_TOOL, (function(_this) {
        return function(e) {
          return setTimeout(function() {
            var choice, tool, _ref;
            _ref = e.detail, tool = _ref.tool, choice = _ref.choice;
            return _this.subjectViewer.setTool(tool, choice);
          });
        };
      })(this));
      this.listenTo(this.decisionTree.el, this.decisionTree.COMPLETE, (function(_this) {
        return function() {
          return _this.finishSubject();
        };
      })(this));
      this.decisionTreeContainer.append(this.decisionTree.el);
      this.listenTo(this.subjectViewer.markingSurface, 'marking-surface:add-tool', (function(_this) {
        return function() {
          return _this.updateDrawingTask();
        };
      })(this));
      this.listenTo(this.subjectViewer.markingSurface, 'marking-surface:remove-tool', (function(_this) {
        return function() {
          return _this.updateDrawingTask();
        };
      })(this));
      this.summary = new ClassificationSummary;
      this.summary.on(this.summary.DISMISS, (function(_this) {
        return function() {
          return _this.getNextSubject();
        };
      })(this));
      this.summaryContainer.append(this.summary.el);
      if (this.examples != null) {
        this.fieldGuide = new FieldGuide({
          examples: this.examples
        });
        this.fieldGuideContainer.append(this.fieldGuide.el);
      }
      this.el.on(StackOfPages.prototype.activateEvent, (function(_this) {
        return function() {
          return _this.onActivate.apply(_this, arguments);
        };
      })(this));
    }

    ClassifyPage.prototype.isUserScientist = function() {
      var project, result, talkUser;
      result = new $.Deferred;
      if (User.current != null) {
        project = Api.current.get("/projects/" + Api.current.project);
        talkUser = Api.current.get("/projects/penguin/talk/users/" + User.current.name);
        $.when(project, talkUser).then((function(_this) {
          return function(project, talkUser) {
            var details, projectRoles, _ref, _ref1, _ref2, _ref3, _ref4;
            projectRoles = (_ref = (_ref1 = talkUser.talk) != null ? (_ref2 = _ref1.roles) != null ? _ref2[project.id] : void 0 : void 0) != null ? _ref : [];
            details = {
              project: project.id,
              roles: projectRoles,
              scientist: __indexOf.call(projectRoles, 'scientist') >= 0,
              admin: __indexOf.call(projectRoles, 'admin') >= 0,
              'brian-c': (_ref3 = talkUser.name) === 'brian-c' || _ref3 === 'eatyourgreens'
            };
            if (typeof console !== "undefined" && console !== null) {
              console.log('Can you pick your own subject?', JSON.stringify(details, null, 2));
            }
            return result.resolve(__indexOf.call(projectRoles, 'scientist') >= 0 || __indexOf.call(projectRoles, 'admin') >= 0 || ((_ref4 = talkUser.name) === 'brian-c' || _ref4 === 'eatyourgreens'));
          };
        })(this));
      } else {
        result.resolve(false);
      }
      return result.promise();
    };

    ClassifyPage.prototype.onActivate = function(e) {
      var _ref;
      this.targetSubjectID = e.originalEvent.detail.subjectID;
      if (this.targetSubjectID) {
        if (this.targetSubjectID !== ((_ref = this.Subject.current) != null ? _ref.zooniverse_id : void 0)) {
          return this.getNextSubject();
        }
      }
    };

    ClassifyPage.prototype.onUserChange = function(user) {
      var tutorialDone, _ref, _ref1, _ref2;
      ClassifyPage.__super__.onUserChange.apply(this, arguments);
      this.classificationsSubmitted = 0;
      if (this.tutorial != null) {
        tutorialDone = user != null ? (_ref = user.project) != null ? _ref.tutorial_done : void 0 : void 0;
        if (tutorialDone == null) {
          tutorialDone = user != null ? (_ref1 = user.preferences) != null ? (_ref2 = _ref1[currentConfig.id]) != null ? _ref2.tutorial_done : void 0 : void 0 : void 0;
        }
        if (tutorialDone) {
          if (this.tutorial.el.hasAttribute('data-open')) {
            return this.tutorial.close();
          }
        } else {
          return this.startTutorial();
        }
      }
    };

    ClassifyPage.prototype.getNextSubject = function() {
      if (this.targetSubjectID) {
        return this.isUserScientist().then((function(_this) {
          return function(theyAre) {
            var request;
            if (theyAre) {
              request = Api.current.get("/projects/" + Api.current.project + "/subjects/" + _this.targetSubjectID);
              request.then(function(data) {
                var subject;
                subject = new _this.Subject(data);
                return subject.select();
              });
              return request.fail(function() {
                return alert("There's no subject with the ID " + _this.targetSubjectID + ".");
              });
            } else {
              alert('Sorry, only science team members can choose the subjects they classify.');
              return ClassifyPage.__super__.getNextSubject.apply(_this, arguments);
            }
          };
        })(this));
      } else {
        return ClassifyPage.__super__.getNextSubject.apply(this, arguments);
      }
    };

    ClassifyPage.prototype.startTutorial = function() {
      this.tutorial.goTo(0);
      this.tutorial.open();
      return this.trigger(this.START_TUTORIAL, this, this.tutorial);
    };

    ClassifyPage.prototype.onNoMoreSubjects = function() {
      this.noMoreSubjectsMessage.show();
      this.subjectViewerContainer.hide();
      this.decisionTreeContainer.hide();
      return this.summaryContainer.hide();
    };

    ClassifyPage.prototype.createClassification = function(subject) {
      ClassifyPage.__super__.createClassification.apply(this, arguments);
      if (subject.zooniverse_id === this.targetSubjectID) {
        return this.classification.set('chosen_subject', true);
      }
    };

    ClassifyPage.prototype.loadSubject = function(subject, callback) {
      var args;
      args = arguments;
      this.noMoreSubjectsMessage.hide();
      this.subjectViewerContainer.show();
      this.decisionTreeContainer.show();
      this.summaryContainer.hide();
      this.subjectViewer.loadSubject(subject, (function(_this) {
        return function() {
          return ClassifyPage.__super__.loadSubject.apply(_this, args);
        };
      })(this));
      return this.summary.loadSubject(subject);
    };

    ClassifyPage.prototype.loadClassification = function(classification, callback) {
      var args;
      args = arguments;
      this.decisionTree.reset();
      return this.subjectViewer.loadClassification(classification, (function(_this) {
        return function() {
          return ClassifyPage.__super__.loadClassification.apply(_this, args);
        };
      })(this));
    };

    ClassifyPage.prototype.showSummary = function() {
      this.decisionTreeContainer.hide();
      this.summaryContainer.show();
      return this.targetSubjectID = '';
    };

    ClassifyPage.prototype.sendClassification = function() {
      var annotation, _i, _len, _ref;
      this.classification.set('workflow', this.workflow);
      _ref = this.composeAnnotations();
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        annotation = _ref[_i];
        this.classification.annotate(annotation);
      }
      ClassifyPage.__super__.sendClassification.apply(this, arguments);
      this.classificationsSubmitted += 1;
      if (User.current == null) {
        if (this.classificationsSubmitted % this.loginPromptEvery === 0) {
          return this.promptToLogIn();
        }
      }
    };

    ClassifyPage.prototype.composeAnnotations = function() {
      var annotations, decisionTreeValues, key, keyAndValue, value, _i, _len;
      annotations = [];
      decisionTreeValues = this.decisionTree.getValues();
      for (_i = 0, _len = decisionTreeValues.length; _i < _len; _i++) {
        keyAndValue = decisionTreeValues[_i];
        for (key in keyAndValue) {
          value = keyAndValue[key];
          annotations.push({
            key: key,
            value: value
          });
        }
      }
      return annotations;
    };

    ClassifyPage.prototype.promptToLogIn = function() {
      var prompt;
      prompt = new Dialog({
        warning: true,
        content: "You've submitted " + this.classificationsSubmitted + " classifications, but you're you're not logged in!\n
Please sign in so we can make better use of your work and give you credit when the data is published.
\n
\n  <button name=\"close-dialog\">No thanks</button>\n  <button name=\"register\">Register</button>\n  <button name=\"sign-in\">Sign in</button>\n
",
        events: $.extend({}, Dialog.prototype.events, {
          'click button[name="register"]': function() {
            this.hide();
            return signupDialog.show();
          },
          'click button[name="sign-in"]': function() {
            this.hide();
            return loginDialog.show();
          }
        }),
        hide: function() {
          Dialog.prototype.hide.call(this);
          return setTimeout(((function(_this) {
            return function() {
              return _this.destroy();
            };
          })(this)), 600);
        }
      });
      return prompt.show();
    };

    ClassifyPage.prototype.updateDrawingTask = function() {
      var mark, marks, _i, _len, _ref, _ref1;
      marks = [];
      _ref = this.subjectViewer.markingSurface.tools;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        mark = _ref[_i].mark;
        if (mark._taskIndex === this.subjectViewer.taskIndex) {
          marks.push(mark);
        }
      }
      return (_ref1 = this.decisionTree.currentTask) != null ? _ref1.reset(marks) : void 0;
    };

    ClassifyPage.prototype.events = {
      'change input[name="favorite"]': function(e) {
        return this.classification.favorite = e.target.checked;
      },
      'click button[name="restart-tutorial"]': function() {
        return this.startTutorial();
      }
    };

    return ClassifyPage;

  })(Classifier);

  module.exports = ClassifyPage;

}).call(this);
<commit_msg>build js<commit_after>// Generated by CoffeeScript 1.9.0
(function() {
  var $, Api, ClassificationSummary, Classifier, ClassifyPage, DecisionTree, Dialog, DrawingTask, FieldGuide, MiniTutorial, StackOfPages, SubjectViewer, User, currentConfig, loginDialog, signupDialog,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    __hasProp = {}.hasOwnProperty,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  Dialog = require('zooniverse/controllers/dialog');

  loginDialog = require('zooniverse/controllers/login-dialog');

  signupDialog = require('zooniverse/controllers/signup-dialog');

  Classifier = require('./classifier');

  MiniTutorial = require('./mini-tutorial');

  SubjectViewer = require('./subject-viewer');

  DecisionTree = require('zooniverse-decision-tree');

  ClassificationSummary = require('./classification-summary');

  DrawingTask = require('./tasks/drawing');

  FieldGuide = require('./field-guide');

  currentConfig = require('zooniverse-readymade/current-configuration');

  User = require('zooniverse/models/user');

  $ = window.jQuery;

  StackOfPages = require('stack-of-pages');

  Api = require('zooniverse/lib/api');

  ClassifyPage = (function(_super) {
    __extends(ClassifyPage, _super);

    ClassifyPage.prototype.START_TUTORIAL = "zooniverse-readymade:classifier:start_tutorial";

    ClassifyPage.prototype.targetSubjectID = '';

    ClassifyPage.prototype.workflow = 'untitled_workflow';

    ClassifyPage.prototype.tasks = null;

    ClassifyPage.prototype.firstTask = '';

    ClassifyPage.prototype.tutorial = null;

    ClassifyPage.prototype.tutorialSteps = null;

    ClassifyPage.prototype.examples = null;

    ClassifyPage.prototype.classificationsSubmitted = 0;

    ClassifyPage.prototype.loginPromptEvery = 5;

    ClassifyPage.prototype.className = Classifier.prototype.className + " readymade-classify-page";

    ClassifyPage.prototype.template = require('./templates/classify-page');

    ClassifyPage.prototype.elements = {
      '.readymade-no-more-subjects-message': 'noMoreSubjectsMessage',
      '.readymade-subject-viewer-container': 'subjectViewerContainer',
      '.readymade-decision-tree-container': 'decisionTreeContainer',
      '.readymade-summary-container': 'summaryContainer',
      '.readymade-field-guide-container': 'fieldGuideContainer'
    };

    function ClassifyPage() {
      ClassifyPage.__super__.constructor.apply(this, arguments);
      if (this.tutorialSteps != null) {
        this.tutorial = new MiniTutorial({
          steps: this.tutorialSteps
        });
        $(this.tutorial.el).on(this.tutorial.CLOSE_EVENT, function() {
          var _ref;
          return (_ref = User.current) != null ? _ref.setPreference('tutorial_done', true) : void 0;
        });
        this.el.append(this.tutorial.el);
      }
      this.subjectViewer = new SubjectViewer;
      this.subjectViewerContainer.append(this.subjectViewer.el);
      this.decisionTree = new DecisionTree({
        taskTypes: {
          radio: require('./tasks/radio'),
          checkbox: require('./tasks/checkbox'),
          button: require('./tasks/button'),
          filter: require('./tasks/filter'),
          drawing: DrawingTask
        },
        tasks: this.tasks,
        firstTask: this.firstTask || Object.keys(this.tasks)[0]
      });
      this.listenTo(this.decisionTree.el, this.decisionTree.LOAD_TASK, (function(_this) {
        return function(e) {
          _this.subjectViewer.setTool(null, null);
          _this.subjectViewer.setTaskIndex(e.detail.index);
          if (e.detail.task.type === 'drawing') {
            return _this.updateDrawingTask();
          }
        };
      })(this));
      this.listenTo(this.decisionTree.el, DrawingTask.prototype.SELECT_TOOL, (function(_this) {
        return function(e) {
          return setTimeout(function() {
            var choice, tool, _ref;
            _ref = e.detail, tool = _ref.tool, choice = _ref.choice;
            return _this.subjectViewer.setTool(tool, choice);
          });
        };
      })(this));
      this.listenTo(this.decisionTree.el, this.decisionTree.COMPLETE, (function(_this) {
        return function() {
          return _this.finishSubject();
        };
      })(this));
      this.decisionTreeContainer.append(this.decisionTree.el);
      this.listenTo(this.subjectViewer.markingSurface, 'marking-surface:add-tool', (function(_this) {
        return function() {
          return _this.updateDrawingTask();
        };
      })(this));
      this.listenTo(this.subjectViewer.markingSurface, 'marking-surface:remove-tool', (function(_this) {
        return function() {
          return _this.updateDrawingTask();
        };
      })(this));
      this.summary = new ClassificationSummary;
      this.summary.on(this.summary.DISMISS, (function(_this) {
        return function() {
          return _this.getNextSubject();
        };
      })(this));
      this.summaryContainer.append(this.summary.el);
      if (this.examples != null) {
        this.fieldGuide = new FieldGuide({
          examples: this.examples
        });
        this.fieldGuideContainer.append(this.fieldGuide.el);
      }
      this.el.on(StackOfPages.prototype.activateEvent, (function(_this) {
        return function() {
          return _this.onActivate.apply(_this, arguments);
        };
      })(this));
    }

    ClassifyPage.prototype.isUserScientist = function() {
      var project, result, talkUser;
      result = new $.Deferred;
      if (User.current != null) {
        project = Api.current.get("/projects/" + Api.current.project);
        talkUser = Api.current.get("/projects/penguin/talk/users/" + User.current.name);
        $.when(project, talkUser).then((function(_this) {
          return function(project, talkUser) {
            var details, projectRoles, _ref, _ref1, _ref2, _ref3, _ref4;
            projectRoles = (_ref = (_ref1 = talkUser.talk) != null ? (_ref2 = _ref1.roles) != null ? _ref2[project.id] : void 0 : void 0) != null ? _ref : [];
            details = {
              project: project.id,
              roles: projectRoles,
              scientist: __indexOf.call(projectRoles, 'scientist') >= 0,
              admin: __indexOf.call(projectRoles, 'admin') >= 0,
              'brian-c': (_ref3 = talkUser.name) === 'brian-c' || _ref3 === 'eatyourgreens'
            };
            if (typeof console !== "undefined" && console !== null) {
              console.log('Can you pick your own subject?', JSON.stringify(details, null, 2));
            }
            return result.resolve(__indexOf.call(projectRoles, 'scientist') >= 0 || __indexOf.call(projectRoles, 'admin') >= 0 || ((_ref4 = talkUser.name) === 'brian-c' || _ref4 === 'eatyourgreens'));
          };
        })(this));
      } else {
        result.resolve(false);
      }
      return result.promise();
    };

    ClassifyPage.prototype.onActivate = function(e) {
      var _ref;
      this.targetSubjectID = e.originalEvent.detail.subjectID;
      if (this.targetSubjectID) {
        if (this.targetSubjectID !== ((_ref = this.Subject.current) != null ? _ref.zooniverse_id : void 0)) {
          return this.getNextSubject();
        }
      }
    };

    ClassifyPage.prototype.onUserChange = function(user) {
      var tutorialDone, _ref, _ref1, _ref2;
      ClassifyPage.__super__.onUserChange.apply(this, arguments);
      this.classificationsSubmitted = 0;
      if (this.tutorial != null) {
        tutorialDone = user != null ? (_ref = user.project) != null ? _ref.tutorial_done : void 0 : void 0;
        if (tutorialDone == null) {
          tutorialDone = user != null ? (_ref1 = user.preferences) != null ? (_ref2 = _ref1[currentConfig.id]) != null ? _ref2.tutorial_done : void 0 : void 0 : void 0;
        }
        if (tutorialDone) {
          if (this.tutorial.el.hasAttribute('data-open')) {
            return this.tutorial.close();
          }
        } else {
          return this.startTutorial();
        }
      }
    };

    ClassifyPage.prototype.getNextSubject = function() {
      if (this.targetSubjectID) {
        return this.isUserScientist().then((function(_this) {
          return function(theyAre) {
            var request;
            if (theyAre) {
              request = Api.current.get("/projects/" + Api.current.project + "/subjects/" + _this.targetSubjectID);
              request.then(function(data) {
                var subject;
                subject = new _this.Subject(data);
                return subject.select();
              });
              return request.fail(function() {
                return alert("There's no subject with the ID " + _this.targetSubjectID + ".");
              });
            } else {
              alert('Sorry, only science team members can choose the subjects they classify.');
              return ClassifyPage.__super__.getNextSubject.apply(_this, arguments);
            }
          };
        })(this));
      } else {
        return ClassifyPage.__super__.getNextSubject.apply(this, arguments);
      }
    };

    ClassifyPage.prototype.startTutorial = function() {
      this.tutorial.goTo(0);
      this.tutorial.open();
      return this.trigger(this.START_TUTORIAL, this, this.tutorial);
    };

    ClassifyPage.prototype.onNoMoreSubjects = function() {
      this.noMoreSubjectsMessage.show();
      this.subjectViewerContainer.hide();
      this.decisionTreeContainer.hide();
      return this.summaryContainer.hide();
    };

    ClassifyPage.prototype.createClassification = function(subject) {
      ClassifyPage.__super__.createClassification.apply(this, arguments);
      if (subject.zooniverse_id === this.targetSubjectID) {
        return this.classification.set('chosen_subject', true);
      }
    };

    ClassifyPage.prototype.loadSubject = function(subject, callback) {
      var args;
      args = arguments;
      this.noMoreSubjectsMessage.hide();
      this.subjectViewerContainer.show();
      this.decisionTreeContainer.show();
      this.summaryContainer.hide();
      this.subjectViewer.loadSubject(subject, (function(_this) {
        return function() {
          return ClassifyPage.__super__.loadSubject.apply(_this, args);
        };
      })(this));
      return this.summary.loadSubject(subject);
    };

    ClassifyPage.prototype.loadClassification = function(classification, callback) {
      var args;
      args = arguments;
      this.decisionTree.reset();
      return this.subjectViewer.loadClassification(classification, (function(_this) {
        return function() {
          return ClassifyPage.__super__.loadClassification.apply(_this, args);
        };
      })(this));
    };

    ClassifyPage.prototype.showSummary = function() {
      this.decisionTreeContainer.hide();
      this.summaryContainer.show();
      return this.targetSubjectID = '';
    };

    ClassifyPage.prototype.sendClassification = function() {
      var annotation, _i, _len, _ref;
      this.classification.set('workflow', this.workflow);
      _ref = this.composeAnnotations();
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        annotation = _ref[_i];
        this.classification.annotate(annotation);
      }
      ClassifyPage.__super__.sendClassification.apply(this, arguments);
      this.classificationsSubmitted += 1;
      if (User.current == null) {
        if (this.classificationsSubmitted % this.loginPromptEvery === 0) {
          return this.promptToLogIn();
        }
      }
    };

    ClassifyPage.prototype.composeAnnotations = function() {
      var annotations, decisionTreeValues, key, keyAndValue, value, _i, _len;
      annotations = [];
      decisionTreeValues = this.decisionTree.getValues();
      for (_i = 0, _len = decisionTreeValues.length; _i < _len; _i++) {
        keyAndValue = decisionTreeValues[_i];
        for (key in keyAndValue) {
          value = keyAndValue[key];
          annotations.push({
            key: key,
            value: value
          });
        }
      }
      return annotations;
    };

    ClassifyPage.prototype.promptToLogIn = function() {
      var prompt;
      prompt = new Dialog({
        warning: true,
        content: "You've submitted " + this.classificationsSubmitted + " classifications, but you're you're not logged in!\n
Please sign in so we can make better use of your work and give you credit when the data is published.
\n
\n  <button name=\"close-dialog\">No thanks</button>\n  <button name=\"register\">Register</button>\n  <button name=\"sign-in\">Sign in</button>\n
",
        events: $.extend({}, Dialog.prototype.events, {
          'click button[name="register"]': function() {
            this.hide();
            return signupDialog.show();
          },
          'click button[name="sign-in"]': function() {
            this.hide();
            return loginDialog.show();
          }
        }),
        hide: function() {
          Dialog.prototype.hide.call(this);
          return setTimeout(((function(_this) {
            return function() {
              return _this.destroy();
            };
          })(this)), 600);
        }
      });
      return prompt.show();
    };

    ClassifyPage.prototype.updateDrawingTask = function() {
      var mark, marks, _i, _len, _ref, _ref1;
      marks = [];
      _ref = this.subjectViewer.markingSurface.tools;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        mark = _ref[_i].mark;
        if (mark._taskIndex === this.subjectViewer.taskIndex) {
          marks.push(mark);
        }
      }
      return (_ref1 = this.decisionTree.currentTask) != null ? _ref1.reset(marks) : void 0;
    };

    ClassifyPage.prototype.events = {
      'change input[name="favorite"]': function(e) {
        return this.classification.favorite = e.target.checked;
      },
      'click button[name="restart-tutorial"]': function() {
        return this.startTutorial();
      }
    };

    return ClassifyPage;

  })(Classifier);

  module.exports = ClassifyPage;

}).call(this);
<|endoftext|>


<commit_before>'use strict';

const handlebars = require('handlebars');

const packageJson = require('./package-json');

const indexFile = handlebars.compile(`import React from 'react';
import { StyleSheet, Text } from 'react-native';

const styles = StyleSheet.create({
});

export default function {{{component}}} () {
  return (
    <Text>{{{component}}}</Text>
  );
};
`);

const storyFile = handlebars.compile(`import 'react-native';
import React from 'react';
import { storiesOf } from '@storybook/react';
import {{{component}}} from './{{{packageName}}}';

storiesOf('{{{component}}}', module)
  .add('{{{component}}}', () => (
    <{{{component}}} />
  ));
`);

const testFile = handlebars.compile(`import 'react-native';
import React from 'react';
import {{{component}}} from './{{{packageName}}}';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <{{{component}}} />
  ).toJSON();

  expect(tree).to.exist;
});
`);

const packageJsonFile = (variables) =>
  JSON.stringify(packageJson(variables), null, 2);

module.exports = variables => [
  [ indexFile, variables.packageName + '.js' ],
  [ testFile, variables.packageName + '.test.js' ],
  [ storyFile, variables.packageName + '.stories.js' ],
  [ packageJsonFile, 'package.json' ],
];

<commit_msg>fix: import from @storybook/react-native<commit_after>'use strict';

const handlebars = require('handlebars');

const packageJson = require('./package-json');

const indexFile = handlebars.compile(`import React from 'react';
import { StyleSheet, Text } from 'react-native';

const styles = StyleSheet.create({
});

export default function {{{component}}} () {
  return (
    <Text>{{{component}}}</Text>
  );
};
`);

const storyFile = handlebars.compile(`import 'react-native';
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import {{{component}}} from './{{{packageName}}}';

storiesOf('{{{component}}}', module)
  .add('{{{component}}}', () => (
    <{{{component}}} />
  ));
`);

const testFile = handlebars.compile(`import 'react-native';
import React from 'react';
import {{{component}}} from './{{{packageName}}}';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <{{{component}}} />
  ).toJSON();

  expect(tree).to.exist;
});
`);

const packageJsonFile = (variables) =>
  JSON.stringify(packageJson(variables), null, 2);

module.exports = variables => [
  [ indexFile, variables.packageName + '.js' ],
  [ testFile, variables.packageName + '.test.js' ],
  [ storyFile, variables.packageName + '.stories.js' ],
  [ packageJsonFile, 'package.json' ],
];

<|endoftext|>


<commit_before>/*jshint browser: true */
/*global require, module */
'use strict';

/**
 * @fileOverview
 * Contains the ClickHandler class, which decides if a click is legitimate.
 */

var _ = require('lodash');
var Emitter = require('emitter');
var binder = require('binder');

var scrollPosition = require('./scroll_position');

/**
 * @constructor
 */
function ClickHandler(el) {
  this._emitter = new Emitter();
  this._element = el;

  _.bindAll(this,
            '_touchStartHandler',
            '_touchEndHandler',
            '_touchFinishedHandler',
            '_mousedownHandler',
            '_mouseupHandler',
            '_validatedClick');

  this._startPosition = null;
  this._endPosition = null;
  this._scrollPosition = null;

  // Max distance from the start position to be considered a click
  this._threshold = 50;

  this._touchEnabled = 'ontouchstart' in window;

  this._isBound = false;
}

/**
 * Sets where the click started so we know if it was a legit click when it ends.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchStartHandler = function(event) {
  // Reset start and end in case a click never happens
  this._startPosition = null;
  this._endPosition = null;

  this._scrollPosition = scrollPosition.get();

  this._startPosition = this._getPosition(event);
};

/**
 * When/while the click happens we determine if the click was part of a scroll.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchEndHandler = function(event) {
  // Not a legit click if they are scrolling or missed the start event
  if (this._startPosition === null || this._isScrolling()) {
    this._startPosition = null;
    return;
  }

  // Position before the click is completed.
  this._endPosition = this._getPosition(event);
};

/**
 * When the click finishes we determine if the click was a legit click.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchFinishedHandler = function(event) {
  var start = this._startPosition;
  var end = this._endPosition;

  var validated = false;

  // A touchend without touchmove. End position will never be set because a
  // touchmove never occured.
  if (event.type === 'touchend' && end === null && start) {
    end = start;
    validated = true;

  // Start and end are set, check to see if movement was within the defined
  // touch thresholds.
  } else if (start && end && this._noMove(start, end)) {
    validated = true;
  }

  // If the end moved beyond the threshold distance of start, don't count it as
  // a click
  if (validated) {
    this._validatedClick(event);
  }
};

/**
 * Sets the down position for a mouse event so we know if a click is from the
 * mouse or keyboard.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._mousedownHandler = function(event) {
  this._startPosition = this._getPosition(event);
};

/**
 * Sets the up position for a mouse event so we can animate the click at the
 * end, rather than the beginning.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._mouseupHandler = function(event) {
  this._endPosition = this._getPosition(event);
};

/**
 * Calculate the click position relative to the element clicked in.
 * @private
 * @param {object} event The triggered touchend or click event.
 */
ClickHandler.prototype._validatedClick = function(event) {
  var element = event.target || event.srcElement;

  var location = {};

  // If the start position was never set we know this was a click event using
  // the keyboard.
  if (!this._touchEnabled && this._startPosition === null) {
    location.x = 0.5;
    location.y = 0.5;

  // Touch/Mouse events
  } else if (this._touchEnabled) {
    var box = element.getBoundingClientRect();
    var scrollPos = scrollPosition.get();

    var pos = {
      top: box.top + scrollPos.top,
      left: box.left + scrollPos.left
    };

    var endPos = this._endPosition || this._startPosition;

    // Calculate the offsetX/Y inside the element
    location.x = (endPos.x - pos.left) / element.offsetWidth;
    location.y = (endPos.y - pos.top) / element.offsetHeight;

  }

  var data = {
    element: element,
    location: location
  };

  this._emitter.emit('click', data);

  // Clear start, end and scroll
  this._startPosition = null;
  this._endPosition = null;
  this._scrollPosition = null;
};

/**
 * Get the position of the event for various platforms
 */
ClickHandler.prototype._getPosition = function(event) {
   var pos = {};

  if (event.type === 'click') {
    pos.x = event.target.offsetWidth / 2;
    pos.y = event.target.offsetHeight / 2;
    return pos;

  } else if (event.targetTouches && event.targetTouches[0]) { // Touch
    pos.x = event.targetTouches[0].pageX;
    pos.y = event.targetTouches[0].pageY;
    return pos;

  } else if (event.pageX !== undefined && event.pageY !== undefined) { // Mouse
    pos.x = event.pageX;
    pos.y = event.pageY;
    return pos;

  } else { // IE 8
    pos.x = event.clientX;
    pos.y = event.clientY;
    return pos;
  }
};

/**
 * Checks to see if the scroll position changed since our mousedown/touchstart
 * @private
 * @returns {boolean} True: scrolling occured.
 */
ClickHandler.prototype._isScrolling = function() {

  var oldScroll = this._scrollPosition;
  var newScroll = scrollPosition.get();

  // If we are now scrolling this is no longer a legit click
  if (oldScroll.top !== newScroll.top || oldScroll.left !== newScroll.left) {
    return true;
  }

  return false;
};

/**
 * Calculates the distance from start to end to detect if our click is a drag.
 * @private
 * @param {object} start The first position
 * @param {object} end The last position
 * @param {string} type The event type
 * @returns {boolean} True: the start and end positions are close enough to be
 *                    considered a legit click.
 */
ClickHandler.prototype._noMove = function(start, end) {
  var p1 = Math.pow(end.x - start.x, 2);
  var p2 = Math.pow(end.y - start.y, 2);
  var distance = (Math.sqrt(p1 + p2));

  if (distance <= this._threshold) {
    return true;
  }

  return false;
};

/**
 * Registers an event listener.
 * @public
 * @param {string} event The name of the event to listen for.
 * @param {function} listener The listener function for the event.
 */
ClickHandler.prototype.on = function(event, listener) {
  if (event !== 'click' || this._isBound) {
    return;
  }

  this._emitter.on(event, listener);

    // Mouse devices
  if (!this._touchEnabled) {
    binder.on(this._element, 'mousedown', this._mousedownHandler);
    binder.on(this._element, 'mouseup', this._mouseupHandler);
    binder.on(this._element, 'click', this._validatedClick);

  // Touch devices
  } else {
    binder.on(this._element, 'touchstart', this._touchStartHandler);
    binder.on(this._element, 'touchmove', this._touchEndHandler);
    binder.on(this._element, 'touchend', this._touchFinishedHandler);
  }

  this._isBound = true;
};

/**
 * Deregisters an event listener.
 * @public
 * @param {string} event The name of the event to listen for.
 * @param {function} listener The listener function for the event.
 */
ClickHandler.prototype.off = function(event, listener) {
  if (!this._isBound) {
    return;
  }

  this._emitter.off(event, listener);

  // Mouse devices
  if (!this._touchEnabled) {
    binder.off(this._element, 'mousedown', this._mousedownHandler);
    binder.off(this._element, 'mouseup', this._mouseupHandler);
    binder.off(this._element, 'click', this._validatedClick);

  // Touch devices
  } else {
    binder.off(this._element, 'touchstart', this._touchStartHandler);
    binder.off(this._element, 'touchmove', this._touchEndHandler);
    binder.off(this._element, 'touchend', this._touchFinishedHandler);
  }

  this._isBound = false;
};

module.exports = ClickHandler;
<commit_msg>Another try<commit_after>/*jshint browser: true */
/*global require, module */
'use strict';

/**
 * @fileOverview
 * Contains the ClickHandler class, which decides if a click is legitimate.
 */

var _ = require('lodash');
var Emitter = require('emitter');
var binder = require('binder');

var scrollPosition = require('./scroll_position');

/**
 * @constructor
 */
function ClickHandler(el) {
  this._emitter = new Emitter();
  this._element = el;

  _.bindAll(this,
            '_touchStartHandler',
            '_touchEndHandler',
            '_touchFinishedHandler',
            '_mousedownHandler',
            '_mouseupHandler',
            '_validatedClick');

  this._startPosition = null;
  this._endPosition = null;
  this._scrollPosition = null;

  // Max distance from the start position to be considered a click
  this._threshold = 50;

  this._touchEnabled = 'ontouchstart' in window;

  this._isBound = false;
}

/**
 * Sets where the click started so we know if it was a legit click when it ends.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchStartHandler = function(event) {
  // Reset start and end in case a click never happens
  this._startPosition = null;
  this._endPosition = null;

  this._scrollPosition = scrollPosition.get();

  this._startPosition = this._getPosition(event);
};

/**
 * When/while the click happens we determine if the click was part of a scroll.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchEndHandler = function(event) {
  // Not a legit click if they are scrolling or missed the start event
  if (this._startPosition === null || this._isScrolling()) {
    this._startPosition = null;
    return;
  }

  // Position before the click is completed.
  this._endPosition = this._getPosition(event);
};

/**
 * When the click finishes we determine if the click was a legit click.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._touchFinishedHandler = function(event) {
  var start = this._startPosition;
  var end = this._endPosition;

  var validated = false;

  // A touchend without touchmove. End position will never be set because a
  // touchmove never occured.
  if (event.type === 'touchend' && end === null && start) {
    end = start;
    validated = true;

  // Start and end are set, check to see if movement was within the defined
  // touch thresholds.
  } else if (start && end && this._noMove(start, end)) {
    validated = true;
  }

  // If the end moved beyond the threshold distance of start, don't count it as
  // a click
  if (validated) {
    this._validatedClick(event);
  }
};

/**
 * Sets the down position for a mouse event so we know if a click is from the
 * mouse or keyboard.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._mousedownHandler = function(event) {
  this._startPosition = this._getPosition(event);
};

/**
 * Sets the up position for a mouse event so we can animate the click at the
 * end, rather than the beginning.
 * @private
 * @param {object} event The triggered event.
 */
ClickHandler.prototype._mouseupHandler = function(event) {
  this._endPosition = this._getPosition(event);
};

/**
 * Calculate the click position relative to the element clicked in.
 * @private
 * @param {object} event The triggered touchend or click event.
 */
ClickHandler.prototype._validatedClick = function(event) {
  var element = event.target || event.srcElement;

  var location = {};

  // If the start position was never set we know this was a click event using
  // the keyboard.
  if (!this._touchEnabled && this._startPosition === null) {
    location.x = 0.5;
    location.y = 0.5;

  // Touch/Mouse events
  } else {
    var box = element.getBoundingClientRect();
    var scrollPos = scrollPosition.get();

    var pos = {
      top: box.top + scrollPos.top,
      left: box.left + scrollPos.left
    };

    var endPos = this._endPosition || this._startPosition;

    // Calculate the offsetX/Y inside the element
    location.x = (endPos.x - pos.left) / element.offsetWidth;
    location.y = (endPos.y - pos.top) / element.offsetHeight;
  }

  var data = {
    element: element,
    location: location
  };

  this._emitter.emit('click', data);

  // Clear start, end and scroll
  this._startPosition = null;
  this._endPosition = null;
  this._scrollPosition = null;
};

/**
 * Get the position of the event for various platforms
 */
ClickHandler.prototype._getPosition = function(event) {
   var pos = {};

  if (event.type === 'click') {
    pos.x = event.target.offsetWidth / 2;
    pos.y = event.target.offsetHeight / 2;
    return pos;

  } else if (event.targetTouches && event.targetTouches[0]) { // Touch
    pos.x = event.targetTouches[0].pageX;
    pos.y = event.targetTouches[0].pageY;
    return pos;

  } else if (event.pageX !== undefined && event.pageY !== undefined) { // Mouse
    pos.x = event.pageX;
    pos.y = event.pageY;
    return pos;

  } else { // IE 8
    pos.x = event.clientX;
    pos.y = event.clientY;
    return pos;
  }
};

/**
 * Checks to see if the scroll position changed since our mousedown/touchstart
 * @private
 * @returns {boolean} True: scrolling occured.
 */
ClickHandler.prototype._isScrolling = function() {

  var oldScroll = this._scrollPosition;
  var newScroll = scrollPosition.get();

  // If we are now scrolling this is no longer a legit click
  if (oldScroll.top !== newScroll.top || oldScroll.left !== newScroll.left) {
    return true;
  }

  return false;
};

/**
 * Calculates the distance from start to end to detect if our click is a drag.
 * @private
 * @param {object} start The first position
 * @param {object} end The last position
 * @param {string} type The event type
 * @returns {boolean} True: the start and end positions are close enough to be
 *                    considered a legit click.
 */
ClickHandler.prototype._noMove = function(start, end) {
  var p1 = Math.pow(end.x - start.x, 2);
  var p2 = Math.pow(end.y - start.y, 2);
  var distance = (Math.sqrt(p1 + p2));

  if (distance <= this._threshold) {
    return true;
  }

  return false;
};

/**
 * Registers an event listener.
 * @public
 * @param {string} event The name of the event to listen for.
 * @param {function} listener The listener function for the event.
 */
ClickHandler.prototype.on = function(event, listener) {
  if (event !== 'click' || this._isBound) {
    return;
  }

  this._emitter.on(event, listener);

    // Mouse devices
  if (!this._touchEnabled) {
    binder.on(this._element, 'mousedown', this._mousedownHandler);
    binder.on(this._element, 'mouseup', this._mouseupHandler);
    binder.on(this._element, 'click', this._validatedClick);

  // Touch devices
  } else {
    binder.on(this._element, 'touchstart', this._touchStartHandler);
    binder.on(this._element, 'touchmove', this._touchEndHandler);
    binder.on(this._element, 'touchend', this._touchFinishedHandler);
  }

  this._isBound = true;
};

/**
 * Deregisters an event listener.
 * @public
 * @param {string} event The name of the event to listen for.
 * @param {function} listener The listener function for the event.
 */
ClickHandler.prototype.off = function(event, listener) {
  if (!this._isBound) {
    return;
  }

  this._emitter.off(event, listener);

  // Mouse devices
  if (!this._touchEnabled) {
    binder.off(this._element, 'mousedown', this._mousedownHandler);
    binder.off(this._element, 'mouseup', this._mouseupHandler);
    binder.off(this._element, 'click', this._validatedClick);

  // Touch devices
  } else {
    binder.off(this._element, 'touchstart', this._touchStartHandler);
    binder.off(this._element, 'touchmove', this._touchEndHandler);
    binder.off(this._element, 'touchend', this._touchFinishedHandler);
  }

  this._isBound = false;
};

module.exports = ClickHandler;
<|endoftext|>


<commit_before>// client.js - main client file that does most of the processing
'use strict';

var stream = require('stream'),
  fs = require('fs'),
  constants = require('crypto').constants,
  request = require('request'),
  util = require('util'),
  EventEmitter = require('events').EventEmitter,
  Client = require('./client').Client,
  qs = require('querystring'),
  async = require('async'),
  throttler = require('./throttle'),
  pjson = require('./../../package.json'),
  failCodes = {
    400: 'Bad Request',
    401: 'Not Authorized',
    403: 'Forbidden',
    404: 'Item not found',
    405: 'Method not Allowed',
    409: 'Conflict',
    422: 'Unprocessable Entity',   // zendesk sends this one back when you re-use an organization name
    429: 'Too Many Requests',
    500: 'Internal Server Error',
    503: 'Service Unavailable'
  };

// recursive flatten deep
function flatten(array) {
  var flattend = [];
  !(function flat(array) {
    array.forEach(function (el) {
      if (Array.isArray(el)) flat(el);
      else flattend.push(el);
    });
  })(array);
  return flattend;
}

Client = exports.Client = function (options) {
  this.options = options;
  this.sideLoad = [];
  this.userAgent = 'node-zendesk/' + pjson.version + ' (node/' + process.versions.node + ')';
  // Each client has its own cookies to isolate authentication between clients
  this._request = request.defaults({
    jar: this.options.get('no-cookies') ? false : request.jar(),
    encoding: this.options.get('encoding') || null,
    timeout: this.options.get('timeout') || 240000,
    proxy: this.options.get('proxy') || null,
    secureOptions: constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1,
    forever: true,
    pool: { maxSockets: 100 },
    secureProtocol: 'TLSv1_2_method',
  });

  if (!this.jsonAPINames) {
    this.jsonAPINames = [];
  }

  if ('function' !== typeof this.options.get) {
    this.options.get = function (key) {
      return this[key];
    };
  }

};

util.inherits(Client, EventEmitter);

Client.prototype.request = function (method, uri) {
  var options, url, self = this, args = Array.prototype.slice.call(arguments),
    callback = args.pop(),
    body = 'object' === typeof args[args.length - 1] && !Array.isArray(args[args.length - 1]) && args.pop(),
    auth = this.options.get('password') ? ':' + this.options.get('password') : '/token:' + this.options.get('token'),
    encoded = Buffer.from(this.options.get('username') + auth).toString('base64'),
    proxy = this.options.get('proxy'),
    useOAuth = this.options.get('oauth'),
    token = this.options.get('token'),
    asUser = this.options.get('asUser'),
    customHeaders = this.options.get('customHeaders');

  url = assembleUrl(self, uri);

  self.options.headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'User-Agent': self.userAgent,
    'Content-Length': body.length
  };

  if (asUser) {
    self.options.headers['X-On-Behalf-Of'] = asUser;
  }

  if (useOAuth) {// token is an oauth token obtained from OAuth2
    self.options.headers.Authorization = 'Bearer ' + token;
  } else {// token is an API token obtained from the Zendesk Settings UI
    self.options.headers.Authorization = 'Basic ' + encoded;
  }

  if (customHeaders) {
    self.options.headers = { ...self.options.headers, ...customHeaders };
  }

  self.options.uri = url;
  self.options.method = method || 'GET';

  if ('GET' === method) {
    self.options.body = undefined;
  } else if (body) {
    self.options.body = JSON.stringify(body);
  } else if ('GET' !== method && 'application/json' === self.options.headers['Content-Type']) {
    self.options.body = '{}';
  }

  if (proxy) {
    self.options.proxy = proxy;
  }

  self.emit('debug::request', self.options);

  return new Promise(function (resolve, reject) {
    self._request(self.options, function (err, response, result) {
      var stdCb = function (error, statusCode, body, response) {
        if (error) return reject(error);
        return resolve(body);
      };
      return requestCallback(self, err, response, result, callback || stdCb);
    });
  });
};

Client.prototype.requestAll = function (method, uri) {
  var args = Array.prototype.slice.call(arguments),
    callbackOpt = args.pop(),
    nextPage = 'Not Null!',
    count = -1,
    bodyList = [],
    statusList = [],
    responseList = [],
    resultList = [],
    self = this,
    throttle = this.options.get('throttle'),
    isIncremental = uri[0] === 'incremental',
    __request = Client.prototype.request;

  return new Promise(function (resolve, reject) {
    var errorCb, nextCb, completeCb;
    if (typeof callbackOpt === 'function') {
      errorCb = callbackOpt;
      nextCb = function () { };
      completeCb = function (sl, bl, rl, rsl) { // avoids scope collision
        callbackOpt(null, sl, bl, rl, rsl)
      };
    } else {
      callbackOpt = callbackOpt || {};
      errorCb = callbackOpt.error || reject;
      nextCb = callbackOpt.next || function () { };
      completeCb = callbackOpt.complete || function (sl, scopedBodyList, rl, rsl) { resolve(scopedBodyList); }; // avoids scope collision
    }

    if (throttle) {
      __request = throttler(self, Client.prototype.request, throttle);
    }

    function processPage(status, body, response, result) {
      if (completeCb) { // only accumulate pages if a completeCb is provided
        statusList.push(status);
        bodyList.push(body);
        responseList.push(response);
        resultList.push(result);
      }
      nextPage = result ? result.next_page : null;
      count = result ? result.count : 0;
      nextCb(status, body, response, result, nextPage);
    }

    return __request.apply(self, args.concat(function (error, status, body, response, result) {
      if (error) {
        return errorCb(error);
      }
      processPage(status, body, response, result);
      async.whilst(
        function (cb) {
          if (nextPage === null || (isIncremental && count < 1000)) {
            nextPage = '';
          }
          cb(null, nextPage);
        },
        function (cb) {
          __request.apply(self, ['GET', nextPage, function (error, status, body, response, result) {
            if (error) {
              return cb(error);
            }
            processPage(status, body, response, result);
            cb(null);
          }]);
        },
        function (err) {
          if (err) {
            return errorCb(err);
          } else if (completeCb) {
            return completeCb(statusList, flatten(bodyList), responseList, resultList);
          }
        }
      );
    }));
  });

};

Client.prototype.requestUpload = function (uri, file, callback) {
  var self = this,
    out,
    auth = this.options.get('password') ? ':' + this.options.get('password') : '/token:' + this.options.get('token'),
    encoded = Buffer.from(this.options.get('username') + auth).toString('base64'),
    useOAuth = this.options.get('oauth'),
    token = this.options.get('token'),
    uploadOptions = self.options,
    binary = uri[1] ? (uri[1].binary || file instanceof stream) : false;

  self.options.uri = assembleUrl(self, uri);
  self.options.method = 'POST';
  // Fixes ERR_STREAM_WRITE_AFTER_END after new ticket creation
  if (self.options.body) delete self.options.body

  self.options.headers = { 'Content-Type': 'application/binary' };

  if (useOAuth) {
    self.options.headers.Authorization = 'Bearer ' + token;
  } else {
    self.options.headers.Authorization = 'Basic ' + encoded;
  }

  self.emit('debug::request', self.options);

  return new Promise(function (resolve, reject) {

    var stdCallback = function (error, statusCode, body, response) {
      if (error) return reject(error);
      return resolve(body);
    };

    // assumes a binary file is passed in instead of a path
    if (binary) {
      self.options.body = file;
      return self._request(self.options, function (err, response, result) {
        if (!callback) callback = stdCallback;
        return requestCallback(self, err, response, result, callback);
      });
    } else {
      out = self._request(self.options, function (err, response, result) {
        if (!callback) callback = stdCallback;
        return requestCallback(self, err, response, result, callback);
      });
      fs.createReadStream(file).pipe(out); // pipe the file!
    }
  });
};

Client.prototype.setSideLoad = function (arr) {
  var self = this;
  self.sideLoad = arr;
}

function checkRequestResponse(self, response, result, callback) {
  var statusCode, error, retryAfter, res;

  if (!result) { // should this really be an error?
    error = new Error('Zendesk returned an empty result');
    error.statusCode = 204;
    return callback(error);
  }
  try {
    statusCode = response.statusCode;
    res = JSON.parse(result);
  }
  catch (ex) {
    // Emit Errors
    self.emit('debug::error', { exception: ex, code: statusCode, request: self.options, result: result });
  }

  self.emit('debug::response', { statusCode: statusCode, result: result });

  retryAfter = response.headers['retry-after'];
  if (retryAfter) {
    error = new Error('Zendesk rate limits 200 requests per minute');
    error.statusCode = 429;
    error.result = result;
    error.retryAfter = retryAfter;
    return callback(error);
  }

  if (failCodes[statusCode]) {
    error = new Error('Zendesk Error (' + statusCode + '): ' + failCodes[statusCode]);
    error.statusCode = statusCode;
    error.result = result;
    error.retryAfter = null;
    return callback(error);
  }

  return callback(null, res);
}

function requestCallback(self, err, response, result, callback) {
  if (err) {
    return callback(err);
  }

  checkRequestResponse(self, response, result, function (err, res) {
    if (err) {
      return callback(err);
    }
    var body = null;
    if (res) {
      if (self.jsonAPINames) {
        for (var i = 0; i < self.jsonAPINames.length; i++) {
          if (res.hasOwnProperty(self.jsonAPINames[i].toString())) {
            body = res[self.jsonAPINames[i].toString()];
            break;
          }
        }
      }

      if (!body) {
        body = res;
      }
      if (self.hasOwnProperty('sideLoadMap')) {
        body = populateFields(body, res, self.sideLoadMap);
      }
    } else {
      body = '';
    }

    return callback(null, response.statusCode, body, response, res);
  });

}

function populateFields(data, response, map) {
  if (Array.isArray(data)) {
    for (var i = 0; i < data.length; i++) {
      var record = data[i];
      populateRecord(record);
    }
  } else {
    populateRecord(data);
  }
  return data;

  function populateRecord(record) {
    for (var i = 0; i < map.length; i++) {
      var field = map[i].field;
      var name = map[i].name;
      var dataset = map[i].dataset;

      if (record.hasOwnProperty(field) && response.hasOwnProperty(dataset)) {
        //If specifying all, then put everything in response[dataset] to record[name]
        if (map[i].hasOwnProperty('all') && map[i].all === true) {
          record[name] = response[dataset];
        } else {
          var key = 'id';
          if (map[i].hasOwnProperty('dataKey')) {
            key = map[i].dataKey;
          }
          if (map[i].hasOwnProperty('array') && map[i].array) {
            record[name] = findAllRecordsById(response[dataset], key, record[field]);
          } else {
            record[name] = findOneRecordById(response[dataset], key, record[field]);
          }
        }
      }
    }
    return record;
  }
}

function findAllRecordsById(data, key, id) {
  var arr = [];
  for (var i = 0; i < data.length; i++) {
    if (data[i][key] === id) {
      arr.push(data[i]);
    }
  }
  return arr;
}

function findOneRecordById(data, key, id) {
  for (var i = 0; i < data.length; i++) {
    if (data[i][key] === id) {
      return data[i];
    }
  }
  return null;
}

function assembleUrl(self, uri) {
  var lastElement,
    params = '';

  if ('object' === typeof uri && Array.isArray(uri)) {
    lastElement = uri.pop();
    if (lastElement) {
      // we have received an object ex. {"sort_by":"id","sort_order":"desc"}
      if ('object' === typeof lastElement) {
        if (self.sideLoad.length) {
          lastElement.include = self.sideLoad.join(',');
        }
        params = '?' + qs.stringify(lastElement);
      }
      // we have received a query string ex. '?sort_by=id&sort_order=desc'
      else if (0 === lastElement.toString().indexOf('?')) {
        if (self.sideLoad.length) {
          lastElement += '&include=' + self.sideLoad.join(',');
        }
        params = lastElement;
      }
      else {
        if (self.sideLoad.length) {
          params = '?include=' + self.sideLoad.join(',');
        }
        uri.push(lastElement);
      }
    }
    return self.options.get('remoteUri') + '/' + uri.join('/') + '.json' + params;
  }
  else if ('string' === typeof uri && uri.indexOf(self.options.get('remoteUri')) === -1) {
    return self.options.get('remoteUri') + uri;
  }
  else {
    return uri;
  }
}
<commit_msg>Fixed accessing non-existent property Client of module exports inside circular dependency #281<commit_after>// client.js - main client file that does most of the processing
'use strict';

var stream = require('stream'),
  fs = require('fs'),
  constants = require('crypto').constants,
  request = require('request'),
  util = require('util'),
  EventEmitter = require('events').EventEmitter,
  qs = require('querystring'),
  async = require('async'),
  throttler = require('./throttle'),
  pjson = require('./../../package.json'),
  failCodes = {
    400: 'Bad Request',
    401: 'Not Authorized',
    403: 'Forbidden',
    404: 'Item not found',
    405: 'Method not Allowed',
    409: 'Conflict',
    422: 'Unprocessable Entity',   // zendesk sends this one back when you re-use an organization name
    429: 'Too Many Requests',
    500: 'Internal Server Error',
    503: 'Service Unavailable'
  };

// recursive flatten deep
function flatten(array) {
  var flattend = [];
  !(function flat(array) {
    array.forEach(function (el) {
      if (Array.isArray(el)) flat(el);
      else flattend.push(el);
    });
  })(array);
  return flattend;
}

var Client = exports.Client = function (options) {
  this.options = options;
  this.sideLoad = [];
  this.userAgent = 'node-zendesk/' + pjson.version + ' (node/' + process.versions.node + ')';
  // Each client has its own cookies to isolate authentication between clients
  this._request = request.defaults({
    jar: this.options.get('no-cookies') ? false : request.jar(),
    encoding: this.options.get('encoding') || null,
    timeout: this.options.get('timeout') || 240000,
    proxy: this.options.get('proxy') || null,
    secureOptions: constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1,
    forever: true,
    pool: { maxSockets: 100 },
    secureProtocol: 'TLSv1_2_method',
  });

  if (!this.jsonAPINames) {
    this.jsonAPINames = [];
  }

  if ('function' !== typeof this.options.get) {
    this.options.get = function (key) {
      return this[key];
    };
  }

};

util.inherits(Client, EventEmitter);

Client.prototype.request = function (method, uri) {
  var options, url, self = this, args = Array.prototype.slice.call(arguments),
    callback = args.pop(),
    body = 'object' === typeof args[args.length - 1] && !Array.isArray(args[args.length - 1]) && args.pop(),
    auth = this.options.get('password') ? ':' + this.options.get('password') : '/token:' + this.options.get('token'),
    encoded = Buffer.from(this.options.get('username') + auth).toString('base64'),
    proxy = this.options.get('proxy'),
    useOAuth = this.options.get('oauth'),
    token = this.options.get('token'),
    asUser = this.options.get('asUser'),
    customHeaders = this.options.get('customHeaders');

  url = assembleUrl(self, uri);

  self.options.headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'User-Agent': self.userAgent,
    'Content-Length': body.length
  };

  if (asUser) {
    self.options.headers['X-On-Behalf-Of'] = asUser;
  }

  if (useOAuth) {// token is an oauth token obtained from OAuth2
    self.options.headers.Authorization = 'Bearer ' + token;
  } else {// token is an API token obtained from the Zendesk Settings UI
    self.options.headers.Authorization = 'Basic ' + encoded;
  }

  if (customHeaders) {
    self.options.headers = { ...self.options.headers, ...customHeaders };
  }

  self.options.uri = url;
  self.options.method = method || 'GET';

  if ('GET' === method) {
    self.options.body = undefined;
  } else if (body) {
    self.options.body = JSON.stringify(body);
  } else if ('GET' !== method && 'application/json' === self.options.headers['Content-Type']) {
    self.options.body = '{}';
  }

  if (proxy) {
    self.options.proxy = proxy;
  }

  self.emit('debug::request', self.options);

  return new Promise(function (resolve, reject) {
    self._request(self.options, function (err, response, result) {
      var stdCb = function (error, statusCode, body, response) {
        if (error) return reject(error);
        return resolve(body);
      };
      return requestCallback(self, err, response, result, callback || stdCb);
    });
  });
};

Client.prototype.requestAll = function (method, uri) {
  var args = Array.prototype.slice.call(arguments),
    callbackOpt = args.pop(),
    nextPage = 'Not Null!',
    count = -1,
    bodyList = [],
    statusList = [],
    responseList = [],
    resultList = [],
    self = this,
    throttle = this.options.get('throttle'),
    isIncremental = uri[0] === 'incremental',
    __request = Client.prototype.request;

  return new Promise(function (resolve, reject) {
    var errorCb, nextCb, completeCb;
    if (typeof callbackOpt === 'function') {
      errorCb = callbackOpt;
      nextCb = function () { };
      completeCb = function (sl, bl, rl, rsl) { // avoids scope collision
        callbackOpt(null, sl, bl, rl, rsl)
      };
    } else {
      callbackOpt = callbackOpt || {};
      errorCb = callbackOpt.error || reject;
      nextCb = callbackOpt.next || function () { };
      completeCb = callbackOpt.complete || function (sl, scopedBodyList, rl, rsl) { resolve(scopedBodyList); }; // avoids scope collision
    }

    if (throttle) {
      __request = throttler(self, Client.prototype.request, throttle);
    }

    function processPage(status, body, response, result) {
      if (completeCb) { // only accumulate pages if a completeCb is provided
        statusList.push(status);
        bodyList.push(body);
        responseList.push(response);
        resultList.push(result);
      }
      nextPage = result ? result.next_page : null;
      count = result ? result.count : 0;
      nextCb(status, body, response, result, nextPage);
    }

    return __request.apply(self, args.concat(function (error, status, body, response, result) {
      if (error) {
        return errorCb(error);
      }
      processPage(status, body, response, result);
      async.whilst(
        function (cb) {
          if (nextPage === null || (isIncremental && count < 1000)) {
            nextPage = '';
          }
          cb(null, nextPage);
        },
        function (cb) {
          __request.apply(self, ['GET', nextPage, function (error, status, body, response, result) {
            if (error) {
              return cb(error);
            }
            processPage(status, body, response, result);
            cb(null);
          }]);
        },
        function (err) {
          if (err) {
            return errorCb(err);
          } else if (completeCb) {
            return completeCb(statusList, flatten(bodyList), responseList, resultList);
          }
        }
      );
    }));
  });

};

Client.prototype.requestUpload = function (uri, file, callback) {
  var self = this,
    out,
    auth = this.options.get('password') ? ':' + this.options.get('password') : '/token:' + this.options.get('token'),
    encoded = Buffer.from(this.options.get('username') + auth).toString('base64'),
    useOAuth = this.options.get('oauth'),
    token = this.options.get('token'),
    uploadOptions = self.options,
    binary = uri[1] ? (uri[1].binary || file instanceof stream) : false;

  self.options.uri = assembleUrl(self, uri);
  self.options.method = 'POST';
  // Fixes ERR_STREAM_WRITE_AFTER_END after new ticket creation
  if (self.options.body) delete self.options.body

  self.options.headers = { 'Content-Type': 'application/binary' };

  if (useOAuth) {
    self.options.headers.Authorization = 'Bearer ' + token;
  } else {
    self.options.headers.Authorization = 'Basic ' + encoded;
  }

  self.emit('debug::request', self.options);

  return new Promise(function (resolve, reject) {

    var stdCallback = function (error, statusCode, body, response) {
      if (error) return reject(error);
      return resolve(body);
    };

    // assumes a binary file is passed in instead of a path
    if (binary) {
      self.options.body = file;
      return self._request(self.options, function (err, response, result) {
        if (!callback) callback = stdCallback;
        return requestCallback(self, err, response, result, callback);
      });
    } else {
      out = self._request(self.options, function (err, response, result) {
        if (!callback) callback = stdCallback;
        return requestCallback(self, err, response, result, callback);
      });
      fs.createReadStream(file).pipe(out); // pipe the file!
    }
  });
};

Client.prototype.setSideLoad = function (arr) {
  var self = this;
  self.sideLoad = arr;
}

function checkRequestResponse(self, response, result, callback) {
  var statusCode, error, retryAfter, res;

  if (!result) { // should this really be an error?
    error = new Error('Zendesk returned an empty result');
    error.statusCode = 204;
    return callback(error);
  }
  try {
    statusCode = response.statusCode;
    res = JSON.parse(result);
  }
  catch (ex) {
    // Emit Errors
    self.emit('debug::error', { exception: ex, code: statusCode, request: self.options, result: result });
  }

  self.emit('debug::response', { statusCode: statusCode, result: result });

  retryAfter = response.headers['retry-after'];
  if (retryAfter) {
    error = new Error('Zendesk rate limits 200 requests per minute');
    error.statusCode = 429;
    error.result = result;
    error.retryAfter = retryAfter;
    return callback(error);
  }

  if (failCodes[statusCode]) {
    error = new Error('Zendesk Error (' + statusCode + '): ' + failCodes[statusCode]);
    error.statusCode = statusCode;
    error.result = result;
    error.retryAfter = null;
    return callback(error);
  }

  return callback(null, res);
}

function requestCallback(self, err, response, result, callback) {
  if (err) {
    return callback(err);
  }

  checkRequestResponse(self, response, result, function (err, res) {
    if (err) {
      return callback(err);
    }
    var body = null;
    if (res) {
      if (self.jsonAPINames) {
        for (var i = 0; i < self.jsonAPINames.length; i++) {
          if (res.hasOwnProperty(self.jsonAPINames[i].toString())) {
            body = res[self.jsonAPINames[i].toString()];
            break;
          }
        }
      }

      if (!body) {
        body = res;
      }
      if (self.hasOwnProperty('sideLoadMap')) {
        body = populateFields(body, res, self.sideLoadMap);
      }
    } else {
      body = '';
    }

    return callback(null, response.statusCode, body, response, res);
  });

}

function populateFields(data, response, map) {
  if (Array.isArray(data)) {
    for (var i = 0; i < data.length; i++) {
      var record = data[i];
      populateRecord(record);
    }
  } else {
    populateRecord(data);
  }
  return data;

  function populateRecord(record) {
    for (var i = 0; i < map.length; i++) {
      var field = map[i].field;
      var name = map[i].name;
      var dataset = map[i].dataset;

      if (record.hasOwnProperty(field) && response.hasOwnProperty(dataset)) {
        //If specifying all, then put everything in response[dataset] to record[name]
        if (map[i].hasOwnProperty('all') && map[i].all === true) {
          record[name] = response[dataset];
        } else {
          var key = 'id';
          if (map[i].hasOwnProperty('dataKey')) {
            key = map[i].dataKey;
          }
          if (map[i].hasOwnProperty('array') && map[i].array) {
            record[name] = findAllRecordsById(response[dataset], key, record[field]);
          } else {
            record[name] = findOneRecordById(response[dataset], key, record[field]);
          }
        }
      }
    }
    return record;
  }
}

function findAllRecordsById(data, key, id) {
  var arr = [];
  for (var i = 0; i < data.length; i++) {
    if (data[i][key] === id) {
      arr.push(data[i]);
    }
  }
  return arr;
}

function findOneRecordById(data, key, id) {
  for (var i = 0; i < data.length; i++) {
    if (data[i][key] === id) {
      return data[i];
    }
  }
  return null;
}

function assembleUrl(self, uri) {
  var lastElement,
    params = '';

  if ('object' === typeof uri && Array.isArray(uri)) {
    lastElement = uri.pop();
    if (lastElement) {
      // we have received an object ex. {"sort_by":"id","sort_order":"desc"}
      if ('object' === typeof lastElement) {
        if (self.sideLoad.length) {
          lastElement.include = self.sideLoad.join(',');
        }
        params = '?' + qs.stringify(lastElement);
      }
      // we have received a query string ex. '?sort_by=id&sort_order=desc'
      else if (0 === lastElement.toString().indexOf('?')) {
        if (self.sideLoad.length) {
          lastElement += '&include=' + self.sideLoad.join(',');
        }
        params = lastElement;
      }
      else {
        if (self.sideLoad.length) {
          params = '?include=' + self.sideLoad.join(',');
        }
        uri.push(lastElement);
      }
    }
    return self.options.get('remoteUri') + '/' + uri.join('/') + '.json' + params;
  }
  else if ('string' === typeof uri && uri.indexOf(self.options.get('remoteUri')) === -1) {
    return self.options.get('remoteUri') + uri;
  }
  else {
    return uri;
  }
}
<|endoftext|>


<commit_before>var CloudCommander, CloudFunc, CodeMirror;
/* object contains editors CodeMirror
 * and later will be Ace
 */
CloudCommander.Editor = {};
CloudCommander.Editor.CodeMirror = {
    load: (function(pParent){ /* function loads CodeMirror js and css files */

        /* function shows editor */
        var createEditorDiv = function(){
            if (!document.getElementById('CloudEditor')) {
                var lEditor=document.createElement('div');
                lEditor.id ='CloudEditor';
                var lFM = document.getElementById('fm');

                if(lFM){
                    lFM.appendChild(lEditor);
                }else console.log('Error. Something went wrong FM not found');

                pParent.show();
            }
        };
        /* function loads css files
         * of CodeMirror
         */
        var loadAll = function(pParent) {
            return function(){
                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/codemirror.pack.css'
                });

                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/night.pack.css'
                });

                CloudCommander.cssSet({id:'editor',
                    inner : '.CodeMirror{'                          +
                                'font-family :\'Droid Sans Mono\';' +
                                'font-size   :15px;'                +
                                'padding     :20px;'                +
                            '}'                                     +
                            '.CodeMirror-scroll{'                   +
                                'height      : 660px;'              +
                            '}'
                });

                CloudCommander.jsload('lib/client/editor/codemirror/pack/xml.pack.js',
                    createEditorDiv);
            };
        };

        /* load CodeMirror main module */
        CloudCommander.jsload('lib/client/editor/codemirror/pack/codemirror.pack.js',
            loadAll(this));
    }),

    show : (function(){ /* function shows CodeMirror editor */
            /* if CloudEditor is not loaded - loading him */
            if(!document.getElementById('CloudEditor'))
                return this.load(this);
              /* removing keyBinding if set */

            var lParent = this;
            var initCodeMirror_f = function(pValue){
                CodeMirror(lCloudEditor,{
                    mode        : 'xml',
                    value       : pValue,
                    theme       : 'night',
                    lineNumbers : true,
                    //переносим длинные строки
                    lineWrapping: false,
                    autofocus   : true,
                    extraKeys: {
                      //Сохранение
                      "Esc": lParent.hide(lParent)
                    }
                });
            };

            var lLeft           = this.getById('left');
            var lCloudEditor    = this.getById('CloudEditor');
            var lCURRENTFILE    = CloudCommander.CURRENT_FILE;

            var lCurrent        = this.getByClass(lCURRENTFILE);
            var lA;
            if(lCurrent.length){
                lCurrent = lCurrent[0];

                /* getting link */
                lA = lCurrent.getElementsByTagName('a');
                if(!lA.length)
                    return console.log('Error:' +
                        'can not find links in current file');

                lA = lA[0].href;
                /* убираем адрес хоста*/
                lA = '/' + lA.replace(document.location.href,'');

                /* checking is this link is to directory */
                var lSize = lCurrent.getElementsByClassName('size');
                if(lSize){
                    lSize = lSize[0].textContent;

                    /* if directory - load json
                     * not html data
                     */
                    if (lSize === '<dir>'){
                        if (lA.indexOf(CloudFunc.NOJS) ===
                            CloudFunc.FS.length){
                            lA = lA.replace(CloudFunc.NOJS, '');
                        }
                    }
                }
            }

            /* показываем гиф загрузки возле пути папки сверху*/
            var lLoadingImage   = CloudCommander._images.loading();
            var lErrorImage     = CloudCommander._images.error();

            lLoadingImage.className='icon loading';/* показываем загрузку*/
            lErrorImage.className='icon error hidden';/* прячем ошибку */
            /* show loading icon */
            lCurrent.firstChild.nextSibling.appendChild(lLoadingImage);

            /* reading data from current file */
            $.ajax({
                url:lA,
                 error: function(jqXHR, textStatus, errorThrown){
                    lErrorImage.className   ='icon error';
                    lErrorImage.title       = jqXHR.responseText;

                    lCurrent.firstChild.nextSibling.appendChild(lErrorImage);

                    lLoadingImage.className ='hidden';

                    console.log(jqXHR.responseText);
                 },

                 success:function(data, textStatus, jqXHR){
                    /* if we got json - show it */
                    if(typeof data === 'object')
                        data = JSON.stringify(data);

                    initCodeMirror_f(data);

                    CloudCommander.keyBinded = false;

                    lLeft   &&
                        (lLeft.className = 'panel hidden');

                    lLoadingImage.className ='hidden';
                }
            });
        }),
    hide :  (function(pParent) {
                return function(){
                    CloudCommander.keyBinded = true;

                    var lLeft           = pParent.getById('left');
                    var lCloudEditor    = pParent.getById('CloudEditor');

                    /*
                    lCloudEditor &&
                        (lCloudEditor.className  = 'hidden');
                    */
                    lLeft       &&
                        (lLeft.className         = 'panel');

                    var lCodeMirror = pParent.getByClass('CodeMirror');
                    if(lCodeMirror.length)
                        lCloudEditor
                            .removeChild(lCodeMirror[0]);
                };
            }),
    getById     : function(pId){return document.getElementById(pId);},

    getByClass  : function(pClass){
        return document.getElementsByClassName(pClass);
    },

    getPanel    : function(){
        var lCurrent = document.getElementsByClassName('current-file');
        lCurrent.length &&
            (lCurrent = lCurrent[0].parentElement);

        return lCurrent && lCurrent.id;
    }
};
CloudCommander.Editor.Keys = (function(){
    "use strict";

    /* loading js and css of CodeMirror */
    CloudCommander.Editor.CodeMirror.show(CloudCommander.Editor.CodeMirror);

    var key_event=function(event){

        /* если клавиши можно обрабатывать */
        if(CloudCommander.keyBinded){
            /* if f4 pressed */
            if(event.keyCode===115){
                CloudCommander.Editor.CodeMirror.show();
            }
        }
    };

    /* добавляем обработчик клавишь */
    if (document.addEventListener)
        document.addEventListener('keydown', key_event,false);

    else
        document.onkeypress=key_event;
});<commit_msg>added json easy beautifier<commit_after>var CloudCommander, CloudFunc, CodeMirror;
/* object contains editors CodeMirror
 * and later will be Ace
 */
CloudCommander.Editor = {};
CloudCommander.Editor.CodeMirror = {
    load: (function(pParent){ /* function loads CodeMirror js and css files */

        /* function shows editor */
        var createEditorDiv = function(){
            if (!document.getElementById('CloudEditor')) {
                var lEditor=document.createElement('div');
                lEditor.id ='CloudEditor';
                var lFM = document.getElementById('fm');

                if(lFM){
                    lFM.appendChild(lEditor);
                }else console.log('Error. Something went wrong FM not found');

                pParent.show();
            }
        };
        /* function loads css files
         * of CodeMirror
         */
        var loadAll = function(pParent) {
            return function(){
                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/codemirror.pack.css'
                });

                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/night.pack.css'
                });

                CloudCommander.cssSet({id:'editor',
                    inner : '.CodeMirror{'                          +
                                'font-family :\'Droid Sans Mono\';' +
                                'font-size   :15px;'                +
                                'padding     :20px;'                +
                            '}'                                     +
                            '.CodeMirror-scroll{'                   +
                                'height      : 660px;'              +
                            '}'
                });

                CloudCommander.jsload('lib/client/editor/codemirror/pack/xml.pack.js',
                    createEditorDiv);
            };
        };

        /* load CodeMirror main module */
        CloudCommander.jsload('lib/client/editor/codemirror/pack/codemirror.pack.js',
            loadAll(this));
    }),

    show : (function(){ /* function shows CodeMirror editor */
            /* if CloudEditor is not loaded - loading him */
            if(!document.getElementById('CloudEditor'))
                return this.load(this);
              /* removing keyBinding if set */

            var lParent = this;
            var initCodeMirror_f = function(pValue){
                CodeMirror(lCloudEditor,{
                    mode        : 'xml',
                    value       : pValue,
                    theme       : 'night',
                    lineNumbers : true,
                    //переносим длинные строки
                    lineWrapping: false,
                    autofocus   : true,
                    extraKeys: {
                      //Сохранение
                      "Esc": lParent.hide(lParent)
                    }
                });
            };

            var lLeft           = this.getById('left');
            var lCloudEditor    = this.getById('CloudEditor');
            var lCURRENTFILE    = CloudCommander.CURRENT_FILE;

            var lCurrent        = this.getByClass(lCURRENTFILE);
            var lA;
            if(lCurrent.length){
                lCurrent = lCurrent[0];

                /* getting link */
                lA = lCurrent.getElementsByTagName('a');
                if(!lA.length)
                    return console.log('Error:' +
                        'can not find links in current file');

                lA = lA[0].href;
                /* убираем адрес хоста*/
                lA = '/' + lA.replace(document.location.href,'');

                /* checking is this link is to directory */
                var lSize = lCurrent.getElementsByClassName('size');
                if(lSize){
                    lSize = lSize[0].textContent;

                    /* if directory - load json
                     * not html data
                     */
                    if (lSize === '<dir>'){
                        if (lA.indexOf(CloudFunc.NOJS) ===
                            CloudFunc.FS.length){
                            lA = lA.replace(CloudFunc.NOJS, '');
                        }
                    }
                }
            }

            /* показываем гиф загрузки возле пути папки сверху*/
            var lLoadingImage   = CloudCommander._images.loading();
            var lErrorImage     = CloudCommander._images.error();

            lLoadingImage.className='icon loading';/* показываем загрузку*/
            lErrorImage.className='icon error hidden';/* прячем ошибку */
            /* show loading icon */
            lCurrent.firstChild.nextSibling.appendChild(lLoadingImage);

            /* reading data from current file */
            $.ajax({
                url:lA,
                 error: function(jqXHR, textStatus, errorThrown){
                    lErrorImage.className   ='icon error';
                    lErrorImage.title       = jqXHR.responseText;

                    lCurrent.firstChild.nextSibling.appendChild(lErrorImage);

                    lLoadingImage.className ='hidden';

                    console.log(jqXHR.responseText);
                 },

                 success:function(data, textStatus, jqXHR){
                    /* if we got json - show it */
                    if(typeof data === 'object')
                        data = JSON.stringify(data, null, 4);

                    initCodeMirror_f(data);

                    CloudCommander.keyBinded = false;

                    lLeft   &&
                        (lLeft.className = 'panel hidden');

                    lLoadingImage.className ='hidden';
                }
            });
        }),
    hide :  (function(pParent) {
                return function(){
                    CloudCommander.keyBinded = true;

                    var lLeft           = pParent.getById('left');
                    var lCloudEditor    = pParent.getById('CloudEditor');

                    /*
                    lCloudEditor &&
                        (lCloudEditor.className  = 'hidden');
                    */
                    lLeft       &&
                        (lLeft.className         = 'panel');

                    var lCodeMirror = pParent.getByClass('CodeMirror');
                    if(lCodeMirror.length)
                        lCloudEditor
                            .removeChild(lCodeMirror[0]);
                };
            }),
    getById     : function(pId){return document.getElementById(pId);},

    getByClass  : function(pClass){
        return document.getElementsByClassName(pClass);
    },

    getPanel    : function(){
        var lCurrent = document.getElementsByClassName('current-file');
        lCurrent.length &&
            (lCurrent = lCurrent[0].parentElement);

        return lCurrent && lCurrent.id;
    }
};
CloudCommander.Editor.Keys = (function(){
    "use strict";

    /* loading js and css of CodeMirror */
    CloudCommander.Editor.CodeMirror.show(CloudCommander.Editor.CodeMirror);

    var key_event=function(event){

        /* если клавиши можно обрабатывать */
        if(CloudCommander.keyBinded){
            /* if f4 pressed */
            if(event.keyCode===115){
                CloudCommander.Editor.CodeMirror.show();
            }
        }
    };

    /* добавляем обработчик клавишь */
    if (document.addEventListener)
        document.addEventListener('keydown', key_event,false);

    else
        document.onkeypress=key_event;
});<|endoftext|>


<commit_before>var CloudCommander, CodeMirror;
/* object contains editors CodeMirror
 * and later will be Ace
 */
CloudCommander.Editor = {};
CloudCommander.Editor.CodeMirror = {
    load: (function(pParent){ /* function loads CodeMirror js and css files */

        /* function shows editor */
        var createEditorDiv = function(){
            if (!document.getElementById('CloudEditor')) {
                var lEditor=document.createElement('div');
                lEditor.id ='CloudEditor';
                var lFM = document.getElementById('fm');

                if(lFM){
                    lFM.appendChild(lEditor);
                }else console.log('Error. Something went wrong FM not found');

                pParent.show();
            }
        };
        /* function loads css files
         * of CodeMirror
         */
        var loadAll = function(pParent) {
            return function(){
                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/codemirror.pack.css'
                });

                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/night.pack.css'
                });

                CloudCommander.cssSet({id:'editor',
                    inner : '.CodeMirror{'                          +
                                'font-family:\'Droid Sans Mono\';'  +
                                'font-size:15px;'                   +
                                'resize:vertical;'                  +
                                'padding:20px;'                     +
                            '}'                                     +
                            '.CodeMirror-scroll{'                   +
                                'height: 660px;'                    +
                            '}'                                     +
                            '.CodeMirror-scrollbar{'                +
                                 'overflow-y:auto'                  +
                            '}'
                });

                CloudCommander.jsload('lib/client/editor/codemirror/pack/xml.pack.js',
                    createEditorDiv);
            };
        };

        /* load CodeMirror main module */
        CloudCommander.jsload('lib/client/editor/codemirror/pack/codemirror.pack.js', loadAll(this));
    }),

    show : (function(){ /* function shows CodeMirror editor */
            /* if CloudEditor is not loaded - loading him */
            if(!document.getElementById('CloudEditor'))
                return this.load(this);
              /* removing keyBinding if set */
            CloudCommander.keyBinded = false;

            var lLeft           = this.getById('left');
            var lCloudEditor    = this.getById('CloudEditor');

            lLeft   &&
                (lLeft.className = 'panel hidden');

            CodeMirror(lCloudEditor,{
                            mode        : "xml",
                            htmlMode    : true,
                            theme       : 'night',
                            lineNumbers : true,
                            //переносим длинные строки
                            lineWrapping: true,
                            extraKeys: {
                              //Сохранение
                              "Esc": this.hide(this)
                            }
                        });

            lCloudEditor    &&
                (lCloudEditor.className  = '');
        }),
    hide :  (function(pParent) {
                return function(){
                    CloudCommander.keyBinded = true;

                    var lLeft           = pParent.getById('left');
                    var lCloudEditor    = pParent.getById('CloudEditor');

                    lCloudEditor &&
                        (lCloudEditor.className  = 'hidden');

                    lLeft       &&
                        (lLeft.className         = 'panel');
                };
            }),
    getById: function(pId){return document.getElementById(pId);},

    getPanel: function(){
        var lCurrent = document.getElementsByClassName('current-file');
        lCurrent.length &&
            (lCurrent = lCurrent[0].parentElement);

        return lCurrent && lCurrent.id;
    }
};
CloudCommander.Editor.Keys = (function(){
    "use strict";

    /* loading js and css of CodeMirror */
    CloudCommander.Editor.CodeMirror.show(CloudCommander.Editor.CodeMirror);

    var key_event=function(event){

        /* если клавиши можно обрабатывать */
        if(CloudCommander.keyBinded){
            /* if f4 pressed */
            if(event.keyCode===115){
                CloudCommander.Editor.CodeMirror.show();
            }
        }
    };

    /* добавляем обработчик клавишь */
    if (document.addEventListener)
        document.addEventListener('keydown', key_event,false);

    else
        document.onkeypress=key_event;
});<commit_msg>minor changes<commit_after>var CloudCommander, CodeMirror;
/* object contains editors CodeMirror
 * and later will be Ace
 */
CloudCommander.Editor = {};
CloudCommander.Editor.CodeMirror = {
    load: (function(pParent){ /* function loads CodeMirror js and css files */

        /* function shows editor */
        var createEditorDiv = function(){
            if (!document.getElementById('CloudEditor')) {
                var lEditor=document.createElement('div');
                lEditor.id ='CloudEditor';
                var lFM = document.getElementById('fm');

                if(lFM){
                    lFM.appendChild(lEditor);
                }else console.log('Error. Something went wrong FM not found');

                pParent.show();
            }
        };
        /* function loads css files
         * of CodeMirror
         */
        var loadAll = function(pParent) {
            return function(){
                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/codemirror.pack.css'
                });

                CloudCommander.cssLoad({
                    src     : 'lib/client/editor/codemirror/pack/night.pack.css'
                });

                CloudCommander.cssSet({id:'editor',
                    inner : '.CodeMirror{'                          +
                                'font-family:\'Droid Sans Mono\';'  +
                                'font-size:15px;'                   +
                                'resize:vertical;'                  +
                                'padding:20px;'                     +
                            '}'                                     +
                            '.CodeMirror-scroll{'                   +
                                'height: 660px;'                    +
                            '}'                                     +
                            '.CodeMirror-scrollbar{'                +
                                 'overflow-y:auto'                  +
                            '}'
                });

                CloudCommander.jsload('lib/client/editor/codemirror/pack/xml.pack.js',
                    createEditorDiv);
            };
        };

        /* load CodeMirror main module */
        CloudCommander.jsload('lib/client/editor/codemirror/pack/codemirror.pack.js', loadAll(this));
    }),

    show : (function(){ /* function shows CodeMirror editor */
            /* if CloudEditor is not loaded - loading him */
            if(!document.getElementById('CloudEditor'))
                return this.load(this);
              /* removing keyBinding if set */
            CloudCommander.keyBinded = false;

            var lLeft           = this.getById('left');
            var lCloudEditor    = this.getById('CloudEditor');

            lLeft   &&
                (lLeft.className = 'panel hidden');

            CodeMirror(lCloudEditor,{
                            mode        : "xml",
                            htmlMode    : true,
                            theme       : 'night',
                            lineNumbers : true,
                            //переносим длинные строки
                            lineWrapping: true,
                            extraKeys: {
                              //Сохранение
                              "Esc": this.hide(this)
                            }
                        });

            lCloudEditor    &&
                (lCloudEditor.className  = '');
        }),
    hide :  (function(pParent) {
                return function(){
                    CloudCommander.keyBinded = true;

                    var lLeft           = pParent.getById('left');
                    var lCloudEditor    = pParent.getById('CloudEditor');

                    lCloudEditor &&
                        (lCloudEditor.className  = 'hidden');

                    lLeft       &&
                        (lLeft.className         = 'panel');

                    var lCodeMirror = pParent.getByClassName('CodeMirror');
                    if(lCodeMirror.length)
                        document.body.removeChild([0]);
                };
            }),
    getById: function(pId){return document.getElementById(pId);},

    getPanel: function(){
        var lCurrent = document.getElementsByClassName('current-file');
        lCurrent.length &&
            (lCurrent = lCurrent[0].parentElement);

        return lCurrent && lCurrent.id;
    }
};
CloudCommander.Editor.Keys = (function(){
    "use strict";

    /* loading js and css of CodeMirror */
    CloudCommander.Editor.CodeMirror.show(CloudCommander.Editor.CodeMirror);

    var key_event=function(event){

        /* если клавиши можно обрабатывать */
        if(CloudCommander.keyBinded){
            /* if f4 pressed */
            if(event.keyCode===115){
                CloudCommander.Editor.CodeMirror.show();
            }
        }
    };

    /* добавляем обработчик клавишь */
    if (document.addEventListener)
        document.addEventListener('keydown', key_event,false);

    else
        document.onkeypress=key_event;
});<|endoftext|>