<commit_before>SimpleUpdateField = function(selector) {
  var self = this
  /*
   * This is used internally to track what key has been
   * pressed last in complete event form.
   *
   */
  self.last_keydown_event = undefined;
  self.selector = selector
  self.current_input = function () {
    var last_clicked = $(self.selector + ' > input')
    if (last_clicked.size() == 0) {
      return null
    } else {
      return last_clicked
    }
  }
  // Given a node with text() create an input that has the nodes text as it's value
  // and record a memo about what the original-text is
  //
  var create_input_from = function(node) {

    var input_node = $("<input/>")
    var attributes = node.get(0).attributes
    for(var i = attributes.length-1; i >=0; i--) {
      if(attributes[i].nodeName.indexOf('editable') == 0) {
        input_node.attr(attributes[i].nodeName, attributes[i].nodeValue)
      }
    }
    input_node.data('original-text',node.text().trim())

    input_node.val(node.text().trim())
    input_node.addClass('editable-input')
    return input_node
  }

  var begin_edit_event = function(event) {
      var clicked_node = $(this);
      var input_node = create_input_from(clicked_node);
      clicked_node.text("")
      clicked_node.append(input_node)
      install_edit_complete_notions(input_node)
      input_node.focus();
  }
  var is_rollback_changes  = function() {
    if (self.last_keydown_event) {
      if (self.last_keydown_event.keyCode == SimpleUpdateField.ESC_KEY) {
        return true
      }
    }
    return false
  }
  var is_blur_tab_redirect = function () {
    if (self.last_keydown_event) {
      if (self.last_keydown_event.keyCode == SimpleUpdateField.TAB_KEY) {
        return true
      }
      if (self.last_keydown_event.keyCode == SimpleUpdateField.ENTER_KEY) {
        return true
      }
    }
    return false
  }
  var move_to_next_sibling = function(element) {
    if(element.attr('editable-index')) {
      var next_position = parseInt(element.attr('editable-index')) +1
      var next_editable = $(selector).filter('[editable-index='+next_position+']')
      if (next_editable.size() == 0) {
        next_editable = $(selector).filter('[editable-index=1]')
      }
      next_editable.trigger('click.editable')
    }else {
      throw 'Expected to find custom attribute editable-index'
    }
  }
  var rollback_edit_event = function(event) {
    var finished_input_node = $(this)

    finished_input_node.parent().text(finished_input_node.data('original-text')) // the input we create had a memo about it's original text
    finished_input_node.remove() // remove the input field that we created such that the node is unchanged

  }
  var commit_to_remote_resource = function(input_node) {
    uri        = input_node.attr('editable-resource-uri')
    name       = input_node.attr('editable-resource-model')
    attribute  = input_node.attr('editable-resource-attribute')
    id         = input_node.attr('editable-resource-id')
    data       = {}
    data['id'] = id
    data[name] = {}
    data[name][attribute] = input_node.val().trim()
    $.ajax({url:uri,data:data,type:'PUT'})
  }

  var commit_if_changed = function(input_node) {
    if(input_node.data('original-text') != input_node.val().trim())  {
      commit_to_remote_resource(input_node)
    }
  }

  var complete_edit_event = function(event) {

    var finished_input_node = $(this)
    var parent = finished_input_node.parent();

    commit_if_changed(finished_input_node)

    // set the elements character data back to text
    parent.text(finished_input_node.val())

    // remove the input field that we created
    // such that the node is unchanged
    finished_input_node.remove()

    // If tab key was hit during the edit phase
    // we want to redirect this blur to be a
    // click on the next sibling
    if(is_blur_tab_redirect()) {
      move_to_next_sibling(parent)
    }

    // Cleanup - cross event state
    // there was no last keydown event
    self.last_keydown_event = undefined;
  }

  var install_edit_notions = function(selector) {

    $(selector).bind('click.editable',begin_edit_event)
    $(selector).bind('mouseover.editable',function() {
      $(this).addClass('editable-hover')
    })

    $(selector).bind('mouseout.editable',function() {
      $(this).removeClass('editable-hover')
    })
  }

  var install_edit_complete_notions = function (selector) {

    $(selector).bind('keydown.editable',function(e) {
      self.last_keydown_event = e
      if(is_blur_tab_redirect()) {
        $(this).trigger('blur.editable')
        return false; // manually handle tab - no event propigation
      }
      if(is_rollback_changes()) {
       $(this).trigger('rollback.editable')
       return false;
      }
      return true // allow default propigation
    })

    $(selector).bind('blur.editable',complete_edit_event)
    $(selector).bind('rollback.editable',rollback_edit_event)
  }
  var annotate_editable_with_position = function(selector) {
    $(selector).each(function(i,el) {
      $(el).attr('editable-index',i+1)
    })
  }

  var annotate_with_resource_errors = function(selector) {
    $(selector).each(function(i,el){
      if (!($(el).attr('editable-resource-uri')) ||
            $(el).attr('editable-resource-uri') == "") {
        $(el).parent().append('
expected editable-resource-uri attribute in form http://server/resource/id
')
       }
      if (!($(el).attr('editable-resource-model')) ||
            $(el).attr('editable-resource-model') == "") {
        $(el).parent().append('
expected editable-resource-model attribute in underscorized-rails form
')
       }
      if (!($(el).attr('editable-resource-attribute')) ||
            $(el).attr('editable-resource-attribute') == "") {
        $(el).parent().append('
expected editable-resource-attribute attribute in underscorized-rails form
')
       }
    })
  }

  var install = function() {
    install_edit_notions(selector)
    annotate_editable_with_position(selector)
    annotate_with_resource_errors(selector)
    $(selector).data('editable','installed')
  }()
  return self;
}
SimpleUpdateField.TAB_KEY   = 9   // tab is   #9
SimpleUpdateField.ENTER_KEY = 13  // enter is #13
SimpleUpdateField.ESC_KEY   = 27  // enter is #13
<commit_msg>bugfix -> uninstall and re-install edit complete<commit_after>//1
SimpleUpdateField = function(selector) {
  var self = this
  /*
   * This is used internally to track what key has been
   * pressed last in complete event form.
   *
   */
  self.last_keydown_event = undefined;
  self.selector = selector
  self.current_input = function () {
    var last_clicked = $(self.selector + ' > input')
    if (last_clicked.size() == 0) {
      return null
    } else {
      return last_clicked
    }
  }
  // Given a node with text() create an input that has the nodes text as it's value
  // and record a memo about what the original-text is
  //
  var create_input_from = function(node) {

    var input_node = $("<input/>")
    var attributes = node.get(0).attributes
    for(var i = attributes.length-1; i >=0; i--) {
      if(attributes[i].nodeName.indexOf('editable') == 0) {
        input_node.attr(attributes[i].nodeName, attributes[i].nodeValue)
      }
    }
    input_node.data('original-text',node.text().trim())

    input_node.val(node.text().trim())
    input_node.addClass('editable-input')
    return input_node
  }

  var begin_edit_event = function(event) {
      var clicked_node = $(this);
      var input_node = create_input_from(clicked_node);
      clicked_node.text("")
      clicked_node.append(input_node)
      install_edit_complete_notions(input_node)
      uninstall_edit_notions(clicked_node)
      input_node.focus();
  }
  var is_rollback_changes  = function() {
    if (self.last_keydown_event) {
      if (self.last_keydown_event.keyCode == SimpleUpdateField.ESC_KEY) {
        return true
      }
    }
    return false
  }
  var is_blur_tab_redirect = function () {
    if (self.last_keydown_event) {
      if (self.last_keydown_event.keyCode == SimpleUpdateField.TAB_KEY) {
        return true
      }
      if (self.last_keydown_event.keyCode == SimpleUpdateField.ENTER_KEY) {
        return true
      }
    }
    return false
  }
  var move_to_next_sibling = function(element) {
    if(element.attr('editable-index')) {
      var next_position = parseInt(element.attr('editable-index')) +1
      var next_editable = $(selector).filter('[editable-index='+next_position+']')
      if (next_editable.size() == 0) {
        next_editable = $(selector).filter('[editable-index=0]')
      }
      next_editable.trigger('click.editable')
    }else {
      throw 'Expected to find custom attribute editable-index'
    }
  }
  var commit_to_remote_resource = function(input_node) {
    uri        = input_node.attr('editable-resource-uri')
    name       = input_node.attr('editable-resource-model')
    attribute  = input_node.attr('editable-resource-attribute')
    id         = input_node.attr('editable-resource-id')
    data       = {}
    data['id'] = id
    data[name] = {}
    data[name][attribute] = input_node.val().trim()
    $.ajax({url:uri,data:data,type:'PUT'})
  }

  var commit_if_changed = function(input_node) {
    if(input_node.data('original-text') != input_node.val().trim())  {
      commit_to_remote_resource(input_node)
    }
  }

  var editable_restoration = function(element,text_value) {
    element.text(text_value)
    install_edit_notions(element)
  }

  var rollback_edit_event = function(event) {
    var finished_input_node = $(this)
    var parent = finished_input_node.parent();

    editable_restoration(parent,finished_input_node.data('original-text')) // the input we create had a memo about it's original text
  }

  var complete_edit_event = function(event) {

    var finished_input_node = $(this)
    var parent = finished_input_node.parent();

    commit_if_changed(finished_input_node)

    editable_restoration(parent,finished_input_node.val())

    // If tab key was hit during the edit phase
    // we want to redirect this blur to be a
    // click on the next sibling
    if(is_blur_tab_redirect()) {
      move_to_next_sibling(parent)
    }

    // Cleanup - cross event state
    // there was no last keydown event
    self.last_keydown_event = undefined;
  }

  var install_edit_notions = function(selector) {

    $(selector).bind('click.editable',begin_edit_event)
    $(selector).bind('mouseover.editable',function() {
      $(this).addClass('editable-hover')
    })

    $(selector).bind('mouseout.editable',function() {
      $(this).removeClass('editable-hover')
    })
  }

  var uninstall_edit_notions = function(selector) {
    $(selector).unbind('click.editable')
    $(selector).unbind('mouseover.editable')
    $(selector).unbind('mouseout.editable')
  }

  var install_edit_complete_notions = function (selector) {

    $(selector).bind('keydown.editable',function(e) {
      self.last_keydown_event = e
      if(is_blur_tab_redirect()) {
        $(this).trigger('blur.editable')
        return false; // manually handle tab - no event propigation
      }
      if(is_rollback_changes()) {
       $(this).trigger('rollback.editable')
       return false;
      }
      return true // allow default propigation
    })

    $(selector).bind('blur.editable',complete_edit_event)
    $(selector).bind('rollback.editable',rollback_edit_event)
  }
  var annotate_editable_with_position = function(selector) {
    $(selector).each(function(i,el) {
      $(el).attr('editable-index',i)
    })
  }

  var annotate_with_resource_errors = function(selector) {
    $(selector).each(function(i,el){
      if (!($(el).attr('editable-resource-uri')) ||
            $(el).attr('editable-resource-uri') == "") {
        $(el).parent().append('
expected editable-resource-uri attribute in form http://server/resource/id
')
       }
      if (!($(el).attr('editable-resource-model')) ||
            $(el).attr('editable-resource-model') == "") {
        $(el).parent().append('
expected editable-resource-model attribute in underscorized-rails form
')
       }
      if (!($(el).attr('editable-resource-attribute')) ||
            $(el).attr('editable-resource-attribute') == "") {
        $(el).parent().append('
expected editable-resource-attribute attribute in underscorized-rails form
')
       }
    })
  }

  var install = function() {
    install_edit_notions(selector)
    annotate_editable_with_position(selector)
    annotate_with_resource_errors(selector)
    $(selector).data('editable','installed')
  }()
  return self;
}
SimpleUpdateField.TAB_KEY   = 9   // tab is   #9
SimpleUpdateField.ENTER_KEY = 13  // enter is #13
SimpleUpdateField.ESC_KEY   = 27  // enter is #13
<|endoftext|>


<commit_before>/**
 * New node file
 */

var url = require('url');
var http = require("http");
var logger = require('../logger');

function callService(body, option, callback) {

	//web service endpointurl
    var parseURL = url.parse(option.url);
    var options = {
	                host: parseURL.hostname,
	                port: parseURL.port,
	                path: parseURL.path,
	                method: option.method,
					headers:{
					         'content-type':option.headers['content-type'],
					         'soapaction':option.headers['soapaction'],
					         'transfer-encoding':option.headers['transfer-encoding']
					         }
                }
    //create the http request with the soap message
	var post_req = http.request(options, function(res) {
	   					res.setEncoding('utf8');
	   					res.on('data', function (chunk) {
	       				//	console.log('Response: ' + chunk);
	       				logger.debug('EndPoint', 'Response: ' + chunk);
	       					callback(null, chunk);
	   					});
  	              });

    //error condition
    post_req.on('error', function(e) {
    	  //console.log('problem with request: ' + e.message);
    	logger.error('EndPoint', 'problem with request: ' + e.message);
    	  callback(e);
    	 });

    // post the data
	post_req.write(body);
	post_req.end();
}

exports.callService = callService;<commit_msg>deleted old version file<commit_after><|endoftext|>


<commit_before>var state = require('./state');

var default_element_name = 'element';
var template_escape = {"\\": "\\\\", "\n": "\\n", "\r": "\\r", "'": "\\'"};
var render_escape = {'&': '&', '"': '"', '<': '<', '>': '>'};

exports.state = state.state;

/**
 * Initialize the View module instance.
 *
 * @public
*/
exports.init = function () {
    var self = this;

    self._config = self._config || {};
    // set document title
    if (self._config.title) {
        document.title = self._config.title;
    }

    this.templates = {};

    // create event stream
    this._renderedDOMStream = self.flow("renderedDOM");

    // create and render the template
    if (self._config.templates) {

        var tmpl;
        self._config.defaultTemplate = self._config.defaultTemplate || Object.keys(self._config.templates)[0];

        for (var tmplKey in self._config.templates) {
            tmpl = self._config.templates[tmplKey];

            self.templates[tmplKey] = {
                'to': tmpl.to,
                'e': tmpl.dontEscape,
                'k': tmpl.leaveKeys,
                'f': default_escape_fn,
                '_elmName': tmpl.element || default_element_name,
                'element': '[data-' + (tmpl.element || default_element_name) + ']',
                'elements': {}
            };

            // add page selector to template
            if (tmpl.pages) {
                self.templates[tmplKey].pages.page = '_page_' + self._name;
            }

            // create template function
            if (engine.markup[tmpl.html]) {
                self.templates[tmplKey].render = createTemplate(engine.markup[tmpl.html]);
            }

            // auto render template
            if (tmpl.render) {
                draw.call(self, null, { template: tmplKey, data: {} });
            }
        }
    }

    // setup states
    if (self._config.states) {

        // create states cache
        self.states = {};

        // sage state in cache
        for (var stateName in self._config.states) {
            self.states[stateName] = self._config.states[stateName];
        }
    }
};

function draw (err, renderObj) {

    var self = this;
    renderObj = renderObj || {};

    // the template must exist
    var template = self.templates[renderObj.template || self._config.defaultTemplate];
    if (!template) {
        return;
    }

    var dontEscape = !!renderObj.dontEscape;
    var leaveKeys = !!renderObj.leaveKeys;
    var clearList = !!renderObj.clear;
    var insertPosition = renderObj.position || template.position || 'beforeend';

    // prepare render data
    template.data = renderObj.data;

    // render page class name
    if (template.page) {
        template.data.page = template.page;
    }

    // create html
    template.html = template.render(renderObj.data, dontEscape, leaveKeys);

    // get dom parent
    if (typeof template.to === 'string') {
        template._to = template.to;
    }
    if (typeof template._to === 'string') {
        template.to = document.querySelector(template._to);
    }

    // render html
    if (template.to) {
        if (clearList) {
            template.to.innerHTML = '';
        }

        // append dom events
        if (!self._config.flow) {
            template.to.insertAdjacentHTML(insertPosition, template.html);
        } else {
            var tmpDiv = document.createElement('div');
            tmpDiv.innerHTML = template.html;

            // TODO
            //if (template.element) {
            //    // get available elements
            //    var elements = template.to.querySelectorAll(template.element);
            //    if (elements.length) {
            //        for (var e = 0, l = elements.length; e < l; ++e) {
            //            template.elements[elements[e].dataset[template._elmName]] = elements[e];
            //        }
            //    }
            //}

            setupDomEventFlow.call(self, tmpDiv, renderObj.data);

            var children = tmpDiv.children;
            for (var i = 0, l = children.length; i < l; ++i) {
                template.to.appendChild(document.adoptNode(children[0]));
            }
        }
    }

    // write to render done stream
    self._renderedDOMStream.write(null, renderObj);
}

/**
 * Render data to the HTML template.
 *
 * @public
 * @param {object} The event object.
 * @param {object} The data object.
*/
exports.render = function (stream) {
    stream.data(draw);
};

/**
 * Escape html chars.
 *
 * @private
 * @param {object} The template object.
 * @param {object} The data object.
 * @param {string} The data key.
*/
function default_escape_fn (data, key, dont_escape_html, leaveKeys) {

    // get options
    dont_escape_html = dont_escape_html || this.e;
    leaveKeys = leaveKeys || this.k;

    // get the string value
    str = key.indexOf('.') > 0 ? engine.path(key, data) : (data[key] || null);

    // if str is null or undefined
    str = str === null ? (leaveKeys ? '{' + key + '}' : '') : str;

    // render a nested view
    if (typeof str === 'object' && this.nested && this._.view[this.nested[key]]) {
        var tmpl = this.tmpls[this.nested[key]];

        // render nested view and don't append to the dom
        tmpl.render && tmpl.render(str, dont_escape_html, leaveKeys, true);

        // get html of rendered view
        str = tmpl.html || '';

        // don't escape html chars
        dont_escape_html = true;

    // make sure str is a string
    } else {
        str += '';
    }

    // escape html chars
    if (!dont_escape_html) {
        return str.replace(/[&\"<>]/g, function(_char) {
            return render_escape[_char];
        });
    }

    return str;
}

/**
 * Create a template function.
 * Heavily inspired by the https://github.com/muut/riotjs render method.
 *
 * @private
 * @param {string} The HTML string.
*/
function createTemplate (tmpl) {
    return new Function("_", "e", "k", "_=_||{};return '" +
        (tmpl || '').replace(/[\\\n\r']/g, function(_char) {
            return template_escape[_char];
        }).replace(/{\s*([\w\.]+)\s*}/g, "' + this.f(_,'$1',e,k) + '") + "'"
    );
}

/**
 * Setup the user (DOM) event flow.
 *
 * @private
 * @param {object} The moule instnace.
*/
function setupDomEventFlow (scope, data) {

    var self = this;

    if (!self._config || !self._config.flow) {
        return;
    }

    var flows = self._config.flow;

    for (var i = 0, l = flows.length, flow, stream; i < l; ++i) {
        flow = flows[i];

        // handle element config
        if (flow.element) {
            flow.selector = "[data-element='" + flow.element + "']";
            delete flow.element;
        }

        var elms = scope.querySelectorAll(flow.selector);
        if (elms) {
            // create event stream
            stream = self.flow(flow, {
                renderData: data,
                dontPrevent: flow.dontPrevent
            });

            for (var e = 0; e < elms.length; ++e) {
                elms[e].addEventListener(flow.on, domEventListenerClosure(stream, elms, data));
            }
        }
        //}
    }
}

function domEventListenerClosure (stream, elms, data) {
    return function (event) {
        // dont prevent default browser actions
        if (!stream.dontPrevent) {
            event.preventDefault();
        }

        stream.write(null, {
            event: event,
            elms: elms,
            item: data
        });
    };
}
<commit_msg>Set the title in the draw function<commit_after>var state = require('./state');

var default_element_name = 'element';
var template_escape = {"\\": "\\\\", "\n": "\\n", "\r": "\\r", "'": "\\'"};
var render_escape = {'&': '&', '"': '"', '<': '<', '>': '>'};

exports.state = state.state;

/**
 * Initialize the View module instance.
 *
 * @public
*/
exports.init = function () {
    var self = this;

    self._config = self._config || {};

    this.templates = {};

    // create event stream
    this._renderedDOMStream = self.flow("renderedDOM");

    // create and render the template
    if (self._config.templates) {

        var tmpl;
        self._config.defaultTemplate = self._config.defaultTemplate || Object.keys(self._config.templates)[0];

        for (var tmplKey in self._config.templates) {
            tmpl = self._config.templates[tmplKey];

            self.templates[tmplKey] = {
                'to': tmpl.to,
                'e': tmpl.dontEscape,
                'k': tmpl.leaveKeys,
                'f': default_escape_fn,
                '_elmName': tmpl.element || default_element_name,
                'element': '[data-' + (tmpl.element || default_element_name) + ']',
                'elements': {}
            };

            // add page selector to template
            if (tmpl.pages) {
                self.templates[tmplKey].pages.page = '_page_' + self._name;
            }

            // create template function
            if (engine.markup[tmpl.html]) {
                self.templates[tmplKey].render = createTemplate(engine.markup[tmpl.html]);
            }

            // auto render template
            if (tmpl.render) {
                draw.call(self, null, { template: tmplKey, data: {} });
            }
        }
    }

    // setup states
    if (self._config.states) {

        // create states cache
        self.states = {};

        // sage state in cache
        for (var stateName in self._config.states) {
            self.states[stateName] = self._config.states[stateName];
        }
    }
};

function draw (err, renderObj) {

    var self = this;
    // set document title
    if (self._config.title) {
        document.title = self._config.title;
    }
    renderObj = renderObj || {};

    // the template must exist
    var template = self.templates[renderObj.template || self._config.defaultTemplate];
    if (!template) {
        return;
    }

    var dontEscape = !!renderObj.dontEscape;
    var leaveKeys = !!renderObj.leaveKeys;
    var clearList = !!renderObj.clear;
    var insertPosition = renderObj.position || template.position || 'beforeend';

    // prepare render data
    template.data = renderObj.data;

    // render page class name
    if (template.page) {
        template.data.page = template.page;
    }

    // create html
    template.html = template.render(renderObj.data, dontEscape, leaveKeys);

    // get dom parent
    if (typeof template.to === 'string') {
        template._to = template.to;
    }
    if (typeof template._to === 'string') {
        template.to = document.querySelector(template._to);
    }

    // render html
    if (template.to) {
        if (clearList) {
            template.to.innerHTML = '';
        }

        // append dom events
        if (!self._config.flow) {
            template.to.insertAdjacentHTML(insertPosition, template.html);
        } else {
            var tmpDiv = document.createElement('div');
            tmpDiv.innerHTML = template.html;

            // TODO
            //if (template.element) {
            //    // get available elements
            //    var elements = template.to.querySelectorAll(template.element);
            //    if (elements.length) {
            //        for (var e = 0, l = elements.length; e < l; ++e) {
            //            template.elements[elements[e].dataset[template._elmName]] = elements[e];
            //        }
            //    }
            //}

            setupDomEventFlow.call(self, tmpDiv, renderObj.data);

            var children = tmpDiv.children;
            for (var i = 0, l = children.length; i < l; ++i) {
                template.to.appendChild(document.adoptNode(children[0]));
            }
        }
    }

    // write to render done stream
    self._renderedDOMStream.write(null, renderObj);
}

/**
 * Render data to the HTML template.
 *
 * @public
 * @param {object} The event object.
 * @param {object} The data object.
*/
exports.render = function (stream) {
    stream.data(draw);
};

/**
 * Escape html chars.
 *
 * @private
 * @param {object} The template object.
 * @param {object} The data object.
 * @param {string} The data key.
*/
function default_escape_fn (data, key, dont_escape_html, leaveKeys) {

    // get options
    dont_escape_html = dont_escape_html || this.e;
    leaveKeys = leaveKeys || this.k;

    // get the string value
    str = key.indexOf('.') > 0 ? engine.path(key, data) : (data[key] || null);

    // if str is null or undefined
    str = str === null ? (leaveKeys ? '{' + key + '}' : '') : str;

    // render a nested view
    if (typeof str === 'object' && this.nested && this._.view[this.nested[key]]) {
        var tmpl = this.tmpls[this.nested[key]];

        // render nested view and don't append to the dom
        tmpl.render && tmpl.render(str, dont_escape_html, leaveKeys, true);

        // get html of rendered view
        str = tmpl.html || '';

        // don't escape html chars
        dont_escape_html = true;

    // make sure str is a string
    } else {
        str += '';
    }

    // escape html chars
    if (!dont_escape_html) {
        return str.replace(/[&\"<>]/g, function(_char) {
            return render_escape[_char];
        });
    }

    return str;
}

/**
 * Create a template function.
 * Heavily inspired by the https://github.com/muut/riotjs render method.
 *
 * @private
 * @param {string} The HTML string.
*/
function createTemplate (tmpl) {
    return new Function("_", "e", "k", "_=_||{};return '" +
        (tmpl || '').replace(/[\\\n\r']/g, function(_char) {
            return template_escape[_char];
        }).replace(/{\s*([\w\.]+)\s*}/g, "' + this.f(_,'$1',e,k) + '") + "'"
    );
}

/**
 * Setup the user (DOM) event flow.
 *
 * @private
 * @param {object} The moule instnace.
*/
function setupDomEventFlow (scope, data) {

    var self = this;

    if (!self._config || !self._config.flow) {
        return;
    }

    var flows = self._config.flow;

    for (var i = 0, l = flows.length, flow, stream; i < l; ++i) {
        flow = flows[i];

        // handle element config
        if (flow.element) {
            flow.selector = "[data-element='" + flow.element + "']";
            delete flow.element;
        }

        var elms = scope.querySelectorAll(flow.selector);
        if (elms) {
            // create event stream
            stream = self.flow(flow, {
                renderData: data,
                dontPrevent: flow.dontPrevent
            });

            for (var e = 0; e < elms.length; ++e) {
                elms[e].addEventListener(flow.on, domEventListenerClosure(stream, elms, data));
            }
        }
        //}
    }
}

function domEventListenerClosure (stream, elms, data) {
    return function (event) {
        // dont prevent default browser actions
        if (!stream.dontPrevent) {
            event.preventDefault();
        }

        stream.write(null, {
            event: event,
            elms: elms,
            item: data
        });
    };
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
var compressor = require('yuicompressor');
var path = require('path');

exports.compressor = function (options, blob, done) {
    options = options || {};

    compressor.compress(blob.result, options, function (err, data) {
        if (err) {
            done(err);
        } else {
            done(null, new blob.constructor(data, blob));
        }
    });
};
<commit_msg>Throttle the Compressor task so to not tax an underpowered machine<commit_after>/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
var compressor = require('yuicompressor'),
    path = require('path'),
    compressing = false,
    queue = [],
    running = 0,
    maxCompressor = 8,
    log = require('../log'),
    runQueue = function () {
        compressing = false;
        var item = queue.pop();
        if (item) {
            exports.compressor(item.options, item.blob, item.done);
        }
    };

if (process.env.SHIFTER_COMPRESSOR_TASKS) {
    if (parseInt(process.env.SHIFTER_COMPRESSOR_TASKS, 10) > 0) {
        maxCompressor = parseInt(process.env.SHIFTER_COMPRESSOR_TASKS, 10);
    }
    log.info('found env for compressor tasks, running ' + maxCompressor + ' concurrent compressor tasks');
}

exports.compressor = function (options, blob, done) {
    options = options || {};

    if (compressing && running >= maxCompressor) {
        queue.push({
            options: options,
            blob: blob,
            done: done
        });
        return;
    }

    compressing = true;
    running = running + 1;
    compressor.compress(blob.result, options, function (err, data) {
        running = running - 1;
        runQueue();
        if (err) {
            done(err);
        } else {
            done(null, new blob.constructor(data, blob));
        }
    });
};
<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';

export default function (WrappedComponent) {
  class KeyStrokeSupport extends Component {

    static propTypes = {
      cancel: PropTypes.func.isRequired,
      submit: PropTypes.func.isRequired
    };

    constructor (props) {
      super(props);
      this.handleKeyDown = this.handleKeyDown.bind(this);
    }

    componentWillMount () {
      document.addEventListener('keydown', this.handleKeyDown);
    }

    componentWillUnmount () {
      document.removeEventListener('keydown', this.handleKeyDown);
    }

    handleKeyDown (e) {
      switch (e.keyCode) {
        case 13:
          this.props.submit();
          break;
        case 27:
          this.props.cancel();
          break;
      }
    }

    render () {
      return (<WrappedComponent {...this.props}/>);
    }
  }

  return KeyStrokeSupport;
};
<commit_msg>Send events to be prevented by default<commit_after>import React, { PropTypes, Component } from 'react';

export default function (WrappedComponent) {
  class KeyStrokeSupport extends Component {

    static propTypes = {
      cancel: PropTypes.func.isRequired,
      submit: PropTypes.func.isRequired
    };

    constructor (props) {
      super(props);
      this.handleKeyDown = this.handleKeyDown.bind(this);
    }

    componentWillMount () {
      document.addEventListener('keydown', this.handleKeyDown);
    }

    componentWillUnmount () {
      document.removeEventListener('keydown', this.handleKeyDown);
    }

    handleKeyDown (e) {
      switch (e.keyCode) {
        case 13:
          this.props.submit(e);
          break;
        case 27:
          this.props.cancel(e);
          break;
      }
    }

    render () {
      return (<WrappedComponent {...this.props}/>);
    }
  }

  return KeyStrokeSupport;
};
<|endoftext|>


<commit_before>'use strict';
import config from 'config';
import url from 'url';
import request from 'request-promise';
import {
  filter,
  take,
  pluck,
  flatten,
  sortBy
}
from 'lodash';

import Bluebird from 'bluebird';
import amqp from 'amqplib';
import logger from '@hoist/logger';

class Rebalancer {
  constructor() {
    this._logger = logger.child({
      cls: this.constructor.name
    });

  }
  getChannel() {
    if (this._channel && this._channel !== 'resolving') {
      return Promise.resolve(this._channel);
    } else if (this._channel === 'resolving') {
      return Bluebird.delay(20)
        .then(() => {
          return this.getChannel();
        });

    } else {
      this._channel = 'resolving';
      return amqp.connect(config.get('Hoist.rabbit.url'), {
        heartbeat: 60
      }).then((connection) => {
        this._connection = connection;
        return connection.createChannel()
          .then((channel) => {
            this._channel = channel;
            return channel;
          });
      });
    }
  }
  getEventQueues() {
    var rabbitUrl = url.parse(config.get('Hoist.rabbit.managementurl'));
    rabbitUrl.pathname = '/api/queues';
    rabbitUrl.query = {
      'lengths_age': 120,
      'lengths_incr': 1
    };
    return request.get(url.format(rabbitUrl), {
        json: true
      })
      .then((response) => {
        return filter(response, function (queue) {
          return queue.name.endsWith('_events');
        });
      });
  }
  getDesiredExecutorCount(queue) {
    this._logger.info({
      messagesReady: queue.messages_ready
    }, 'determining executor count for queue');
    //minimum of two executors
    //maxium of 20 executors
    //one executor per 200 messages in queue otherwise
    let expectedCount = queue.consumers;
    if (queue.messages_ready === 0) {
      expectedCount = queue.consumers - 2;
    } else if (queue.messages_ready > 1000) {
      expectedCount++;
    } else {
      let messageStats = queue.messages_ready_details;

      if (messageStats) {
        if (messageStats.avg_rate > 10) {
          expectedCount += 8;
        } else if (messageStats.avg_rate > 5) {
          expectedCount += 4;
        } else if (messageStats.avg_rate > -5) {
          expectedCount += 2;
        } else if (messageStats.avg_rate < -30) {
          expectedCount -= 8;
        } else if (messageStats.avg_rate < -20) {
          expectedCount -= 4;
        } else if (messageStats.avg_rate < -5) {
          expectedCount -= 2;
        }
      } else {
        expectedCount = 2;
      }
    }
    expectedCount = Math.max(2, Math.min(20, expectedCount));
    this._logger.info({
      expectedCount, queue: queue.name
    }, 'expected consumer count');
    return expectedCount;
  };
  sendRebalanceCommands(queues) {
    this._logger.info('sending rebalance commands');
    return Promise.resolve()
      .then(() => {
        return Promise.all(queues.map((queue) => {
          return this.getConsumerStats(queue);
        }));
      })
      .then((queueStats) => {
        //we can take from these queues freely
        let overPopulatedConsumers = flatten(filter(queueStats, (queueStat) => {
          return queueStat.consumers > queueStat.expectedConsumers;
        }).map((queue) => {
          return take(sortBy(queue.consumerTags, () => {
            return Math.random();
          }), queue.consumers - queue.expectedConsumers).map((tag) => {
            return {
              consumerTag: tag,
              applicationId: queue.name.replace('_events', '')
            };
          });
        }));

        //we can take from these queues in an emergency
        let stealableQueues = flatten(filter(queueStats, (queueStat) => {
          return queueStat.consumers <= queueStat.expectedConsumers && queueStat.consumers > 1;
        }).map((queue) => {
          return take(queue.consumerTags, 1).map((tag) => {
            return {
              consumerTag: tag,
              applicationId: queue.name.replace('_events', '')
            };
          });
        }));

        let underPopulatedConsumerCount = filter(queueStats, (queueStat) => {
          return queueStat.consumers < queueStat.expectedConsumers && queueStat.consumers > 0;
        }).reduce((current, queue) => current + (queue.expectedConsumers - queue.consumers), 0);
        //we need to populate this many empty queues
        let emptyQueueCount = filter(queueStats, (queueStat) => {
          return queueStat.consumers === 0;
        }).length;
        let rebalancingCommands = [];
        if (overPopulatedConsumers.length < emptyQueueCount) {
          rebalancingCommands = overPopulatedConsumers.concat(take(stealableQueues, emptyQueueCount - overPopulatedConsumers.length));
        } else {
          rebalancingCommands = take(overPopulatedConsumers, emptyQueueCount + underPopulatedConsumerCount);
        }
        logger.info({
          rebalanceCommands: rebalancingCommands.length,
          stealableQueues: stealableQueues.length,
          emptyQueueCount,
          underPopulatedConsumerCount,
          overPopulatedConsumers
        }, 'gathered queue stats');
        if (rebalancingCommands.length > 0) {
          return this.getChannel().then((channel) => {
            return Promise.all([
              rebalancingCommands.map((rebalanceCommand) => {
                this._logger.info({
                  consumerTag: rebalanceCommand.consumerTag,
                  applicationId: rebalanceCommand.applicationId
                }, 'issuing rebalance command');
                if (!channel.publish) {
                  this._logger.error('no publish method');
                  this._logger.info({
                    channel
                  }, 'channel?');
                  return null;
                }
                let drained = new Promise((resolve) => {
                  channel.on('drain', resolve);
                });

                let published = channel.publish('commands', `command.${rebalanceCommand.applicationId}.rebalance`, new Buffer(JSON.stringify({
                  issuer: 'overlord'
                })), {
                  priority: 9,
                  type: 'rebalance',
                  headers: {
                    'x-target-consumer-tag': rebalanceCommand.consumerTag,
                    'x-application-id': rebalanceCommand.applicationId
                  }
                });
                //console.log(published);
                return published || drained;
              })
            ]).then(() => {
              let connection = channel.connection;
              return channel.close().then(() => {
                return connection.close();
              });
            });
          });
        }
      });
  }
  getConsumerStats(queue) {
    let rabbitUrl = url.parse(config.get('Hoist.rabbit.managementurl'));
    rabbitUrl.pathname = `/api/queues/${encodeURIComponent(queue.vhost)}/${encodeURIComponent(queue.name)}`;
    return request.get(url.format(rabbitUrl), {
        json: true
      })
      .then((response) => {
        let stats = {
          consumers: 0,
          expectedConsumers: 0,
          name: queue.name,
          consumerTags: pluck(response.consumer_details, 'consumer_tag')
        };
        stats.expectedConsumers = this.getDesiredExecutorCount(queue);
        stats.consumers = response.consumers;
        return stats;
      });
  }
  rebalance() {
    return Promise.resolve()
      .then(() => {
        this._logger.info('getting event queues');
        return this.getEventQueues();
      }).then((queues) => {
        this._logger.info('rebalancing executors');
        return this.sendRebalanceCommands(queues).then(() => {
          console.log('finished rebalancer');
        });
      }).catch((err) => {
        if (err.code && err.code === 'ScalingActivityInProgress') {
          this._logger.warn(err);
        } else {
          this._logger.error(err);
        }
      });
  }
}
var mongoConnection = require('../mongoose_connection');

mongoConnection.connect();

let rebalancer = new Rebalancer();
rebalancer.rebalance().then(() => {
  process.exit(0);
});
<commit_msg>reduce to 2 executors if no messages waiting<commit_after>'use strict';
import config from 'config';
import url from 'url';
import request from 'request-promise';
import {
  filter,
  take,
  pluck,
  flatten,
  sortBy
}
from 'lodash';

import Bluebird from 'bluebird';
import amqp from 'amqplib';
import logger from '@hoist/logger';

class Rebalancer {
  constructor() {
    this._logger = logger.child({
      cls: this.constructor.name
    });

  }
  getChannel() {
    if (this._channel && this._channel !== 'resolving') {
      return Promise.resolve(this._channel);
    } else if (this._channel === 'resolving') {
      return Bluebird.delay(20)
        .then(() => {
          return this.getChannel();
        });

    } else {
      this._channel = 'resolving';
      return amqp.connect(config.get('Hoist.rabbit.url'), {
        heartbeat: 60
      }).then((connection) => {
        this._connection = connection;
        return connection.createChannel()
          .then((channel) => {
            this._channel = channel;
            return channel;
          });
      });
    }
  }
  getEventQueues() {
    var rabbitUrl = url.parse(config.get('Hoist.rabbit.managementurl'));
    rabbitUrl.pathname = '/api/queues';
    rabbitUrl.query = {
      'lengths_age': 120,
      'lengths_incr': 1
    };
    return request.get(url.format(rabbitUrl), {
        json: true
      })
      .then((response) => {
        return filter(response, function (queue) {
          return queue.name.endsWith('_events');
        });
      });
  }
  getDesiredExecutorCount(queue) {
    this._logger.info({
      messagesReady: queue.messages_ready
    }, 'determining executor count for queue');
    //minimum of two executors
    //maxium of 20 executors
    //one executor per 200 messages in queue otherwise
    let expectedCount = queue.consumers;
    if (queue.messages_ready === 0) {
      expectedCount = 2;
    } else if (queue.messages_ready > 1000) {
      expectedCount++;
    } else {
      let messageStats = queue.messages_ready_details;

      if (messageStats) {
        if (messageStats.avg_rate > 10) {
          expectedCount += 8;
        } else if (messageStats.avg_rate > 5) {
          expectedCount += 4;
        } else if (messageStats.avg_rate > -5) {
          expectedCount += 2;
        } else if (messageStats.avg_rate < -30) {
          expectedCount -= 8;
        } else if (messageStats.avg_rate < -20) {
          expectedCount -= 4;
        } else if (messageStats.avg_rate < -5) {
          expectedCount -= 2;
        }
      } else {
        expectedCount = 2;
      }
    }
    expectedCount = Math.max(2, Math.min(20, expectedCount));
    this._logger.info({
      expectedCount, queue: queue.name
    }, 'expected consumer count');
    return expectedCount;
  };
  sendRebalanceCommands(queues) {
    this._logger.info('sending rebalance commands');
    return Promise.resolve()
      .then(() => {
        return Promise.all(queues.map((queue) => {
          return this.getConsumerStats(queue);
        }));
      })
      .then((queueStats) => {
        //we can take from these queues freely
        let overPopulatedConsumers = flatten(filter(queueStats, (queueStat) => {
          return queueStat.consumers > queueStat.expectedConsumers;
        }).map((queue) => {
          return take(sortBy(queue.consumerTags, () => {
            return Math.random();
          }), queue.consumers - queue.expectedConsumers).map((tag) => {
            return {
              consumerTag: tag,
              applicationId: queue.name.replace('_events', '')
            };
          });
        }));

        //we can take from these queues in an emergency
        let stealableQueues = flatten(filter(queueStats, (queueStat) => {
          return queueStat.consumers <= queueStat.expectedConsumers && queueStat.consumers > 1;
        }).map((queue) => {
          return take(queue.consumerTags, 1).map((tag) => {
            return {
              consumerTag: tag,
              applicationId: queue.name.replace('_events', '')
            };
          });
        }));

        let underPopulatedConsumerCount = filter(queueStats, (queueStat) => {
          return queueStat.consumers < queueStat.expectedConsumers && queueStat.consumers > 0;
        }).reduce((current, queue) => current + (queue.expectedConsumers - queue.consumers), 0);
        //we need to populate this many empty queues
        let emptyQueueCount = filter(queueStats, (queueStat) => {
          return queueStat.consumers === 0;
        }).length;
        let rebalancingCommands = [];
        if (overPopulatedConsumers.length < emptyQueueCount) {
          rebalancingCommands = overPopulatedConsumers.concat(take(stealableQueues, emptyQueueCount - overPopulatedConsumers.length));
        } else {
          rebalancingCommands = take(overPopulatedConsumers, emptyQueueCount + underPopulatedConsumerCount);
        }
        logger.info({
          rebalanceCommands: rebalancingCommands.length,
          stealableQueues: stealableQueues.length,
          emptyQueueCount,
          underPopulatedConsumerCount,
          overPopulatedConsumers
        }, 'gathered queue stats');
        if (rebalancingCommands.length > 0) {
          return this.getChannel().then((channel) => {
            return Promise.all([
              rebalancingCommands.map((rebalanceCommand) => {
                this._logger.info({
                  consumerTag: rebalanceCommand.consumerTag,
                  applicationId: rebalanceCommand.applicationId
                }, 'issuing rebalance command');
                if (!channel.publish) {
                  this._logger.error('no publish method');
                  this._logger.info({
                    channel
                  }, 'channel?');
                  return null;
                }
                let drained = new Promise((resolve) => {
                  channel.on('drain', resolve);
                });

                let published = channel.publish('commands', `command.${rebalanceCommand.applicationId}.rebalance`, new Buffer(JSON.stringify({
                  issuer: 'overlord'
                })), {
                  priority: 9,
                  type: 'rebalance',
                  headers: {
                    'x-target-consumer-tag': rebalanceCommand.consumerTag,
                    'x-application-id': rebalanceCommand.applicationId
                  }
                });
                //console.log(published);
                return published || drained;
              })
            ]).then(() => {
              let connection = channel.connection;
              return channel.close().then(() => {
                return connection.close();
              });
            });
          });
        }
      });
  }
  getConsumerStats(queue) {
    let rabbitUrl = url.parse(config.get('Hoist.rabbit.managementurl'));
    rabbitUrl.pathname = `/api/queues/${encodeURIComponent(queue.vhost)}/${encodeURIComponent(queue.name)}`;
    return request.get(url.format(rabbitUrl), {
        json: true
      })
      .then((response) => {
        let stats = {
          consumers: 0,
          expectedConsumers: 0,
          name: queue.name,
          consumerTags: pluck(response.consumer_details, 'consumer_tag')
        };
        stats.expectedConsumers = this.getDesiredExecutorCount(queue);
        stats.consumers = response.consumers;
        return stats;
      });
  }
  rebalance() {
    return Promise.resolve()
      .then(() => {
        this._logger.info('getting event queues');
        return this.getEventQueues();
      }).then((queues) => {
        this._logger.info('rebalancing executors');
        return this.sendRebalanceCommands(queues).then(() => {
          console.log('finished rebalancer');
        });
      }).catch((err) => {
        if (err.code && err.code === 'ScalingActivityInProgress') {
          this._logger.warn(err);
        } else {
          this._logger.error(err);
        }
      });
  }
}
var mongoConnection = require('../mongoose_connection');

mongoConnection.connect();

let rebalancer = new Rebalancer();
rebalancer.rebalance().then(() => {
  process.exit(0);
});
<|endoftext|>


<commit_before>(function () {
  angular.module('tpTagger')
      .directive('tpTagger', tpTagger);

  // tpTagger.$inject = ['$timeout', $filter, $log];
  // directiveController.$inject = ['$scope'];

  function tpTagger($timeout, $filter, $log){
    return {
      restrict: 'AE',
      templateUrl: 'tp_tagger.tpl.html',
      scope: {
        options: '='
      },
      controller: directiveController,
      link: link,
    };

    function directiveController($scope) {
      // console.log($scope.options);
      initCtrl();
      //$scope config
      $scope.hasFocus = false;
      $scope.isSuggestionsVisible = false;
      $scope.suggestions = [];
      $scope.searchTag = '';
      $scope.searching = false;
      $scope.selectedSuggestionIndex = -1;
      $scope.uniqueError = false;
      $scope.maxTagLengthError = false;
      $scope.hasError = false;

      //$scope methods
      $scope.addTag = addTag;
      $scope.deleteTag = deleteTag;
      $scope.search = search;
      $scope.isActive = isActive;
      $scope.selectActive = selectActive;
      $scope.changeInput = changeInput;
      $scope.changeSuggestionVisible = changeSuggestionVisible;
      $scope.resetErrors = resetErrors;
      /////////////////////////////////////////////

      var setError = function(errorName, state) {
        //it is only possible to show one error
        $scope[errorName] = state;
        $scope.hasError = state;
      };

      function addTag(tag) {
        if(tag === '' || tag == undefined) {
          $log.debug('tag empty');
        } else if(tag.length > $scope.options.maxTagLength) {
          $log.debug('tag too long');
          setError('maxTagLengthError', true);
          $scope.searchTag = '';
        } else if ($scope.options.uniqueTags && $scope.selectedLowerTags.indexOf(tag.toLowerCase()) !== -1) {
          $log.debug('tag not unique');
          setError('uniqueError', true);
          $scope.searchTag = '';
        } else {
          //add tag
          $scope.selectedTags.push(tag);
          $scope.selectedLowerTags.push(tag.toLowerCase());
          $scope.searchTag = '';
          if($scope.options.addFunction) {
            $scope.options.addFunction(tag);
          }
        }
      }

      function deleteTag(index) {
        if(!$scope.selectedTags[index] && !$scope.selectedLowerTags[index])
          return false;
        var tag = angular.copy($scope.selectedTags[index]);

        $scope.selectedTags.splice(index, 1);
        $scope.selectedLowerTags.splice(index, 1);

        if($scope.options.deleteFunction) {
          $scope.options.deleteFunction(tag);
        }
      }

      //the supplied search method must return a promise to indicate finish of loading
      function search(callback) {
        $scope.searching = true;
        return callback($scope.selectedTags).then(function() {
          $log.debug('finished searching');
          $scope.searching = false;
          return true;
        }, function(reason) {
          $log.error(reason);
          $scope.searching = false;
          return false;
        });
      }

      function isActive(index) {
        return index === $scope.selectedSuggestionIndex;
      }

      function selectActive(index) {
        if(!$scope.selectedTags[index])
          return false;
        $scope.selectedSuggestionIndex = index;
      }

      function changeInput() {
        //$log.info($scope.searchTag);
        if ($scope.searchTag.length > $scope.options.minChar) {
          $scope.suggestions = $filter('filter')($scope.dictionary, $scope.searchTag) || [];
          $scope.suggestions = $scope.suggestions.slice(0, $scope.options.maxResults);
          //check if suggestions view should be open
          if ($scope.suggestions.length >= 1) {
            $scope.changeSuggestionVisible(true);
          } else {
            $scope.changeSuggestionVisible(false);
          }

          //$scope.$digest();
        } else {
          if ($scope.isSuggestionsVisible) {
            $scope.changeSuggestionVisible(false);
            //scope.$digest();
          }
        }

        $scope.resetErrors();
      }

      function changeSuggestionVisible(visible) {
        if (visible) {
          $scope.isSuggestionsVisible = true;
        } else {
          $scope.selectedSuggestionIndex = -1;
          $scope.selectedSuggestion = undefined;
          $scope.isSuggestionsVisible = false;
        }
      }

      function resetErrors() {
        if($scope.hasError) {
          $log.debug('reset errors');
          $scope.uniqueError = false;
          $scope.hasError = false;
        } else
          return false;
      }

      function initCtrl() {
        //SUPPORTED OPTIONS (OPTIONS)
        $scope.options = $scope.options || {};
        //minimal no of characters that needs to be entered before typeahead kicks-in
        $scope.options.minChar = $scope.options.minChar || 1;
        $scope.options.maxResults = $scope.options.maxResults || 10;
        $scope.options.maxTagLength = $scope.options.maxTagLength || 50;
        //array of preselected Tags
        $scope.selectedTags = $scope.options.selectedTags || [];
        $scope.selectedLowerTags = [];
        //copy lower case version to seperate array
        for(var i=0; i<$scope.selectedTags.length; i++) {
          $scope.selectedLowerTags.push($scope.selectedTags[i].toLowerCase());
        }
        //array of tag to search for suggestions
        $scope.dictionary = $scope.options.dictionary || [];
        //should the user only be able to add a tag once
        $scope.options.uniqueTags = $scope.options.uniqueTags || true;
        //custom error message can be provided
        $scope.options.errors = $scope.options.errors || {
            notUniqueTag: 'The tag which you tried to add is not unique. You may only add a Tag once.',
            maxTagLength: 'The tag which you tried to add is too long. Only ' + $scope.options.maxTagLength + ' characters are allowed.'
          };
      }
    }

    function link(scope) {
      // //SUPPORTED OPTIONS (OPTIONS)
      // scope.options = scope.options || {};
      // //minimal no of characters that needs to be entered before typeahead kicks-in
      // scope.options.minChar = scope.options.minChar || 1;
      // scope.options.maxResults = scope.options.maxResults || 10;
      // scope.options.maxTagLength = scope.options.maxTagLength || 50;
      // //array of preselected Tags
      // scope.selectedTags = scope.options.selectedTags || [];
      // scope.selectedLowerTags = [];
      // //copy lower case version to seperate array
      // for(var i=0; i<scope.selectedTags.length; i++) {
      //   scope.selectedLowerTags.push(scope.selectedTags[i].toLowerCase());
      // }
      // //array of tag to search for suggestions
      // scope.dictionary = scope.options.dictionary || [];
      // //should the user only be able to add a tag once
      // scope.options.uniqueTags = scope.options.uniqueTags || true;
      // //custom error message can be provided
      // scope.options.errors = scope.options.errors || {
      //       notUniqueTag: 'The tag which you tried to add is not unique. You may only add a Tag once.',
      //       maxTagLength: 'The tag which you tried to add is too long. Only ' + scope.options.maxTagLength + ' characters are allowed.'
      //     };
    }
  }
})();
<commit_msg>bug fix<commit_after>(function () {
  angular.module('tpTagger')
      .directive('tpTagger', tpTagger);

  // tpTagger.$inject = ['$timeout', $filter, $log];
  // directiveController.$inject = ['$scope'];

  function tpTagger($timeout, $filter, $log){
    return {
      restrict: 'AE',
      templateUrl: 'tp_tagger.tpl.html',
      scope: {
        options: '='
      },
      controller: directiveController,
      link: link,
    };

    function directiveController($scope) {
      // console.log($scope.options);
      initCtrl();
      //$scope config
      $scope.hasFocus = false;
      $scope.isSuggestionsVisible = false;
      $scope.suggestions = [];
      $scope.searchTag = '';
      $scope.searching = false;
      $scope.selectedSuggestionIndex = -1;
      $scope.uniqueError = false;
      $scope.maxTagLengthError = false;
      $scope.hasError = false;

      //$scope methods
      $scope.addTag = addTag;
      $scope.deleteTag = deleteTag;
      $scope.search = search;
      $scope.isActive = isActive;
      $scope.selectActive = selectActive;
      $scope.changeInput = changeInput;
      $scope.changeSuggestionVisible = changeSuggestionVisible;
      $scope.resetErrors = resetErrors;
      /////////////////////////////////////////////

      var setError = function(errorName, state) {
        //it is only possible to show one error
        $scope[errorName] = state;
        $scope.hasError = state;
      };

      function addTag(tag) {
        if(tag === '' || tag == undefined) {
          $log.debug('tag empty');
        } else if(tag.length > $scope.options.maxTagLength) {
          $log.debug('tag too long');
          setError('maxTagLengthError', true);
          $scope.searchTag = '';
        } else if ($scope.options.uniqueTags && $scope.selectedLowerTags.indexOf(tag.toLowerCase()) !== -1) {
          $log.debug('tag not unique');
          setError('uniqueError', true);
          $scope.searchTag = '';
        } else {
          //add tag
          $scope.selectedTags.push(tag);
          $scope.selectedLowerTags.push(tag.toLowerCase());
          $scope.searchTag = '';
          if($scope.options.addFunction) {
            $scope.options.addFunction(tag);
          }
        }
      }

      function deleteTag(index) {
        if(!$scope.selectedTags[index] && !$scope.selectedLowerTags[index])
          return false;
        var tag = angular.copy($scope.selectedTags[index]);

        $scope.selectedTags.splice(index, 1);
        $scope.selectedLowerTags.splice(index, 1);

        if($scope.options.deleteFunction) {
          $scope.options.deleteFunction(tag);
        }
      }

      //the supplied search method must return a promise to indicate finish of loading
      function search(callback) {
        $scope.searching = true;
        return callback($scope.selectedTags).then(function() {
          $log.debug('finished searching');
          $scope.searching = false;
          return true;
        }, function(reason) {
          $log.error(reason);
          $scope.searching = false;
          return false;
        });
      }

      function isActive(index) {
        return index === $scope.selectedSuggestionIndex;
      }

      function selectActive(index) {
        if(!$scope.selectedTags[index])
          return false;
        $scope.selectedSuggestionIndex = index;
      }

      function changeInput() {
        //$log.info($scope.searchTag);
        if ($scope.searchTag.length > $scope.options.minChar) {
          $scope.suggestions = $filter('filter')($scope.dictionary, $scope.searchTag) || [];
          $scope.suggestions = $scope.suggestions.slice(0, $scope.options.maxResults);
          //check if suggestions view should be open
          if ($scope.suggestions.length >= 1) {
            $scope.changeSuggestionVisible(true);
          } else {
            $scope.changeSuggestionVisible(false);
          }

          //$scope.$digest();
        } else {
          if ($scope.isSuggestionsVisible) {
            $scope.changeSuggestionVisible(false);
            //scope.$digest();
          }
        }

        $scope.resetErrors();
      }

      function changeSuggestionVisible(visible) {
        if (visible) {
          $scope.isSuggestionsVisible = true;
        } else {
          $scope.selectedSuggestionIndex = -1;
          $scope.selectedSuggestion = undefined;
          $scope.isSuggestionsVisible = false;
        }
      }

      function resetErrors() {
        if($scope.hasError) {
          $log.debug('reset errors');
          $scope.uniqueError = false;
          $scope.hasError = false;
        } else
          return false;
      }

      function initCtrl() {
        //SUPPORTED OPTIONS (OPTIONS)
        $scope.options = $scope.options || {};
        //minimal no of characters that needs to be entered before typeahead kicks-in
        $scope.options.minChar = $scope.options.minChar || 1;
        $scope.options.maxResults = $scope.options.maxResults || 10;
        $scope.options.maxTagLength = $scope.options.maxTagLength || 50;
        //array of preselected Tags
        $scope.selectedTags = $scope.options.selectedTags || [];
        $scope.selectedLowerTags = [];
        //copy lower case version to seperate array
        for(var i=0; i<$scope.selectedTags.length; i++) {
          $scope.selectedLowerTags.push($scope.selectedTags[i].toLowerCase());
        }
        //array of tag to search for suggestions
        $scope.dictionary = $scope.options.dictionary || [];
        //should the user only be able to add a tag once
        $scope.options.uniqueTags = $scope.options.uniqueTags || true;
        //custom error message can be provided
        $scope.options.errors = $scope.options.errors || {
            notUniqueTag: 'The tag which you tried to add is not unique. You may only add a Tag once.',
            maxTagLength: 'The tag which you tried to add is too long. Only ' + this.maxTagLength + ' characters are allowed.'
          };
      }
    }

    function link(scope) {
      // //SUPPORTED OPTIONS (OPTIONS)
      // scope.options = scope.options || {};
      // //minimal no of characters that needs to be entered before typeahead kicks-in
      // scope.options.minChar = scope.options.minChar || 1;
      // scope.options.maxResults = scope.options.maxResults || 10;
      // scope.options.maxTagLength = scope.options.maxTagLength || 50;
      // //array of preselected Tags
      // scope.selectedTags = scope.options.selectedTags || [];
      // scope.selectedLowerTags = [];
      // //copy lower case version to seperate array
      // for(var i=0; i<scope.selectedTags.length; i++) {
      //   scope.selectedLowerTags.push(scope.selectedTags[i].toLowerCase());
      // }
      // //array of tag to search for suggestions
      // scope.dictionary = scope.options.dictionary || [];
      // //should the user only be able to add a tag once
      // scope.options.uniqueTags = scope.options.uniqueTags || true;
      // //custom error message can be provided
      // scope.options.errors = scope.options.errors || {
      //       notUniqueTag: 'The tag which you tried to add is not unique. You may only add a Tag once.',
      //       maxTagLength: 'The tag which you tried to add is too long. Only ' + scope.options.maxTagLength + ' characters are allowed.'
      //     };
    }
  }
})();
<|endoftext|>


<commit_before>"use strict";

// Show an error dialog on any error

define(
		[	'src/storage',
			'src/urlUtils',
			'src/debug',
			'jquery.ui'
		],
		function (
			CSLEDIT_storage,
			CSLEDIT_urlUtils,
			debug,
			jquery_ui
		) {

	$(document).ready(function () {
		window.onerror = function (err, url, line) {
			var dialog = $('

').css({overflow: "auto"}),
				errLines = err.split("\n"),
				refreshPage = $('<button>Refresh Page</button>'),
				resetButton = $('<button>Reset Everything</button>');

			if (
					!($.browser.chrome === true && $.browser.version.split(".")[0] >= 21) &&
					!($.browser.mozilla === true && $.browser.version.split(".")[0] >= 14)) {
				dialog.append($('
Please upgrade to the latest version of ' +
					'Chrome or ' +
					'Firefox to ' +
					'reduce the likelihood of errors.
'));
			}

			dialog.append($('
').append(refreshPage).append(" try this first"));
			refreshPage.on("click", function () {
				window.location.reload();
			});

			dialog.append($('
').append(resetButton).append(" unsaved work will be lost"));
			resetButton.on("click", function () {
				CSLEDIT_storage.clear();
				window.location.reload();
			});

			dialog.append("
" + errLines[0] + "
");

			errLines.splice(0, 1);
			if (errLines.length > 0) {
				dialog.append("
" + errLines.join("\n") + "
");
			} else {
				dialog.append("
url: " + url + "
");
				dialog.append("
line: " + line + "
");
			}

			dialog.dialog({
				width: 650,
				height: 400
			});
		};
	});
});
<commit_msg>Add comment referring to the removed PHP error logging.<commit_after>"use strict";

// Show an error dialog on any error
//
// # Error logging
//
// If you want to add error logging, you may find the following link useful:
//
// https://github.com/citation-style-editor/csl-editor-demo-site/commit/b77e0b7667ee3dc494b8934c3239643446f882e8
//
// This commit removed the PHP error logging which was used before migrating
// to a static Jekyll site.

define(
		[	'src/storage',
			'src/urlUtils',
			'src/debug',
			'jquery.ui'
		],
		function (
			CSLEDIT_storage,
			CSLEDIT_urlUtils,
			debug,
			jquery_ui
		) {

	$(document).ready(function () {
		window.onerror = function (err, url, line) {
			var dialog = $('

').css({overflow: "auto"}),
				errLines = err.split("\n"),
				refreshPage = $('<button>Refresh Page</button>'),
				resetButton = $('<button>Reset Everything</button>');

			if (
					!($.browser.chrome === true && $.browser.version.split(".")[0] >= 21) &&
					!($.browser.mozilla === true && $.browser.version.split(".")[0] >= 14)) {
				dialog.append($('
Please upgrade to the latest version of ' +
					'Chrome or ' +
					'Firefox to ' +
					'reduce the likelihood of errors.
'));
			}

			dialog.append($('
').append(refreshPage).append(" try this first"));
			refreshPage.on("click", function () {
				window.location.reload();
			});

			dialog.append($('
').append(resetButton).append(" unsaved work will be lost"));
			resetButton.on("click", function () {
				CSLEDIT_storage.clear();
				window.location.reload();
			});

			dialog.append("
" + errLines[0] + "
");

			errLines.splice(0, 1);
			if (errLines.length > 0) {
				dialog.append("
" + errLines.join("\n") + "
");
			} else {
				dialog.append("
url: " + url + "
");
				dialog.append("
line: " + line + "
");
			}

			dialog.dialog({
				width: 650,
				height: 400
			});
		};
	});
});
<|endoftext|>


<commit_before>'use strict'

/**
 * Exports
 * @ignore
 */
module.exports = {
  DataError: require('./DataError'),
}
<commit_msg>feat(errors): export OperationError<commit_after>'use strict'

/**
 * Exports
 * @ignore
 */
module.exports = {
  DataError: require('./DataError'),
  OperationError: require('./OperationError'),
}
<|endoftext|>


<commit_before>'use strict';

const Tree  = require('shark-tree');
const path  = require('path');
const chalk = require('chalk');

module.exports = function *TransformerPipe(tree, logger, transformers) {
	var oneDestTrees = [];
	var _tree = tree.getTree();
	for (var destPath in _tree) {
		if (!_tree.hasOwnProperty(destPath)) {
			continue;
		}

		var srcCollection = _tree[destPath];
		var srcArr = [];
		srcCollection.forEach(function(srcFile) {
			if (srcFile.getSrc()) {
				srcArr.push(srcFile.getSrc());
			}

		});

		var oneDestObj = {};
		oneDestObj[destPath] = {
			files: srcArr,
			options: srcCollection.getOptions()
		};
		var oneDestTree = yield Tree(oneDestObj, logger);

		var time = logger.time();
		var destPathAtStart = chalk.white(path.basename(destPath)) + ' at ' + path.dirname(destPath);
		var destPathAtFinish = chalk.green(path.basename(destPath)) + ' at ' + path.dirname(destPath);
		logger.info({
			opName: destPathAtStart,
			opType: logger.OP_TYPE.STARTED
		});

		for (var i = 0, len = transformers.length; i < len; i += 1) {
			var transformerMethod = transformers[i];
			oneDestTree = yield transformerMethod(oneDestTree, logger.child({
				deepLevel: logger.getDeepLevel() + 1,
				inPipe: true
			}));
		}

		logger.info({
			opName: destPathAtFinish,
			opType: logger.OP_TYPE.FINISHED,
			duration: time.delta()
		});
		logger.info("");

		oneDestTrees.push(oneDestTree);
	}

	oneDestTrees.forEach(function(oneDestTree) {
		tree.merge(oneDestTree);
	});

	return tree;
};<commit_msg>Replace oneDestTree creation by tree.createTreeFromDest<commit_after>'use strict';

const Tree  = require('shark-tree');
const path  = require('path');
const chalk = require('chalk');

module.exports = function *TransformerPipe(tree, logger, transformers) {
	var oneDestTrees = [];
	var _tree = tree.getTree();
	for (var destPath in _tree) {
		if (!_tree.hasOwnProperty(destPath)) {
			continue;
		}

		var oneDestTree = yield tree.createTreeFromDest(destPath);

		var time = logger.time();
		var destPathAtStart = chalk.white(path.basename(destPath)) + ' at ' + path.dirname(destPath);
		var destPathAtFinish = chalk.green(path.basename(destPath)) + ' at ' + path.dirname(destPath);
		logger.info({
			opName: destPathAtStart,
			opType: logger.OP_TYPE.STARTED
		});

		for (var i = 0, len = transformers.length; i < len; i += 1) {
			var transformerMethod = transformers[i];
			oneDestTree = yield transformerMethod(oneDestTree, logger.child({
				deepLevel: logger.getDeepLevel() + 1,
				inPipe: true
			}));
		}

		logger.info({
			opName: destPathAtFinish,
			opType: logger.OP_TYPE.FINISHED,
			duration: time.delta()
		});
		logger.info("");

		oneDestTrees.push(oneDestTree);
	}

	oneDestTrees.forEach(function(oneDestTree) {
		tree.merge(oneDestTree);
	});

	return tree;
};<|endoftext|>


<commit_before>
function tab(tabId, pageId) {
  $("div#tabs" + tabId + "> div.page").css('display', 'none');
  $("div#tabs" + tabId + "> div#page" + pageId).css('display', 'inline');
  $("ul#tabs" + tabId + "> li").css('background-color', '#A0A0A0');
  $("ul#tabs" + tabId + "> li#page" + pageId).css('background-color', 'white');
};

The MIT License (MIT)

Copyright (c) 2015 ScratchOs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<commit_msg>Update tabs.js<commit_after>
function tab(tabId, pageId) {
  $("div#tabs" + tabId + "> div.page").css('display', 'none');
  $("div#tabs" + tabId + "> div#page" + pageId).css('display', 'inline');
  $("ul#tabs" + tabId + "> li").css('background-color', '#A0A0A0');
  $("ul#tabs" + tabId + "> li#page" + pageId).css('background-color', 'white');
};

/*The MIT License (MIT)

Copyright (c) 2015 ScratchOs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
<|endoftext|>


<commit_before>/* globals L */

L.esri = {
  _callback: {}
};

// Namespace for various support variables we need to track
L.esri.Support = {
  // from: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js#L20
  CORS: !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest())
};

// AJAX handlers for CORS (modern browsers) or JSONP (older browsers)
L.esri.RequestHandlers = {
  CORS: function(url, params, callback, context){
    var httpRequest = new XMLHttpRequest();

    params.f="json";

    httpRequest.onreadystatechange = function(){
      var response;
      if (httpRequest.readyState === 4) {
        try {
          response = JSON.parse(httpRequest.responseText);
        } catch(e) {
          response = {
            error: "Could not parse response as JSON."
          };
        }
        if(context){
          callback.call(context, response);
        } else {
          callback(response);
        }
      }
    };

    httpRequest.open('GET', url + L.esri.Util.serialize(params), true);
    httpRequest.send(null);
  },
  JSONP: function(url, params, callback, context){
    var callbackId = "c"+(Math.random() * 1e9).toString(36).replace(".", "_");

    params.f="json";
    params.callback="L.esri._callback."+callbackId;

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url + L.esri.Util.serialize(params);
    script.id = callbackId;

    L.esri._callback[callbackId] = function(response){
      if(context){
        callback.call(context, response);
      } else {
        callback(response);
      }
      document.body.removeChild(script);
      delete L.esri._callback[callbackId];
    };

    document.body.appendChild(script);
  }
};

// Choose the correct AJAX handler depending on CORS support
L.esri.get = (L.esri.Support.CORS) ? L.esri.RequestHandlers.CORS : L.esri.RequestHandlers.JSONP;

// General utility namespace
L.esri.Util = {
  // make it so that passed `function` never gets called
  // twice within `delay` milliseconds. Used to throttle
  // `move` events on the layer.
  // http://remysharp.com/2010/07/21/throttling-function-calls/
  debounce: function (fn, delay, context) {
    var timer = null;
    return function() {
      var context = this||context, args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
        fn.apply(context, args);
      }, delay);
    };
  },
  // round a number away from zero used to snap
  // row/columns away from the origin of the grid
  roundAwayFromZero: function (num){
    return (num > 0) ? Math.ceil(num) : Math.floor(num);
  },
  trim: function(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  },
  cleanUrl: function(url){
    url = L.esri.Util.trim(url);

    //add a trailing slash to the url if the user omitted it
    if(url[url.length-1] !== "/"){
      url += "/";
    }

    return url;
  },
  // quick and dirty serialization
  serialize: function(params){
    var qs="?";

    for(var param in params){
      if(params.hasOwnProperty(param)){
        var key = param;
        var value = params[param];
        qs+=encodeURIComponent(key);
        qs+="=";
        qs+=encodeURIComponent(value);
        qs+="&";
      }
    }

    return qs.substring(0, qs.length - 1);
  },

  // index of polyfill, needed for IE 8
  indexOf: function(arr, obj, start){
    start = start || 0;
    if(arr.indexOf){
      return arr.indexOf(obj, start);
    }
    for (var i = start, j = arr.length; i < j; i++) {
      if (arr[i] === obj) { return i; }
    }
    return -1;
  },

  // convert an extent (ArcGIS) to LatLngBounds (Leaflet)
  extentToBounds: function(extent){
    var southWest = new L.LatLng(extent.ymin, extent.xmin);
    var northEast = new L.LatLng(extent.ymax, extent.xmax);
    return new L.LatLngBounds(southWest, northEast);
  },

  // convert an LatLngBounds (Leaflet) to extent (ArcGIS)
  boundsToExtent: function(bounds) {
    return {
      "xmin": bounds.getSouthWest().lng,
      "ymin": bounds.getSouthWest().lat,
      "xmax": bounds.getNorthEast().lng,
      "ymax": bounds.getNorthEast().lat,
      "spatialReference": {
        "wkid" : 4326
      }
    };
  },

  // convert a LatLngBounds (Leaflet) to a Envelope (Terraformer.Rtree)
  boundsToEnvelope: function(bounds){
    var extent = L.esri.Util.boundsToExtent(bounds);
    return {
      x: extent.xmin,
      y: extent.ymin,
      w: Math.abs(extent.xmin - extent.xmax),
      h: Math.abs(extent.ymin - extent.ymax)
    };
  }
};

L.esri.Mixins = {};

L.esri.Mixins.featureGrid = {
  _activeRequests: 0,
  _initializeFeatureGrid: function(map){
    this._map = map;
    this._previousCells = [];
    this.center = this._map.getCenter();
    this.origin = this._map.project(this.center);

    this._moveHandler = L.esri.Util.debounce(function(e){
      if(e.type === "zoomend"){
        this.origin = this._map.project(this.center);
        this._previousCells = [];
      }
      this._requestFeatures(e.target.getBounds());
    }, this.options.debounce, this);

    map.on("zoomend resize move", this._moveHandler, this);

    this._requestFeatures(map.getBounds());
  },
  _destroyFeatureGrid: function(map){
    map.off("zoomend resize move", this._moveHandler, this);
  },
  _requestFeatures: function(bounds){
    var cells = this._cellsWithin(bounds);

    if(cells) {
      this.fire("loading", {
        bounds: bounds
      });
    }

    for (var i = 0; i < cells.length; i++) {
      this._makeRequest(cells[i], cells, bounds);
    }
  },
  _makeRequest: function(cell, cells, bounds){
    this._activeRequests++;

    L.esri.get(this.url+"query", {
      geometryType: "esriGeometryEnvelope",
      geometry: JSON.stringify(L.esri.Util.boundsToExtent(cell.bounds)),
      outFields:"*",
      outSR: 4326,
      inSR: 4326
    }, function(response){

      //deincriment the request counter
      this._activeRequests--;

      // if there are no more active requests fire a load event for this view
      if(this._activeRequests <= 0){
        this.fire("load", {
          bounds: bounds
        });
      }

      // call the render method to render features
      this._render(response);
    }, this);
  },
  _cellsWithin: function(mapBounds){
    var size = this._map.getSize();
    var offset = this._map.project(this._map.getCenter());
    var padding = Math.min(this.options.cellSize/size.x, this.options.cellSize/size.y);
    var bounds = mapBounds.pad(0.1);
    var cells = [];

    var topLeftPoint = this._map.project(bounds.getNorthWest());
    var bottomRightPoint = this._map.project(bounds.getSouthEast());

    var topLeft = topLeftPoint.subtract(offset).divideBy(this.options.cellSize);
    var bottomRight = bottomRightPoint.subtract(offset).divideBy(this.options.cellSize);

    var offsetRows = Math.round((this.origin.x - offset.x) / this.options.cellSize);
    var offsetCols = Math.round((this.origin.y - offset.y) / this.options.cellSize);

    var minRow = L.esri.Util.roundAwayFromZero(topLeft.x)-offsetRows;
    var maxRow = L.esri.Util.roundAwayFromZero(bottomRight.x)-offsetRows;
    var minCol = L.esri.Util.roundAwayFromZero(topLeft.y)-offsetCols;
    var maxCol = L.esri.Util.roundAwayFromZero(bottomRight.y)-offsetCols;

    for (var row = minRow; row < maxRow; row++) {
      for (var col = minCol; col < maxCol; col++) {
        var cellId = "cell:"+row+":"+col;
        var duplicate = L.esri.Util.indexOf(this._previousCells, cellId) >= 0;

        if(!duplicate || !this.options.deduplicate){
          var cellBounds = this._cellExtent(row, col);
          var cellCenter = cellBounds.getCenter();
          var radius = cellCenter.distanceTo(cellBounds.getNorthWest());
          var distance = cellCenter.distanceTo(this.center);
          var cell = {
            row: row,
            col: col,
            id: cellId,
            center: cellCenter,
            bounds: cellBounds,
            distance:distance,
            radius: radius
          };
          cells.push(cell);
          this._previousCells.push(cellId);
        }
      }
    }

    cells.sort(function (a, b) {
      return a.distance - b.distance;
    });

    return cells;
  },
  _cellExtent: function(row, col){
    var swPoint = this._cellPoint(row, col);
    var nePoint = this._cellPoint(row+1, col+1);
    var sw = this._map.unproject(swPoint);
    var ne = this._map.unproject(nePoint);
    return L.latLngBounds(sw, ne);
  },
  _cellPoint:function(row, col){
    var x = this.origin.x + (row*this.options.cellSize);
    var y = this.origin.y + (col*this.options.cellSize);
    return [x, y];
  }
};

L.esri.Mixins.identifiableLayer = {
  identify:function(latLng, options, callback){
    var defaults = {
      sr: '4326',
      mapExtent: JSON.stringify(L.esri.Util.boundsToExtent(this._map.getBounds())),
      tolerance: 5,
      geometryType: 'esriGeometryPoint',
      imageDisplay: this._map._size.x + ',' + this._map._size.y + ',96',
      geometry: JSON.stringify({
        x: latLng.lng,
        y: latLng.lat,
        spatialReference: {
          wkid: 4326
        }
      })
    };

    if(this.options.layers) {
      defaults.layers = this.options.layers;
    }

    var params;

    if (typeof options === 'function' && typeof callback === 'undefined') {
      callback = options;
      params = defaults;
    } else if (typeof options === 'object') {
      if (options.layerDefs) {
        options.layerDefs = this.parseLayerDefs(options.layerDefs);
      }

      params = L.Util.extend(defaults, options);
    }

    L.esri.get(this.serviceUrl + '/identify', params, callback);
  },
  parseLayerDefs: function (layerDefs) {
    if (layerDefs instanceof Array) {
      //throw 'must be object or string';
      return '';
    }

    if (typeof layerDefs === 'object') {
      return JSON.stringify(layerDefs);
    }

    return layerDefs;
  }
};
<commit_msg>add token to feature requests<commit_after>/* globals L */

L.esri = {
  _callback: {}
};

// Namespace for various support variables we need to track
L.esri.Support = {
  // from: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js#L20
  CORS: !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest())
};

// AJAX handlers for CORS (modern browsers) or JSONP (older browsers)
L.esri.RequestHandlers = {
  CORS: function(url, params, callback, context){
    var httpRequest = new XMLHttpRequest();

    params.f="json";

    httpRequest.onreadystatechange = function(){
      var response;
      if (httpRequest.readyState === 4) {
        try {
          response = JSON.parse(httpRequest.responseText);
        } catch(e) {
          response = {
            error: "Could not parse response as JSON."
          };
        }
        if(context){
          callback.call(context, response);
        } else {
          callback(response);
        }
      }
    };

    httpRequest.open('GET', url + L.esri.Util.serialize(params), true);
    httpRequest.send(null);
  },
  JSONP: function(url, params, callback, context){
    var callbackId = "c"+(Math.random() * 1e9).toString(36).replace(".", "_");

    params.f="json";
    params.callback="L.esri._callback."+callbackId;

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url + L.esri.Util.serialize(params);
    script.id = callbackId;

    L.esri._callback[callbackId] = function(response){
      if(context){
        callback.call(context, response);
      } else {
        callback(response);
      }
      document.body.removeChild(script);
      delete L.esri._callback[callbackId];
    };

    document.body.appendChild(script);
  }
};

// Choose the correct AJAX handler depending on CORS support
L.esri.get = (L.esri.Support.CORS) ? L.esri.RequestHandlers.CORS : L.esri.RequestHandlers.JSONP;

// General utility namespace
L.esri.Util = {
  // make it so that passed `function` never gets called
  // twice within `delay` milliseconds. Used to throttle
  // `move` events on the layer.
  // http://remysharp.com/2010/07/21/throttling-function-calls/
  debounce: function (fn, delay, context) {
    var timer = null;
    return function() {
      var context = this||context, args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
        fn.apply(context, args);
      }, delay);
    };
  },
  // round a number away from zero used to snap
  // row/columns away from the origin of the grid
  roundAwayFromZero: function (num){
    return (num > 0) ? Math.ceil(num) : Math.floor(num);
  },
  trim: function(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  },
  cleanUrl: function(url){
    url = L.esri.Util.trim(url);

    //add a trailing slash to the url if the user omitted it
    if(url[url.length-1] !== "/"){
      url += "/";
    }

    return url;
  },
  // quick and dirty serialization
  serialize: function(params){
    var qs="?";

    for(var param in params){
      if(params.hasOwnProperty(param)){
        var key = param;
        var value = params[param];
        qs+=encodeURIComponent(key);
        qs+="=";
        qs+=encodeURIComponent(value);
        qs+="&";
      }
    }

    return qs.substring(0, qs.length - 1);
  },

  // index of polyfill, needed for IE 8
  indexOf: function(arr, obj, start){
    start = start || 0;
    if(arr.indexOf){
      return arr.indexOf(obj, start);
    }
    for (var i = start, j = arr.length; i < j; i++) {
      if (arr[i] === obj) { return i; }
    }
    return -1;
  },

  // convert an extent (ArcGIS) to LatLngBounds (Leaflet)
  extentToBounds: function(extent){
    var southWest = new L.LatLng(extent.ymin, extent.xmin);
    var northEast = new L.LatLng(extent.ymax, extent.xmax);
    return new L.LatLngBounds(southWest, northEast);
  },

  // convert an LatLngBounds (Leaflet) to extent (ArcGIS)
  boundsToExtent: function(bounds) {
    return {
      "xmin": bounds.getSouthWest().lng,
      "ymin": bounds.getSouthWest().lat,
      "xmax": bounds.getNorthEast().lng,
      "ymax": bounds.getNorthEast().lat,
      "spatialReference": {
        "wkid" : 4326
      }
    };
  },

  // convert a LatLngBounds (Leaflet) to a Envelope (Terraformer.Rtree)
  boundsToEnvelope: function(bounds){
    var extent = L.esri.Util.boundsToExtent(bounds);
    return {
      x: extent.xmin,
      y: extent.ymin,
      w: Math.abs(extent.xmin - extent.xmax),
      h: Math.abs(extent.ymin - extent.ymax)
    };
  }
};

L.esri.Mixins = {};

L.esri.Mixins.featureGrid = {
  _activeRequests: 0,
  _initializeFeatureGrid: function(map){
    this._map = map;
    this._previousCells = [];
    this.center = this._map.getCenter();
    this.origin = this._map.project(this.center);

    this._moveHandler = L.esri.Util.debounce(function(e){
      if(e.type === "zoomend"){
        this.origin = this._map.project(this.center);
        this._previousCells = [];
      }
      this._requestFeatures(e.target.getBounds());
    }, this.options.debounce, this);

    map.on("zoomend resize move", this._moveHandler, this);

    this._requestFeatures(map.getBounds());
  },
  _destroyFeatureGrid: function(map){
    map.off("zoomend resize move", this._moveHandler, this);
  },
  _requestFeatures: function(bounds){
    var cells = this._cellsWithin(bounds);

    if(cells) {
      this.fire("loading", {
        bounds: bounds
      });
    }

    for (var i = 0; i < cells.length; i++) {
      this._makeRequest(cells[i], cells, bounds);
    }
  },
  _makeRequest: function(cell, cells, bounds){
    this._activeRequests++;

    var requestOptions = {
      geometryType: "esriGeometryEnvelope",
      geometry: JSON.stringify(L.esri.Util.boundsToExtent(cell.bounds)),
      outFields:"*",
      outSR: 4326,
      inSR: 4326
    };

    if(this.options.token){
      requestOptions.token = this.options.token;
    }

    L.esri.get(this.url+"query", requestOptions, function(response){
      //deincriment the request counter
      this._activeRequests--;

      // if there are no more active requests fire a load event for this view
      if(this._activeRequests <= 0){
        this.fire("load", {
          bounds: bounds
        });
      }

      // call the render method to render features
      this._render(response);
    }, this);
  },
  _cellsWithin: function(mapBounds){
    var size = this._map.getSize();
    var offset = this._map.project(this._map.getCenter());
    var padding = Math.min(this.options.cellSize/size.x, this.options.cellSize/size.y);
    var bounds = mapBounds.pad(0.1);
    var cells = [];

    var topLeftPoint = this._map.project(bounds.getNorthWest());
    var bottomRightPoint = this._map.project(bounds.getSouthEast());

    var topLeft = topLeftPoint.subtract(offset).divideBy(this.options.cellSize);
    var bottomRight = bottomRightPoint.subtract(offset).divideBy(this.options.cellSize);

    var offsetRows = Math.round((this.origin.x - offset.x) / this.options.cellSize);
    var offsetCols = Math.round((this.origin.y - offset.y) / this.options.cellSize);

    var minRow = L.esri.Util.roundAwayFromZero(topLeft.x)-offsetRows;
    var maxRow = L.esri.Util.roundAwayFromZero(bottomRight.x)-offsetRows;
    var minCol = L.esri.Util.roundAwayFromZero(topLeft.y)-offsetCols;
    var maxCol = L.esri.Util.roundAwayFromZero(bottomRight.y)-offsetCols;

    for (var row = minRow; row < maxRow; row++) {
      for (var col = minCol; col < maxCol; col++) {
        var cellId = "cell:"+row+":"+col;
        var duplicate = L.esri.Util.indexOf(this._previousCells, cellId) >= 0;

        if(!duplicate || !this.options.deduplicate){
          var cellBounds = this._cellExtent(row, col);
          var cellCenter = cellBounds.getCenter();
          var radius = cellCenter.distanceTo(cellBounds.getNorthWest());
          var distance = cellCenter.distanceTo(this.center);
          var cell = {
            row: row,
            col: col,
            id: cellId,
            center: cellCenter,
            bounds: cellBounds,
            distance:distance,
            radius: radius
          };
          cells.push(cell);
          this._previousCells.push(cellId);
        }
      }
    }

    cells.sort(function (a, b) {
      return a.distance - b.distance;
    });

    return cells;
  },
  _cellExtent: function(row, col){
    var swPoint = this._cellPoint(row, col);
    var nePoint = this._cellPoint(row+1, col+1);
    var sw = this._map.unproject(swPoint);
    var ne = this._map.unproject(nePoint);
    return L.latLngBounds(sw, ne);
  },
  _cellPoint:function(row, col){
    var x = this.origin.x + (row*this.options.cellSize);
    var y = this.origin.y + (col*this.options.cellSize);
    return [x, y];
  }
};

L.esri.Mixins.identifiableLayer = {
  identify:function(latLng, options, callback){
    var defaults = {
      sr: '4326',
      mapExtent: JSON.stringify(L.esri.Util.boundsToExtent(this._map.getBounds())),
      tolerance: 5,
      geometryType: 'esriGeometryPoint',
      imageDisplay: this._map._size.x + ',' + this._map._size.y + ',96',
      geometry: JSON.stringify({
        x: latLng.lng,
        y: latLng.lat,
        spatialReference: {
          wkid: 4326
        }
      })
    };

    if(this.options.layers) {
      defaults.layers = this.options.layers;
    }

    var params;

    if (typeof options === 'function' && typeof callback === 'undefined') {
      callback = options;
      params = defaults;
    } else if (typeof options === 'object') {
      if (options.layerDefs) {
        options.layerDefs = this.parseLayerDefs(options.layerDefs);
      }

      params = L.Util.extend(defaults, options);
    }

    L.esri.get(this.serviceUrl + '/identify', params, callback);
  },
  parseLayerDefs: function (layerDefs) {
    if (layerDefs instanceof Array) {
      //throw 'must be object or string';
      return '';
    }

    if (typeof layerDefs === 'object') {
      return JSON.stringify(layerDefs);
    }

    return layerDefs;
  }
};
<|endoftext|>


<commit_before>(function () {
    Discourse.Markdown.whiteListTag('span', 'class', '*');

    Discourse.Dialect.inlineBetween({
        start: "[nsfw]",
        stop:  "[/nsfw]",
        rawContents: true,
        emitter: function(contents) {
            return ['details', ['summary', ['b', 'NSFW']]].concat(this.processInline(contents));
        }
    });

    Discourse.Dialect.inlineBetween({
        start: "[hide=",
        stop:  "[/hide]",
        rawContents: true,
        emitter: function(contents) {
            var matches = contents.match(/(.+)](.*)/);
            if (matches)
                return ['details', ['summary', ['b', matches[1]]]].concat(this.processInline(matches[2]));
        }
    });

}).call(this);
<commit_msg>Better inline processing, still issues with multiline content<commit_after>(function () {
    Discourse.Markdown.whiteListTag('span', 'class', '*');

    Discourse.Dialect.inlineBetween({
        start: "[nsfw]",
        stop:  "[/nsfw]",
        rawContents: false,
        emitter: function(contents) {
            return ['details', ['summary', ['b', 'NSFW']]].concat(contents);
        }
    });

    Discourse.Dialect.inlineBetween({
        start: "[hide=",
        stop:  "[/hide]",
        rawContents: true,
        emitter: function(contents) {
            var matches = contents.match(/(.+)]([\s\S]*)/);
            if (matches) return ['details', ['summary', ['b', matches[1]]]].concat(this.processInline(matches[2]));
        }
    });

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