<commit_before>/*
 * bootstrap-growl
 * https://github.com/softwarespot/bootstrap-growl
 * Author: softwarespot
 * Licensed under the MIT license
 * Version: 1.2.2
 */
; // jshint ignore:line
(function bootstrapGrowlNamespace($) {

    // Plugin Logic

    $.bootstrapGrowl = function bootstrapGrowl(message, options) {
        // Set our options from the defaults, overriding with the
        // parameter we pass into this function
        options = $.extend({}, $.bootstrapGrowl.options, options);

        // Create a temporary div element
        var $alert = $('<div/>')

        // Add the 'alert' and 'bootstrap-growl' classes for distinguishing
        // other Bootstrap alerts
        .addClass('bootstrap-growl alert')
            .attr('role', 'alert');

        // If the 'type' is set, then add the relevant alert-* class name
        if (_isString(options.type) && /^DANGER|INFO|SUCCESS|WARNING$/i.test(options.type)) {
            $alert.addClass('alert-' + options.type.toLowerCase());
        }

        // If the 'allow dismissal' is a boolean datatype and set to true, then add the relevant class and append a button element
        if (_isBoolean(options.allow_dismiss) && options.allow_dismiss) {
            // Close button
            var $button = $('<button/>')
                .attr('type', 'button')
                .addClass('close')
                .attr('data-dismiss', 'alert')
                .attr('aria-label', 'Close');

            // The small 'x' in the top right hand corner
            var $cross = $('<span/>')
                .attr('aria-hidden', 'true')
                .html('×');

            // Append the cross to the button element
            $button.append($cross);

            // Append the close button to the alert and add the class
            // that specifies it's dimissible
            $alert.append($button)
                .addClass('alert-dismissible');
        }

        // Append the message to the alert. This could be HTML or simple a TEXT node
        if (message) {
            $alert.append(message);
        }

        // If the 'top offset' is set, then create an offset object literal. This is for backwards compatibility only
        if (options.top_offset) {
            options.offset = {
                from: '',
                amount: options.top_offset,
            };
        }

        // Check if the options.offset is correctly formatted
        options.offset.amount = $.isNumeric(options.offset.amount) ? options.offset.amount : 20;
        options.offset.from = _isString(options.offset.from) && /^TOP|BOTTOM$/i.test(options.offset.from) ? options.offset.from : 'top';

        // Cache the jQuery selector
        var $this = null;

        // Store the offset amount
        var offsetAmount = options.offset.amount;

        // If 'stack spacing' is not numeric, then set the default to 10
        if (!$.isNumeric(options.stackup_spacing)) {
            options.stackup_spacing = 10;
        }

        // For each element with the class name of '.bootstrap-growl', calculate the offset
        $('.bootstrap-growl').each(function eachGrowl() {
            $this = $(this);
            offsetAmount = Math.max(offsetAmount, parseInt($this.css(options.offset.from), 10) + $this.outerHeight() + options.stackup_spacing);
        });

        // Workaround for changing ele to element
        if (_isString(options.ele)) {
            options.element = options.ele;
        }

        // Set the default 'element' to 'body', if it's an invalid string
        if (!_isString(options.element)) {
            options.element = 'body';
        }

        // Create a css object literal
        var css = {
            display: 'none',
            margin: 0,
            position: (options.element === 'body' ? 'fixed' : 'absolute'),
            width: 'auto',
            'z-index': '9999',
        };

        // Set the css property i.e. top or bottom, with the offset total
        css[options.offset.from] = offsetAmount + 'px';

        if (options.width !== 'auto' && $.isNumeric(options.width)) {
            css.width = options.width + 'px';
        }

        // Apply the css styles from above
        $alert.css(css);

        // Get the parent jQuery selector
        var $parent = $(options.element);

        // Append the alert to the parent element
        $parent.append($alert);

        // Convert to uppercase for case-insensitive matching
        if (_isString(options.align)) {
            options.align = options.align.toUpperCase();
        }

        // Apply the css styles with regards to alignment in the parent element
        switch (options.align) {
            case 'CENTER':
                $alert.css({
                    left: '50%',
                    'margin-left': '-' + ($alert.outerWidth() / 2) + 'px',
                });
                break;

            case 'LEFT':
                $alert.css('left', '20px');
                break;

            default:
                $alert.css('right', '20px');
        }

        // Set the default value of 'draggable' if not a boolean datatype
        options.draggable = _isBoolean(options.draggable) ? options.draggable : true;

        // Create variables to store anonymous functions. These are referenced in the delay closure
        var mouseDown = null;
        var mouseMove = null;

        // If 'draggable' is set to true
        if (options.draggable) {
            // Add moving cursor to signify they can be moved
            $alert.css('cursor', 'move');

            // Object to store the mouse co-ordinates
            var mouse = {
                x: 0,
                y: 0,

                // Update function
                update: function update(event) {
                    this.x = event.pageX;
                    this.y = event.pageY;
                },
            };

            // Create a function expression to reference at a later stage
            mouseDown = function mouseDown(event) {
                event.preventDefault();

                // If not absolute, fixed or relative, then set the position to relative by default
                if (!/^(absolute|fixed|relative)$/i.test($alert.css('position'))) {
                    $alert.css('position', 'relative');
                }

                // Update the mouse coordinates
                mouse.update(event);

                // Create a function expression to reference at a later stage
                mouseMove = function mouseMove(event) {
                    event.preventDefault();

                    // Get the offset object relative to the document
                    var offset = $alert.offset();

                    // Set the offset of the alert element
                    $alert.offset({
                        left: (offset.left + (event.pageX - mouse.x)),
                        top: (offset.top + (event.pageY - mouse.y)),
                    });

                    // Update the mouse coordinates
                    mouse.update(event);
                };

                // Register an event for 'MOUSE_MOVE' on the parent element
                $parent.on(_eventsMouseMove, mouseMove);

                // Tidy up registered events (good housekeeping)

                // Register an event for 'MOUSE_UP' on the parent element
                $parent.one(_eventsMouseUp, function mouseUpOne() {
                    // 'MOUSE_UP' will automatically be unregistered, due to using .one()

                    // Unregister the 'MOUSE_MOVE' event
                    $parent.off(_eventsMouseMove, mouseMove);
                });
            };

            // Register an event for 'MOUSE_DOWN' on the alert
            $alert.on(_eventsMouseDown, mouseDown);

            // Tidy up registered events (good housekeeping)

            // When the alert is closed, unregister the 'ALERT_CLOSED' event
            $alert.one(_eventsAlertClosed, function alertClosedOne() {
                // 'ALERT_CLOSED' will automatically be unregistered, due to using .one()

                // Unregister the 'MOUSE_DOWN' event applied to the parent element
                $alert.off(_eventsMouseDown, mouseDown);
            });

        }

        // Display the alert
        $alert.fadeIn('fast');

        // Create a delay on fade out if greater than zero,
        // otherwise the alert will stay there indefinitely
        if ($.isNumeric(options.delay) && options.delay > 0) {
            $alert.delay(options.delay).fadeOut('slow', function fadeOut() {
                // Unregister events
                if (options.draggable) {
                    // Tidy up registered events (good housekeeping)

                    // Unregister the 'MOUSE_MOVE' event
                    $parent.off(_eventsMouseMove, mouseMove);

                    // Unregister the 'MOUSE_DOWN' event applied to the parent element
                    $alert.off(_eventsMouseDown, mouseDown);
                }

                return $alert.alert('close');
            });
        }

        // Return the alert selector
        return $alert;
    };

    // Constants

    // Fired by Bootstrap when the alert has finally closed
    var _eventsAlertClosed = 'closed.bs.alert';

    // When the primary mouse button is pushed down on the alert
    var _eventsMouseDown = 'mousedown.bootstrap.growl';

    // When the mouse is moved whilst the primary mouse button is down. This is only created 'MOUSE_DOWN' is invoked
    var _eventsMouseMove = 'mousemove.bootstrap.growl';

    // When the primary mouse button is released. This is only called once using .one()
    var _eventsMouseUp = 'mouseup.bootstrap.growl';

    // Fields

    // Methods (Private)

    // Check if value is a boolean datatype
    function _isBoolean(value) {
        return $.type(value) === 'boolean';
    }

    // Check if a value is a string datatype with a length greater than zero when whitespace is stripped
    function _isString(value) {
        return $.type(value) === 'string' && $.trim(value).length > 0;
    }

    // Defaults

    $.bootstrapGrowl.options = {
        // Default parent element to append the alert to. Previously known as ele, which is still supported
        element: 'body',

        // Type of alert. See Bootstrap documentation for any additional supported formats
        type: 'info', // (null|'default', 'info', 'danger', 'success')

        // Alert offset
        offset: {
            amount: 20, // (number)
            from: 'top', // ('top', 'bottom')
        },

        // Alignment relative to the parent element
        align: 'right', // ('left', 'right', 'center')

        // With of the alert. The default is 250px, which is the same as Bootstrap's alerts
        width: 250, // (number, 'auto')

        // If true then a cross will be displayed in the top right hand corner of the alert
        allow_dismiss: true, // (true, false)

        // Delay for 'on fade out' in milliseconds
        delay: 5000, // (number)

        // Whether the alert should be draggable using the primary mouse button
        draggable: true, // (true, false)

        // Spacing between each new alert that is created
        stackup_spacing: 10, // (number)
    };

})(window.jQuery);
<commit_msg>Removed padding<commit_after>/*
 * bootstrap-growl
 * https://github.com/softwarespot/bootstrap-growl
 * Author: softwarespot
 * Licensed under the MIT license
 * Version: 1.2.2
 */
; // jshint ignore:line
(function bootstrapGrowlNamespace($) {
    // Plugin Logic

    $.bootstrapGrowl = function bootstrapGrowl(message, options) {
        // Set our options from the defaults, overriding with the
        // parameter we pass into this function
        options = $.extend({}, $.bootstrapGrowl.options, options);

        // Create a temporary div element
        var $alert = $('<div/>')

        // Add the 'alert' and 'bootstrap-growl' classes for distinguishing
        // other Bootstrap alerts
        .addClass('bootstrap-growl alert')
            .attr('role', 'alert');

        // If the 'type' is set, then add the relevant alert-* class name
        if (_isString(options.type) && /^DANGER|INFO|SUCCESS|WARNING$/i.test(options.type)) {
            $alert.addClass('alert-' + options.type.toLowerCase());
        }

        // If the 'allow dismissal' is a boolean datatype and set to true, then add the relevant class and append a button element
        if (_isBoolean(options.allow_dismiss) && options.allow_dismiss) {
            // Close button
            var $button = $('<button/>')
                .attr('type', 'button')
                .addClass('close')
                .attr('data-dismiss', 'alert')
                .attr('aria-label', 'Close');

            // The small 'x' in the top right hand corner
            var $cross = $('<span/>')
                .attr('aria-hidden', 'true')
                .html('×');

            // Append the cross to the button element
            $button.append($cross);

            // Append the close button to the alert and add the class
            // that specifies it's dimissible
            $alert.append($button)
                .addClass('alert-dismissible');
        }

        // Append the message to the alert. This could be HTML or simple a TEXT node
        if (message) {
            $alert.append(message);
        }

        // If the 'top offset' is set, then create an offset object literal. This is for backwards compatibility only
        if (options.top_offset) {
            options.offset = {
                from: '',
                amount: options.top_offset,
            };
        }

        // Check if the options.offset is correctly formatted
        options.offset.amount = $.isNumeric(options.offset.amount) ? options.offset.amount : 20;
        options.offset.from = _isString(options.offset.from) && /^TOP|BOTTOM$/i.test(options.offset.from) ? options.offset.from : 'top';

        // Cache the jQuery selector
        var $this = null;

        // Store the offset amount
        var offsetAmount = options.offset.amount;

        // If 'stack spacing' is not numeric, then set the default to 10
        if (!$.isNumeric(options.stackup_spacing)) {
            options.stackup_spacing = 10;
        }

        // For each element with the class name of '.bootstrap-growl', calculate the offset
        $('.bootstrap-growl').each(function eachGrowl() {
            $this = $(this);
            offsetAmount = Math.max(offsetAmount, parseInt($this.css(options.offset.from), 10) + $this.outerHeight() + options.stackup_spacing);
        });

        // Workaround for changing ele to element
        if (_isString(options.ele)) {
            options.element = options.ele;
        }

        // Set the default 'element' to 'body', if it's an invalid string
        if (!_isString(options.element)) {
            options.element = 'body';
        }

        // Create a css object literal
        var css = {
            display: 'none',
            margin: 0,
            position: (options.element === 'body' ? 'fixed' : 'absolute'),
            width: 'auto',
            'z-index': '9999',
        };

        // Set the css property i.e. top or bottom, with the offset total
        css[options.offset.from] = offsetAmount + 'px';

        if (options.width !== 'auto' && $.isNumeric(options.width)) {
            css.width = options.width + 'px';
        }

        // Apply the css styles from above
        $alert.css(css);

        // Get the parent jQuery selector
        var $parent = $(options.element);

        // Append the alert to the parent element
        $parent.append($alert);

        // Convert to uppercase for case-insensitive matching
        if (_isString(options.align)) {
            options.align = options.align.toUpperCase();
        }

        // Apply the css styles with regards to alignment in the parent element
        switch (options.align) {
            case 'CENTER':
                $alert.css({
                    left: '50%',
                    'margin-left': '-' + ($alert.outerWidth() / 2) + 'px',
                });
                break;

            case 'LEFT':
                $alert.css('left', '20px');
                break;

            default:
                $alert.css('right', '20px');
        }

        // Set the default value of 'draggable' if not a boolean datatype
        options.draggable = _isBoolean(options.draggable) ? options.draggable : true;

        // Create variables to store anonymous functions. These are referenced in the delay closure
        var mouseDown = null;
        var mouseMove = null;

        // If 'draggable' is set to true
        if (options.draggable) {
            // Add moving cursor to signify they can be moved
            $alert.css('cursor', 'move');

            // Object to store the mouse co-ordinates
            var mouse = {
                x: 0,
                y: 0,

                // Update function
                update: function update(event) {
                    this.x = event.pageX;
                    this.y = event.pageY;
                },
            };

            // Create a function expression to reference at a later stage
            mouseDown = function mouseDown(event) {
                event.preventDefault();

                // If not absolute, fixed or relative, then set the position to relative by default
                if (!/^(absolute|fixed|relative)$/i.test($alert.css('position'))) {
                    $alert.css('position', 'relative');
                }

                // Update the mouse coordinates
                mouse.update(event);

                // Create a function expression to reference at a later stage
                mouseMove = function mouseMove(event) {
                    event.preventDefault();

                    // Get the offset object relative to the document
                    var offset = $alert.offset();

                    // Set the offset of the alert element
                    $alert.offset({
                        left: (offset.left + (event.pageX - mouse.x)),
                        top: (offset.top + (event.pageY - mouse.y)),
                    });

                    // Update the mouse coordinates
                    mouse.update(event);
                };

                // Register an event for 'MOUSE_MOVE' on the parent element
                $parent.on(_eventsMouseMove, mouseMove);

                // Tidy up registered events (good housekeeping)

                // Register an event for 'MOUSE_UP' on the parent element
                $parent.one(_eventsMouseUp, function mouseUpOne() {
                    // 'MOUSE_UP' will automatically be unregistered, due to using .one()

                    // Unregister the 'MOUSE_MOVE' event
                    $parent.off(_eventsMouseMove, mouseMove);
                });
            };

            // Register an event for 'MOUSE_DOWN' on the alert
            $alert.on(_eventsMouseDown, mouseDown);

            // Tidy up registered events (good housekeeping)

            // When the alert is closed, unregister the 'ALERT_CLOSED' event
            $alert.one(_eventsAlertClosed, function alertClosedOne() {
                // 'ALERT_CLOSED' will automatically be unregistered, due to using .one()

                // Unregister the 'MOUSE_DOWN' event applied to the parent element
                $alert.off(_eventsMouseDown, mouseDown);
            });
        }

        // Display the alert
        $alert.fadeIn('fast');

        // Create a delay on fade out if greater than zero,
        // otherwise the alert will stay there indefinitely
        if ($.isNumeric(options.delay) && options.delay > 0) {
            $alert.delay(options.delay).fadeOut('slow', function fadeOut() {
                // Unregister events
                if (options.draggable) {
                    // Tidy up registered events (good housekeeping)

                    // Unregister the 'MOUSE_MOVE' event
                    $parent.off(_eventsMouseMove, mouseMove);

                    // Unregister the 'MOUSE_DOWN' event applied to the parent element
                    $alert.off(_eventsMouseDown, mouseDown);
                }

                return $alert.alert('close');
            });
        }

        // Return the alert selector
        return $alert;
    };

    // Constants

    // Fired by Bootstrap when the alert has finally closed
    var _eventsAlertClosed = 'closed.bs.alert';

    // When the primary mouse button is pushed down on the alert
    var _eventsMouseDown = 'mousedown.bootstrap.growl';

    // When the mouse is moved whilst the primary mouse button is down. This is only created 'MOUSE_DOWN' is invoked
    var _eventsMouseMove = 'mousemove.bootstrap.growl';

    // When the primary mouse button is released. This is only called once using .one()
    var _eventsMouseUp = 'mouseup.bootstrap.growl';

    // Fields

    // Methods (Private)

    // Check if value is a boolean datatype
    function _isBoolean(value) {
        return $.type(value) === 'boolean';
    }

    // Check if a value is a string datatype with a length greater than zero when whitespace is stripped
    function _isString(value) {
        return $.type(value) === 'string' && $.trim(value).length > 0;
    }

    // Defaults

    $.bootstrapGrowl.options = {
        // Default parent element to append the alert to. Previously known as ele, which is still supported
        element: 'body',

        // Type of alert. See Bootstrap documentation for any additional supported formats
        type: 'info', // (null|'default', 'info', 'danger', 'success')

        // Alert offset
        offset: {
            amount: 20, // (number)
            from: 'top', // ('top', 'bottom')
        },

        // Alignment relative to the parent element
        align: 'right', // ('left', 'right', 'center')

        // With of the alert. The default is 250px, which is the same as Bootstrap's alerts
        width: 250, // (number, 'auto')

        // If true then a cross will be displayed in the top right hand corner of the alert
        allow_dismiss: true, // (true, false)

        // Delay for 'on fade out' in milliseconds
        delay: 5000, // (number)

        // Whether the alert should be draggable using the primary mouse button
        draggable: true, // (true, false)

        // Spacing between each new alert that is created
        stackup_spacing: 10, // (number)
    };
})(window.jQuery);
<|endoftext|>


<commit_before>const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial({
    record: 'record-from-answer',
    timeout: 10,
    hangupOnStar: true,
    callerId: 'bob',
    method: 'POST',
    action: '/handle_post_dial'
});
dial.sip({
    method: 'POST',
    url: '/handle_screening_on_answer'
}, 'sip:kate@example.com?customheader=foo');

console.log(response.toString());
<commit_msg>updated sip-9.3.x.js with x-<commit_after>const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial({
    record: 'record-from-answer',
    timeout: 10,
    hangupOnStar: true,
    callerId: 'bob',
    method: 'POST',
    action: '/handle_post_dial'
});
dial.sip({
    method: 'POST',
    url: '/handle_screening_on_answer'
}, 'sip:kate@example.com?x-customheader=foo');

console.log(response.toString());
<|endoftext|>


<commit_before>/**
 * Given a DOM subtree, wraps it in a list, and puts each line into its own
 * list item.
 *
 * @param {Node} node modified in place.  Its content is pulled into an
 *     HTMLOListElement, and each line is moved into a separate list item.
 *     This requires cloning elements, so the input might not have unique
 *     IDs after numbering.
 */
function numberLines(node, opt_startLineNum) {
  var nocode = /(?:^|\s)nocode(?:\s|$)/;
  var lineBreak = /\r\n?|\n/;

  var document = node.ownerDocument;

  var whitespace;
  if (node.currentStyle) {
    whitespace = node.currentStyle.whiteSpace;
  } else if (window.getComputedStyle) {
    whitespace = document.defaultView.getComputedStyle(node, null)
        .getPropertyValue('white-space');
  }
  // If it's preformatted, then we need to split lines on line breaks
  // in addition to
s.
  var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);

  var li = document.createElement('LI');
  while (node.firstChild) {
    li.appendChild(node.firstChild);
  }
  // An array of lines.  We split below, so this is initialized to one
  // un-split line.
  var listItems = [li];

  function walk(node) {
    switch (node.nodeType) {
      case 1:  // Element
        if (nocode.test(node.className)) { console.log('nocode'); break; }
console.log('  el=' + node.nodeName);
        if ('BR' === node.nodeName) {
          breakAfter(node);
          // Discard the
 since it is now flush against a
.
          if (node.parentNode) {
            node.parentNode.removeChild(node);
          }
        } else {
          for (var child = node.firstChild; child; child = child.nextSibling) {
            walk(child);
          }
        }
        break;
      case 3: case 4:  // Text
        if (isPreformatted) {
          var text = node.nodeValue;
          var match = text.match(lineBreak);
          if (match) {
            var firstLine = text.substring(0, match.index);
            node.nodeValue = firstLine;
            var tail = text.substring(match.index + match[0].length);
console.log('split "' + text.replace(/\r\n?|\n/g, '\\n') + '" into "' + firstLine + '" and "' + tail.replace(/\r\n?|\n/g, '\\n') + '"');
            if (tail) {
              var parent = node.parentNode;
              parent.insertBefore(
                  document.createTextNode(tail), node.nextSibling);
            }
            breakAfter(node);
            if (!firstLine) {
              // Don't leave blank text nodes in the DOM.
              node.parentNode.removeChild(node);
            }
          }
        }
        break;
    }
  }

  // Split a line after the given node.
  function breakAfter(lineEndNode) {
    // If there's nothing to the right, then we can skip ending the line
    // here, and move root-wards since splitting just before an end-tag
    // would require us to create a bunch of empty copies.
    while (!lineEndNode.nextSibling) {
      lineEndNode = lineEndNode.parentNode;
      if (!lineEndNode) { return; }
    }

    function breakLeftOf(limit, copy) {
      // Clone shallowly if this node needs to be on both sides of the break.
      var rightSide = copy ? limit.cloneNode(false) : limit;
      var parent = limit.parentNode;
      if (parent) {
        // We clone the parent chain.
        // This helps us resurrect important styling elements that cross lines.
        // E.g. in Foo
Bar
        // should be rewritten to
Foo

Bar
.
        var parentClone = breakLeftOf(parent, 1);
        // Move the clone and everything to the right of the original
        // onto the cloned parent.
        var next = limit.nextSibling;
        parentClone.appendChild(rightSide);
        for (var sibling = next; sibling; sibling = next) {
          next = sibling.nextSibling;
          parentClone.appendChild(sibling);
        }
      }
      return rightSide;
    }

    var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);

    // Walk the parent chain until we reach an unattached LI.
    for (var parent; (parent = copiedListItem.parentNode);) { copiedListItem = parent; }
    // Put it on the list of lines for later processing.
    listItems.push(copiedListItem);
console.log('pushing listItem length=' + listItems.length + ', copy=' + copiedListItem.nodeName);
  }

  // Split lines while there are lines left to split.
  for (var i = 0;  // Number of lines that have been split so far.
       i < listItems.length;  // length updated by breakAfter calls.
       ++i) {
console.log('walking list item ' + i + ' : ' + listItems[i].innerHTML.replace(/[\r\n]+/, '\\n'));
    walk(listItems[i]);
  }

  // Make sure numeric indices show correctly.
  if (opt_startLineNum === (opt_startLineNum|0)) {
    listItems[0].setAttribute('value', opt_startLineNum);
  }

  var ol = document.createElement('OL');
  ol.className = 'linenums';
  var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
  for (var i = 0, n = listItems.length; i < n; ++i) {
    li = listItems[i];
    // Stick a class on the LIs so that stylesheets can
    // color odd/even rows, or any other row pattern that
    // is co-prime with 10.
    li.className = 'L' + ((i + offset) % 10);
    if (!li.firstChild) {
      li.appendChild(document.createTextNode('\xA0'));
    }
    ol.appendChild(li);
  }

  node.appendChild(ol);
}<commit_msg>logging for IE<commit_after>/**
 * Given a DOM subtree, wraps it in a list, and puts each line into its own
 * list item.
 *
 * @param {Node} node modified in place.  Its content is pulled into an
 *     HTMLOListElement, and each line is moved into a separate list item.
 *     This requires cloning elements, so the input might not have unique
 *     IDs after numbering.
 */
function numberLines(node, opt_startLineNum) {
  var nocode = /(?:^|\s)nocode(?:\s|$)/;
  var lineBreak = /\r\n?|\n/;

  var document = node.ownerDocument;

  var whitespace;
  if (node.currentStyle) {
    whitespace = node.currentStyle.whiteSpace;
  } else if (window.getComputedStyle) {
    whitespace = document.defaultView.getComputedStyle(node, null)
        .getPropertyValue('white-space');
  }
  // If it's preformatted, then we need to split lines on line breaks
  // in addition to
s.
  var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);

  var li = document.createElement('LI');
  while (node.firstChild) {
    li.appendChild(node.firstChild);
  }
  // An array of lines.  We split below, so this is initialized to one
  // un-split line.
  var listItems = [li];

  function walk(node) {
    switch (node.nodeType) {
      case 1:  // Element
        if (nocode.test(node.className)) { console.log('nocode'); break; }
console.log('  el=' + node.nodeName);
        if ('BR' === node.nodeName) {
          breakAfter(node);
          // Discard the
 since it is now flush against a
.
          if (node.parentNode) {
            node.parentNode.removeChild(node);
          }
        } else {
          for (var child = node.firstChild; child; child = child.nextSibling) {
            walk(child);
          }
        }
        break;
      case 3: case 4:  // Text
        if (isPreformatted) {
          var text = node.nodeValue;
          var match = text.match(lineBreak);
          if (match) {
            var firstLine = text.substring(0, match.index);
            node.nodeValue = firstLine;
            var tail = text.substring(match.index + match[0].length);
console.log('split "' + text.replace(/\r\n?|\n/g, '\\n') + '" into "' + firstLine + '" and "' + tail.replace(/\r\n?|\n/g, '\\n') + '"');
            if (tail) {
              var parent = node.parentNode;
              parent.insertBefore(
                  document.createTextNode(tail), node.nextSibling);
            }
            breakAfter(node);
            if (!firstLine) {
              // Don't leave blank text nodes in the DOM.
              node.parentNode.removeChild(node);
            }
          }
        }
        break;
    }
  }

  // Split a line after the given node.
  function breakAfter(lineEndNode) {
    // If there's nothing to the right, then we can skip ending the line
    // here, and move root-wards since splitting just before an end-tag
    // would require us to create a bunch of empty copies.
    while (!lineEndNode.nextSibling) {
      lineEndNode = lineEndNode.parentNode;
      if (!lineEndNode) { return; }
    }

    function breakLeftOf(limit, copy) {
      // Clone shallowly if this node needs to be on both sides of the break.
      var rightSide = copy ? limit.cloneNode(false) : limit;
      var parent = limit.parentNode;
      if (parent) {
        // We clone the parent chain.
        // This helps us resurrect important styling elements that cross lines.
        // E.g. in Foo
Bar
        // should be rewritten to
Foo

Bar
.
        var parentClone = breakLeftOf(parent, 1);
        // Move the clone and everything to the right of the original
        // onto the cloned parent.
        var next = limit.nextSibling;
        parentClone.appendChild(rightSide);
        for (var sibling = next; sibling; sibling = next) {
          next = sibling.nextSibling;
          parentClone.appendChild(sibling);
        }
      }
      return rightSide;
    }

    var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);

    // Walk the parent chain until we reach an unattached LI.
    for (var parent; (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
      copiedListItem = parent;
    }
    // Put it on the list of lines for later processing.
    listItems.push(copiedListItem);
console.log('pushing listItem length=' + listItems.length + ', copy=' + copiedListItem.nodeName);
  }

  // Split lines while there are lines left to split.
  for (var i = 0;  // Number of lines that have been split so far.
       i < listItems.length;  // length updated by breakAfter calls.
       ++i) {
console.log('walking list item ' + i + ' : ' + listItems[i].innerHTML.replace(/[\r\n]+/, '\\n'));
    walk(listItems[i]);
  }

  // Make sure numeric indices show correctly.
  if (opt_startLineNum === (opt_startLineNum|0)) {
    listItems[0].setAttribute('value', opt_startLineNum);
  }

  var ol = document.createElement('OL');
  ol.className = 'linenums';
  var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
  for (var i = 0, n = listItems.length; i < n; ++i) {
    li = listItems[i];
    // Stick a class on the LIs so that stylesheets can
    // color odd/even rows, or any other row pattern that
    // is co-prime with 10.
    li.className = 'L' + ((i + offset) % 10);
    if (!li.firstChild) {
      li.appendChild(document.createTextNode('\xA0'));
    }
    ol.appendChild(li);
  }

  node.appendChild(ol);
}<|endoftext|>


<commit_before>// We need to create this iframe as a place to put code that
// Gecko needs to run with special privileges, for which
// privileges Gecko requires that the code be signed.
// (But we don't want to sign _all_ of Loki, because the page
// that invokes the javascript has to be signed with the
// javascript, and we want to be able to use Loki on dynamic
// pages; sigining dynamic pages would be too inconvenient, not
// to mention slow.)
// We create this here, on the assumption that it will have
// loaded by the time we need it.
//
// For more information about how to sign scripts, see
// privileged/HOWTO
//
// Gecko
(function setup_clipboard_helper() {

	function watch_onload(func)
	{
		if (document.addEventListener) {
			document.addEventListener('DOMContentLoaded', func, false);
			window.addEventListener('load', func, false);
		} else if (window.attachEvent) {
			window.attachEvent('onload', func);
		} else {
			window.onload = func;
		}
	}

	function create_hidden_iframe(src)
	{
		var called = false;
		var frame = Util.Document.create_element(document, 'iframe',
		{
			src: src,
			style: {
				position: 'absolute',
				box: [-500, -500, 2]
			}
		});

		function append_helper_iframe()
		{
			if (called)
				return;
			called = true;

			var body = (document.getElementsByTagName('BODY')[0] ||
				document.documentElement);
			body.appendChild(frame);
		}

		watch_onload(append_helper_iframe);

		return frame;
	}

	if (typeof(Components) == 'object') {
		// Gecko
		create_hidden_iframe(_gecko_clipboard_helper_src);
	} else {
		// everyone else
		UI.Clipboard_Helper_Editable_Iframe =
			create_hidden_iframe(UI__Clipboard_Helper_Editable_Iframe__src);
	}
})();

/**
 * Declares instance variables.
 *
 * @constructor
 *
 * @class A class for helping insert an anchor. Contains code
 * common to both the button and the menu item.
 */
UI.Clipboard_Helper = function()
{
	var self = this;
	Util.OOP.inherits(self, UI.Helper);

	this.is_selection_empty = function()
	{
		var sel = Util.Selection.get_selection(this._loki.window);
		return Util.Selection.is_collapsed(sel);
	};

	this.cut = function clipboard_cut()
	{
		self.copy();
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		Util.Range.delete_contents(rng);
		self._loki.focus();
	};

	this.copy = function clipboard_copy()
	{
		// Get the HTML to copy
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		var html = Util.Range.get_html(rng);
		//var text = rng.toString();

		if (Util.Selection.is_collapsed(sel)) {
			// If nothing is actually selected; do not overwrite the clipboard.
			return;
		}

		// Unmassage and clean HTML
		var container = self._loki.document.createElement('DIV');
		container.innerHTML = html;
		self._loki.unmassage_node_descendants(container);

		// Clean the copied HTML. We pass an override to the block-level element
		// rule enforcer that specifies that inline content within paragraphs do
		// not have to be wrapped in (e.g.) paragraph tags. This prevents inline
		// content that is being copied from being treated as its own paragraph.
		UI.Clean.clean(container, self._loki.settings, false, {
			overrides: {DIV: Util.Block.BLOCK}
		});
		html = container.innerHTML;

		// Move HTML to clipboard
		try // IE
		{
			_ie_copy(html);
		}
		catch(e) // Gecko
		{
			/*
			try
			{
			*/
				_gecko_copy(html);
			/*
			}
			catch(f)
			{
				if ( _is_privilege_error(f) )
					_alert_helpful_message();
				else
					throw('UI.Clipboard_Helper.copy: Neither the IE way nor the Gecko way of copying worked. The IE way resulted in the following error: <<' + e.message + '>>. The Gecko way resulted in the following error: <<' + f.message + '>>.');
			}
			*/
		}
		self._loki.focus();
	};

	this.paste = function clipboard_paste()
	{
		try // IE
		{
			_ie_paste();
		}
		catch(e)
		{
			/*
			try // Gecko
			{
			*/
				_gecko_paste();
			/*
			}
			catch(f)
			{
				if ( _is_privilege_error(f) )
					_alert_helpful_message();
				else
					throw('UI.Clipboard_Helper.paste: Neither the IE way nor the Gecko way of pasteing worked. The IE way resulted in the following error: <<' + e.message + '>>. The Gecko way resulted in the following error: <<' + f.message + '>>.');
			}
			*/
		}
		self._loki.focus();
	};

	this.delete_it = function() // delete is a reserved word
	{
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		rng.deleteContents();
		self._loki.focus();
	};

	this.select_all = function()
	{
		self._loki.exec_command('SelectAll');
		self._loki.focus();
	};

	this.is_security_error = function(e)
	{
		return ( e.message != null && e.message.indexOf != null && e.message.indexOf('Clipboard_Helper') > -1 );
	};

	this.alert_helpful_message = function()
	{
		//self._loki.window.alert("Sorry, your browser's security settings prohibit Loki from accessing the clipboard. \n\nIf you just clicked 'Deny' in a dialog asking about security--congratulations, you have good instincts. But if you want to copy, cut, or paste via Loki's toolbar or context menu, you'll need to try again and click 'Allow' in that dialog, and might want to check 'Remember this decision', too.\n\nIf you saw no such dialog, please contact the Web Services group.");

		var alert_win = new Util.Window;
		//alert_win.open('http://fillmore-apps.carleton.edu/global_stock/php/loki/auxil/lokiaux_message.html', '_blank', 'status=1,scrollbars=1,resizable,width=600,height=300');
		// We have to use a real page rather than innerHTML because,
		// at least in FF1.5.0.4, a JS error in FF's XPI-install
		// chrome causes nothing to happen when you click on the link
		// if the page is dynamically generated.
		/*
		alert_win.body.innerHTML =
			'
You need to install the Lokiaux extension in order to use the clipboard.
' +
			'

Download it
' +
			'
When prompted, press Install
' +
			'
Restart your browser.
';
		*/
	};

	var _gecko_copy = function(html)
	{
		try
		{
			self._loki.owner_window.GeckoClipboard.set(html);
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't copy in _gecko_copy, because <<" + e + ">>.");
		}
	};

	var _ie_copy = function(html)
	{
		try
		{
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// transfer from iframe to editable div
			// select all of editable div
			// copy from editable div
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML = html;
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("SelectAll", false, null);
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("Copy", false, null);

			// Reposition cursor
			rng.select();
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't copy in _ie_copy, because <<" + e.message + ">>.");
		}
	};

	var _gecko_paste = function()
	{
		try
		{
			var data = self._loki.owner_window.GeckoClipboard.get();

			var html = (data.type == 'text/html')
				? data.value
				: data.value.replace(/\r?\n/g, "
\n");

			// Massage and clean HTML
			var container = self._loki.document.createElement('DIV');
			container.innerHTML = html;
			// See UI.Clipboard_helper.copy() for the override rationale.
			UI.Clean.clean(container, self._loki.settings, false, {
				overrides: {DIV: Util.Block.BLOCK}
			});
			self._loki.massage_node_descendants(container);
			html = container.innerHTML;

			// Get selection and range
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// Paste into temporary container
			container = rng.startContainer.ownerDocument.createElement('DIV');
			container.innerHTML = html;

			// Copy into document fragment
			var frag = rng.startContainer.ownerDocument.createDocumentFragment();
			for ( var i = 0; i < container.childNodes.length; i++ )
				frag.appendChild(container.childNodes[i].cloneNode(true));

			// Paste the document fragment
			Util.Selection.paste_node(sel, frag);
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't paste in _gecko_paste, because <<" + e + ">>.");
		}
	};

	var _ie_paste = function()
	{
		try
		{
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// Make clipboard iframe editable
			// clear editable div
			// select all of editable div
			// paste into editable div
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.contentEditable = true;
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML = "";
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("SelectAll", false, null);
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("Paste", false, null);

			// Get HTML
			var html = UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML;

			// Massage and clean HTML
			var container = self._loki.document.createElement('DIV');
			container.innerHTML = html;
			UI.Clean.clean(container, self._loki.settings);
			self._loki.massage_node_descendants(container);
			html = container.innerHTML;

			// Actually paste HTML
			rng.pasteHTML(html);
			rng.select();
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't paste in _ie_paste, because <<" + e.message + ">>.");
		}
	};
};
<commit_msg>Using UI.Messenger.display_once, we now display an explanatory message before clipboard operations on Gecko browsers.<commit_after>// We need to create this iframe as a place to put code that
// Gecko needs to run with special privileges, for which
// privileges Gecko requires that the code be signed.
// (But we don't want to sign _all_ of Loki, because the page
// that invokes the javascript has to be signed with the
// javascript, and we want to be able to use Loki on dynamic
// pages; sigining dynamic pages would be too inconvenient, not
// to mention slow.)
// We create this here, on the assumption that it will have
// loaded by the time we need it.
//
// For more information about how to sign scripts, see
// privileged/HOWTO
//
// Gecko
(function setup_clipboard_helper() {

	function watch_onload(func)
	{
		if (document.addEventListener) {
			document.addEventListener('DOMContentLoaded', func, false);
			window.addEventListener('load', func, false);
		} else if (window.attachEvent) {
			window.attachEvent('onload', func);
		} else {
			window.onload = func;
		}
	}

	function create_hidden_iframe(src)
	{
		var called = false;
		var frame = Util.Document.create_element(document, 'iframe',
		{
			src: src,
			style: {
				position: 'absolute',
				box: [-500, -500, 2]
			}
		});

		function append_helper_iframe()
		{
			if (called)
				return;
			called = true;

			var body = (document.getElementsByTagName('BODY')[0] ||
				document.documentElement);
			body.appendChild(frame);
		}

		watch_onload(append_helper_iframe);

		return frame;
	}

	if (typeof(Components) == 'object') {
		// Gecko
		create_hidden_iframe(_gecko_clipboard_helper_src);
	} else {
		// everyone else
		UI.Clipboard_Helper_Editable_Iframe =
			create_hidden_iframe(UI__Clipboard_Helper_Editable_Iframe__src);
	}
})();

/**
 * Declares instance variables.
 *
 * @constructor
 *
 * @class A class for helping insert an anchor. Contains code
 * common to both the button and the menu item.
 */
UI.Clipboard_Helper = function()
{
	var self = this;
	Util.OOP.inherits(self, UI.Helper);

	this.is_selection_empty = function()
	{
		var sel = Util.Selection.get_selection(this._loki.window);
		return Util.Selection.is_collapsed(sel);
	};

	this.cut = function clipboard_cut()
	{
		self.copy();
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		Util.Range.delete_contents(rng);
		self._loki.focus();
	};

	this.copy = function clipboard_copy()
	{
		// Get the HTML to copy
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		var html = Util.Range.get_html(rng);
		//var text = rng.toString();

		if (Util.Selection.is_collapsed(sel)) {
			// If nothing is actually selected; do not overwrite the clipboard.
			return;
		}

		// Unmassage and clean HTML
		var container = self._loki.document.createElement('DIV');
		container.innerHTML = html;
		self._loki.unmassage_node_descendants(container);

		// Clean the copied HTML. We pass an override to the block-level element
		// rule enforcer that specifies that inline content within paragraphs do
		// not have to be wrapped in (e.g.) paragraph tags. This prevents inline
		// content that is being copied from being treated as its own paragraph.
		UI.Clean.clean(container, self._loki.settings, false, {
			overrides: {DIV: Util.Block.BLOCK}
		});
		html = container.innerHTML;

		// Move HTML to clipboard
		try // IE
		{
			_ie_copy(html);
		}
		catch(e) // Gecko
		{
			/*
			try
			{
			*/
				_gecko_copy(html);
			/*
			}
			catch(f)
			{
				if ( _is_privilege_error(f) )
					_alert_helpful_message();
				else
					throw('UI.Clipboard_Helper.copy: Neither the IE way nor the Gecko way of copying worked. The IE way resulted in the following error: <<' + e.message + '>>. The Gecko way resulted in the following error: <<' + f.message + '>>.');
			}
			*/
		}
		self._loki.focus();
	};

	this.paste = function clipboard_paste()
	{
		try // IE
		{
			_ie_paste();
		}
		catch(e)
		{
			/*
			try // Gecko
			{
			*/
				_gecko_paste();
			/*
			}
			catch(f)
			{
				if ( _is_privilege_error(f) )
					_alert_helpful_message();
				else
					throw('UI.Clipboard_Helper.paste: Neither the IE way nor the Gecko way of pasteing worked. The IE way resulted in the following error: <<' + e.message + '>>. The Gecko way resulted in the following error: <<' + f.message + '>>.');
			}
			*/
		}
		self._loki.focus();
	};

	this.delete_it = function() // delete is a reserved word
	{
		var sel = Util.Selection.get_selection(self._loki.window);
		var rng = Util.Range.create_range(sel);
		rng.deleteContents();
		self._loki.focus();
	};

	this.select_all = function()
	{
		self._loki.exec_command('SelectAll');
		self._loki.focus();
	};

	this.is_security_error = function(e)
	{
		return ( e.message != null && e.message.indexOf != null && e.message.indexOf('Clipboard_Helper') > -1 );
	};

	this.alert_helpful_message = function()
	{
		//self._loki.window.alert("Sorry, your browser's security settings prohibit Loki from accessing the clipboard. \n\nIf you just clicked 'Deny' in a dialog asking about security--congratulations, you have good instincts. But if you want to copy, cut, or paste via Loki's toolbar or context menu, you'll need to try again and click 'Allow' in that dialog, and might want to check 'Remember this decision', too.\n\nIf you saw no such dialog, please contact the Web Services group.");

		var alert_win = new Util.Window;
		//alert_win.open('http://fillmore-apps.carleton.edu/global_stock/php/loki/auxil/lokiaux_message.html', '_blank', 'status=1,scrollbars=1,resizable,width=600,height=300');
		// We have to use a real page rather than innerHTML because,
		// at least in FF1.5.0.4, a JS error in FF's XPI-install
		// chrome causes nothing to happen when you click on the link
		// if the page is dynamically generated.
		/*
		alert_win.body.innerHTML =
			'
You need to install the Lokiaux extension in order to use the clipboard.
' +
			'

Download it
' +
			'
When prompted, press Install
' +
			'
Restart your browser.
';
		*/
	};

	function _show_gecko_privileges_warning()
	{
		var message = "Your browser requires that you give explicit permission for " +
			"your clipboard to be accessed, so you may see a security warning " +
			"after dismissing this message. You are free to deny this permssion, " +
			"but if you do, you may be unable to cut, copy, or paste into this " +
			"document.";

		UI.Messenger.display_once('gecko clipboard warning', message);
	}

	function _gecko_copy(html)
	{
		try
		{
			_show_gecko_privileges_warning();
			self._loki.owner_window.GeckoClipboard.set(html);
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't copy in _gecko_copy, because <<" + e + ">>.");
		}
	};

	function _ie_copy(html)
	{
		try
		{
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// transfer from iframe to editable div
			// select all of editable div
			// copy from editable div
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML = html;
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("SelectAll", false, null);
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("Copy", false, null);

			// Reposition cursor
			rng.select();
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't copy in _ie_copy, because <<" + e.message + ">>.");
		}
	};

	function _gecko_paste()
	{
		try
		{
			_show_gecko_privileges_warning();
			var data = self._loki.owner_window.GeckoClipboard.get();

			var html = (data.type == 'text/html')
				? data.value
				: data.value.replace(/\r?\n/g, "
\n");

			// Massage and clean HTML
			var container = self._loki.document.createElement('DIV');
			container.innerHTML = html;
			// See UI.Clipboard_helper.copy() for the override rationale.
			UI.Clean.clean(container, self._loki.settings, false, {
				overrides: {DIV: Util.Block.BLOCK}
			});
			self._loki.massage_node_descendants(container);
			html = container.innerHTML;

			// Get selection and range
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// Paste into temporary container
			container = rng.startContainer.ownerDocument.createElement('DIV');
			container.innerHTML = html;

			// Copy into document fragment
			var frag = rng.startContainer.ownerDocument.createDocumentFragment();
			for ( var i = 0; i < container.childNodes.length; i++ )
				frag.appendChild(container.childNodes[i].cloneNode(true));

			// Paste the document fragment
			Util.Selection.paste_node(sel, frag);
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't paste in _gecko_paste, because <<" + e + ">>.");
		}
	};

	function _ie_paste()
	{
		try
		{
			var sel = Util.Selection.get_selection(self._loki.window);
			var rng = Util.Range.create_range(sel);

			// Make clipboard iframe editable
			// clear editable div
			// select all of editable div
			// paste into editable div
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.contentEditable = true;
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML = "";
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("SelectAll", false, null);
			UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.execCommand("Paste", false, null);

			// Get HTML
			var html = UI.Clipboard_Helper_Editable_Iframe.contentWindow.document.body.innerHTML;

			// Massage and clean HTML
			var container = self._loki.document.createElement('DIV');
			container.innerHTML = html;
			UI.Clean.clean(container, self._loki.settings);
			self._loki.massage_node_descendants(container);
			html = container.innerHTML;

			// Actually paste HTML
			rng.pasteHTML(html);
			rng.select();
		}
		catch(e)
		{
			throw("UI.Clipboard_Helper: couldn't paste in _ie_paste, because <<" + e.message + ">>.");
		}
	};
};
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////////////////////////////////
function oid() {
    //Get Token Balance
    $("#tokenBal").html(allTokens.balanceTokens.totalEarned.toFixed(2) + " tokens");
    //Load Wallet
    $(".walletToast").remove();
    if (localStorage.getItem('bits-user-name') == null) {
        console.log("Not logged in")
    } else {
        Materialize.toast('Unlock wallet Unlock', null, 'walletToast')
    }
    if (window.location.hash != undefined) {
        //check if hash is oid
        var type = window.location.hash.substr(1);
        // split the hash
        var fields = type.split('=');
        var htpe = fields[0];
        var hval = fields[1];
        if (htpe == "oid") {
            //get the shop and the oder details
            var shop = getBitsWinOpt('s')
            // oid
            $(".otitle").html("");
            $(".otitle").append("Your Order");
            $(".of").html("");
            //var uid = JSON.parseInt(hval)
            var od = getObjectStore('data', 'readwrite').get('bits-user-orders-' + localStorage.getItem("bits-user-name"));
            od.onsuccess = function (event) {
                try {
                    var odData = JSON.parse(event.target.result);
                    for (var ii = 0; ii < odData.length; ++ii) {
                        var xx = odData[ii].items
                        var xid = odData[ii].id
                        //makeOrder(products)
                        // match oid to url id
                        var urloid = getBitsOpt("oid")
                        if (urloid == xid) {
                            makeOrder(JSON.parse(xx), odData[ii].location)
                        } else {
                            console.log("no match")
                        }
                    }
                } catch (err) {}
            };
            od.onerror = function () {};
            //makeOrder(hval)
        } else {
            console.log("we dont know this hash")
        }
    } else {}
}

function unlockWallet() {
    walletFunctions(90).then(function (e) {
        loadGdrive();
        $(".walletToast").remove();
    })
}

function getUserOders(f) {

    doFetch({
        action: 'getAllOrders',
        uid: localStorage.getItem("bits-user-name")
    }).then(function (e) {
        if (e.status == "ok") {
            xx = e.data;
            //var earnedPoints = 0;

            for (var ii in allTokens) {
                allTokens[ii].totalEarned = 0;
            }
            for (var ii in xx) {
                var items = xx[ii].points;
                try {
                    var typeofCoin = JSON.parse(items).coin;
                } catch (err) {
                    console.log(err);
                    continue;
                }
                try {
                    var purchasePoints = JSON.parse(items).purchase;
                    if (purchasePoints == undefined) {
                        var purchasePoints = 0;
                    }
                } catch (err) {
                    console.log('this order does not have any purchase rewards', err);
                    var purchasePoints = 0;
                }
                try {
                    var deliveryPoints = JSON.parse(items).delivery;
                    if (deliveryPoints == undefined) {
                        var deliveryPoints = 0;
                    }
                } catch (err) {
                    console.log('this order does not have any delivery rewards', err);
                    var deliveryPoints = 0;
                }
                try {
                    allTokens[typeofCoin].totalEarned = allTokens[typeofCoin].totalEarned + purchasePoints + deliveryPoints;

                } catch (err) {
                    console.log('this coin had not been included in the rewards since its currently inactive', typeofCoin);
                    continue;
                }

                console.log(typeofCoin, purchasePoints, deliveryPoints);

            };

            var setdb = getObjectStore('data', 'readwrite').put(JSON.stringify(xx), 'bits-user-orders-' + localStorage.getItem("bits-user-name"));
            setdb.onsuccess = function () {
                oid();
            }
            setTimeout(function () {
                updateEarnedTokens(f)
            }, 1500);

        } else {
            swal("Cancelled", "an error occcured", "error");
        }
    })

}
// 		var gtod = localStorage.getItem('bits-user-orders-'+localStorage.getItem("bits-user-name"));
//
function updateEarnedTokens(f) {

    $('.coinlist').html('');
    var at = allTokens['allContracts'];

    var i = 0;
    var tCe = 0;
    tBal = 0;

    for(var i in at) {
if(!(location.origin+'/').includes(allTokens[at[i]].webpage)){
   continue;
   }
try{
        var rate = allTokens[at[i]].rate;
        var coinName = allTokens[at[i]].name;
        //if i have 1000 kobos
        //var koboBalance = 1000;
        //		console.log((rate*e.data.baseEx*koboBalance).toFixed(2)+' KES');
        var koboRate = Math.floor(rate * baseX);
        var qq = rate * baseX;
        var xx = qq.toFixed(2);
        var coinId = at[i];
        var tA = allTokens[coinId].totalEarned + (allTokens[coinId].balance / Math.pow(10, allTokens[coinId].decimals));
        if (tA > 0) {
            //only display the coin if the user has a balance
            $('.coinlist').append('

' + coinName + '')
            $('.coin-' + coinId + '-bal').html('').append(tA.toFixed(5));

        }
        $('.coin-' + coinId + '-xrate').html('').append('1 ' + coinName + ' = ' + xx + ' ' + baseCd);
        tBal = tBal + (tA * allTokens[coinId].rate * baseX);
    }catch(e){
        console.log(e)
    }
        i++;
    }

    $('.balance-coins').html('').append(numberify(tBal,2) + ' ' + baseCd);
}

//Check Bal Interval
var checkBal = window.setInterval(function () {
    if ($("#checkBal")[0].innerHTML == "") {
        updateEarnedTokens()
    } else {
        clearInterval(checkBal);
    }
}, 7000);
<commit_msg>Update bits-oder-functions.js<commit_after>////////////////////////////////////////////////////////////////////////////////////////////////////////////
function oid() {
    //Get Token Balance
    $("#tokenBal").html(allTokens.balanceTokens.totalEarned.toFixed(2) + " tokens");
    //Load Wallet
    $(".walletToast").remove();
    if (localStorage.getItem('bits-user-name') == null) {
        console.log("Not logged in")
    } else {
        Materialize.toast('Unlock wallet Unlock', null, 'walletToast')
    }
    if (window.location.hash != undefined) {
        //check if hash is oid
        var type = window.location.hash.substr(1);
        // split the hash
        var fields = type.split('=');
        var htpe = fields[0];
        var hval = fields[1];
        if (htpe == "oid") {
            //get the shop and the oder details
            var shop = getBitsWinOpt('s')
            // oid
            $(".otitle").html("");
            $(".otitle").append("Your Order");
            $(".of").html("");
            //var uid = JSON.parseInt(hval)
            var od = getObjectStore('data', 'readwrite').get('bits-user-orders-' + localStorage.getItem("bits-user-name"));
            od.onsuccess = function (event) {
                try {
                    var odData = JSON.parse(event.target.result);
                    for (var ii = 0; ii < odData.length; ++ii) {
                        var xx = odData[ii].items
                        var xid = odData[ii].id
                        //makeOrder(products)
                        // match oid to url id
                        var urloid = getBitsOpt("oid")
                        if (urloid == xid) {
                            makeOrder(JSON.parse(xx), odData[ii].location)
                        } else {
                            console.log("no match")
                        }
                    }
                } catch (err) {}
            };
            od.onerror = function () {};
            //makeOrder(hval)
        } else {
            console.log("we dont know this hash")
        }
    } else {}
}

function unlockWallet() {
    walletFunctions(90).then(function (e) {
        loadGdrive();
        $(".walletToast").remove();
    })
}

function getUserOders(f) {

    doFetch({
        action: 'getAllOrders',
        uid: localStorage.getItem("bits-user-name")
    }).then(function (e) {
        if (e.status == "ok") {
            xx = e.data;
            //var earnedPoints = 0;

            for (var ii in allTokens) {
                allTokens[ii].totalEarned = 0;
            }
            for (var ii in xx) {
                var items = xx[ii].points;
                try {
                    var typeofCoin = JSON.parse(items).coin;
                } catch (err) {
                    console.log(err);
                    continue;
                }
                try {
                    var purchasePoints = JSON.parse(items).purchase;
                    if (purchasePoints == undefined) {
                        var purchasePoints = 0;
                    }
                } catch (err) {
                    console.log('this order does not have any purchase rewards', err);
                    var purchasePoints = 0;
                }
                try {
                    var deliveryPoints = JSON.parse(items).delivery;
                    if (deliveryPoints == undefined) {
                        var deliveryPoints = 0;
                    }
                } catch (err) {
                    console.log('this order does not have any delivery rewards', err);
                    var deliveryPoints = 0;
                }
                try {
                    allTokens[typeofCoin].totalEarned = allTokens[typeofCoin].totalEarned + purchasePoints + deliveryPoints;

                } catch (err) {
                    console.log('this coin had not been included in the rewards since its currently inactive', typeofCoin);
                    continue;
                }

                console.log(typeofCoin, purchasePoints, deliveryPoints);

            };

            var setdb = getObjectStore('data', 'readwrite').put(JSON.stringify(xx), 'bits-user-orders-' + localStorage.getItem("bits-user-name"));
            setdb.onsuccess = function () {
                oid();
            }
            setTimeout(function () {
                updateEarnedTokens(f)
            }, 1500);

        } else {
            swal("Cancelled", "an error occcured", "error");
        }
    })

}
// 		var gtod = localStorage.getItem('bits-user-orders-'+localStorage.getItem("bits-user-name"));
//
function updateEarnedTokens(f) {

    $('.coinlist').html('');
    var at = allTokens['allContracts'];

    var i = 0;
    var tCe = 0;
    tBal = 0;

    for(var i in at) {

try{
    if(!(location.origin+'/').includes(allTokens[at[i]].webpage)){
   continue;
   }
        var rate = allTokens[at[i]].rate;
        var coinName = allTokens[at[i]].name;
        //if i have 1000 kobos
        //var koboBalance = 1000;
        //		console.log((rate*e.data.baseEx*koboBalance).toFixed(2)+' KES');
        var koboRate = Math.floor(rate * baseX);
        var qq = rate * baseX;
        var xx = qq.toFixed(2);
        var coinId = at[i];
        var tA = allTokens[coinId].totalEarned + (allTokens[coinId].balance / Math.pow(10, allTokens[coinId].decimals));
        if (tA > 0) {
            //only display the coin if the user has a balance
            $('.coinlist').append('

' + coinName + '')
            $('.coin-' + coinId + '-bal').html('').append(tA.toFixed(5));

        }
        $('.coin-' + coinId + '-xrate').html('').append('1 ' + coinName + ' = ' + xx + ' ' + baseCd);
        tBal = tBal + (tA * allTokens[coinId].rate * baseX);
    }catch(e){
        console.log(e)
    }
        i++;
    }

    $('.balance-coins').html('').append(numberify(tBal,2) + ' ' + baseCd);
}

//Check Bal Interval
var checkBal = window.setInterval(function () {
    if ($("#checkBal")[0].innerHTML == "") {
        updateEarnedTokens()
    } else {
        clearInterval(checkBal);
    }
}, 7000);
<|endoftext|>


<commit_before>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
/*
#set ($jsExtension = '.min')
#if (!$services.debug.minify)
  #set ($jsExtension = '')
#end
*/

require.config({
  paths: {
    JobRunner: '$!services.webjars.url("org.xwiki.platform:xwiki-platform-job-webjar", "jobRunner$jsExtension")'
  }
});

require(['jquery', 'xwiki-meta', 'JobRunner'], function($, xm, JobRunner) {
  'use strict';
  var updateProgress = function(jobUI, job) {
    var percent = Math.floor((job.progress.offset || 0) * 100);
    jobUI.find('.ui-progress-bar').css('width', percent + '%');
    var jobLog = job.log.items || [];
    if (jobLog.size() > 0) {
      jobUI.find('.ui-progress-message').html(jobLog[jobLog.size() - 1].renderedMessage);
    }
  };

  var updateQuestion = function(jobUI, job, answerCallback) {
    var jobQuestion = jobUI.find('.ui-question');

    if (typeof answerCallback === 'function') {
      // Display the question
      var displayerURL = "${request.contextPath}/job/wiki/" + xm.wiki + "/question/" + job.id.join('/');

      // Remember the answer callback
      jobQuestion.data('answerCallback', answerCallback);

      $.ajax(displayerURL).done($.proxy(updateQuestionContent, jobQuestion));
    } else {
      jobQuestion.empty();
    }
  };

  var updateQuestionContent = function(data) {
    var jobQuestion = $(this);

    // Replace the question div content with the data from the request
    jobQuestion.html(data);

    // Indicate that a new question has been loaded
    jobQuestion.trigger('job:question:loaded');
  };

  var updateLog = function(jobUI, job) {
    var jobLog = job.log.items || [];
    var jobLogUI = jobUI.find('.log');
    if (job.log.offset === 0) {
      jobLogUI.html('');
    }
    jobLogUI.find('.log-item-loading').removeClass('log-item-loading');
    $.each(jobLog, function(index, item) {
      var classNames = ['log-item', 'log-item-' + item.level];
      if (job.state !== 'FINISHED' && index === jobLog.size() - 1) {
        classNames.push('log-item-loading');
      }
      $(document.createElement('li')).addClass(classNames.join(' ')).html(item.renderedMessage).appendTo(jobLogUI);
    })
  };

  var resolveAnswerProperties = function(properties, questionForm) {
    if (typeof properties === 'function') {
      return properties.bind(questionForm)();
    }

    return properties;
  }

  var createAnswerProperties = function(questionForm) {
    // Create request parameters
    var properties = {};

    // Add form inputs (either data based on input elements based)
    var dataProperties = questionForm.data('job-answer-properties');
    if (dataProperties) {
      addCustomProperties(properties, resolveAnswerProperties(dataProperties, questionForm));
    } else {
      addFormInputs(properties, questionForm);
    }

    // Add extra values
    var dataPropertiesExtra = questionForm.data('job-answer-properties-extra');
    if (dataPropertiesExtra) {
      addCustomProperties(properties, resolveAnswerProperties(dataPropertiesExtra, questionForm));
    }

    return properties;
  }

  var addCustomProperties = function(properties, extra) {
      $.each(extra, function(key, value) {
        properties['qproperty_' + key] = value;
      });
  };

  var addFormInputs = function(properties, questionForm) {
    questionForm.serializeArray().each(function(entry) {
      var propertyValue = properties[entry.name];

      if (propertyValue) {
        if (Array.isArray(propertyValue)) {
          propertyValue.push(entry.value);
        } else {
          propertyValue = [propertyValue, entry.value];
        }
      } else {
        propertyValue = entry.value;
      }

      properties[entry.name] = propertyValue;
    });
  };

  var onQuestionAnswer = function(event) {
    // Disable standard form behavior
    event.preventDefault();

    var button = $(this);

    var questionForm = button.parents('.form-question');

    // Disable other buttons
    questionForm.find('btAnswerConfirm').prop('disabled', true);
    questionForm.find('btAnswerCancel').prop('disabled', true);

    if (questionForm.length) {
      var questionUI = questionForm.parents('.ui-question');

      if (questionUI.length) {
        var answerCallback = questionUI.data('answerCallback');

        if (typeof answerCallback === 'function') {
          var createAnswerRequest = questionForm.data('job-answer-createRequest');

          if (createAnswerRequest) {
            answerCallback(createAnswerRequest);
          } else {
            var properties = createAnswerProperties(questionForm);

            var answeringNotification =
              "$escapetool.javascript($services.localization.render('job.question.notification.answering'))";

            // Set cancel marker if needed
            if (button.hasClass('btAnswerCancel')) {
              properties.cancel = 'true';

              answeringNotification =
                "$escapetool.javascript($services.localization.render('job.question.notification.canceling'))";
            }

            var notif = new XWiki.widgets.Notification(
                answeringNotification,
                'inprogress'
              );

            // Send the answer
            answerCallback(properties).done(new function() {
              notif.hide();
            });
          }
        }
      }
    }
  };

  var updateStatus = function(job, answerCallback) {
    var jobUI = $(this);
    updateProgress(jobUI, job);
    updateQuestion(jobUI, job, answerCallback);
    updateLog(jobUI, job);
  };

  var notifyJobDone = function(job) {
    var jobUI = $(this);
    jobUI.find('.ui-progress').replaceWith(job.message);
  };

  var notifyConnectionFailure = function() {
  };

  $('.job-status').has('.ui-progress').each(function() {
    var jobStatus = $(this);
    var url = jobStatus.attr('data-url');
    if (url !== '') {
      var jobLog = jobStatus.find('.log');
      var runnerConfig = {};

      runnerConfig.createStatusRequest = function() {
            return {
              url: url,
              data: {
                'logOffset': jobLog.find('.log-item').size()
              }
            };
          };

      // Handle various question related actions
      var jobQuestion = jobStatus.find('.ui-question');
      if (jobQuestion.length) {
        jobQuestion.on('click', '.btAnswerConfirm', onQuestionAnswer);
        jobQuestion.on('click', '.btAnswerCancel', onQuestionAnswer);

        runnerConfig.createAnswerRequest = function(jobId, data) {
          if (typeof data === 'function') {
            return data();
          } else {
            var answerURL = '${request.contextPath}/job/question/' + jobId.join('/');

            return {
              url: answerURL,
              data: data
            };
          }
        };
      }

      new JobRunner(runnerConfig).resume()
        .progress($.proxy(updateStatus, this))
        .done($.proxy(notifyJobDone, this))
        .fail($.proxy(notifyConnectionFailure, this));
    }
  });
});
<commit_msg>XWIKI-15187: Copy progress is broken * tell yui compressor to not remove the comment with the Velocity code when minifying the JavaScript<commit_after>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
/*!
#set ($jsExtension = '.min')
#if (!$services.debug.minify)
  #set ($jsExtension = '')
#end
*/

require.config({
  paths: {
    JobRunner: '$!services.webjars.url("org.xwiki.platform:xwiki-platform-job-webjar", "jobRunner$jsExtension")'
  }
});

require(['jquery', 'xwiki-meta', 'JobRunner'], function($, xm, JobRunner) {
  'use strict';
  var updateProgress = function(jobUI, job) {
    var percent = Math.floor((job.progress.offset || 0) * 100);
    jobUI.find('.ui-progress-bar').css('width', percent + '%');
    var jobLog = job.log.items || [];
    if (jobLog.size() > 0) {
      jobUI.find('.ui-progress-message').html(jobLog[jobLog.size() - 1].renderedMessage);
    }
  };

  var updateQuestion = function(jobUI, job, answerCallback) {
    var jobQuestion = jobUI.find('.ui-question');

    if (typeof answerCallback === 'function') {
      // Display the question
      var displayerURL = "${request.contextPath}/job/wiki/" + xm.wiki + "/question/" + job.id.join('/');

      // Remember the answer callback
      jobQuestion.data('answerCallback', answerCallback);

      $.ajax(displayerURL).done($.proxy(updateQuestionContent, jobQuestion));
    } else {
      jobQuestion.empty();
    }
  };

  var updateQuestionContent = function(data) {
    var jobQuestion = $(this);

    // Replace the question div content with the data from the request
    jobQuestion.html(data);

    // Indicate that a new question has been loaded
    jobQuestion.trigger('job:question:loaded');
  };

  var updateLog = function(jobUI, job) {
    var jobLog = job.log.items || [];
    var jobLogUI = jobUI.find('.log');
    if (job.log.offset === 0) {
      jobLogUI.html('');
    }
    jobLogUI.find('.log-item-loading').removeClass('log-item-loading');
    $.each(jobLog, function(index, item) {
      var classNames = ['log-item', 'log-item-' + item.level];
      if (job.state !== 'FINISHED' && index === jobLog.size() - 1) {
        classNames.push('log-item-loading');
      }
      $(document.createElement('li')).addClass(classNames.join(' ')).html(item.renderedMessage).appendTo(jobLogUI);
    })
  };

  var resolveAnswerProperties = function(properties, questionForm) {
    if (typeof properties === 'function') {
      return properties.bind(questionForm)();
    }

    return properties;
  }

  var createAnswerProperties = function(questionForm) {
    // Create request parameters
    var properties = {};

    // Add form inputs (either data based on input elements based)
    var dataProperties = questionForm.data('job-answer-properties');
    if (dataProperties) {
      addCustomProperties(properties, resolveAnswerProperties(dataProperties, questionForm));
    } else {
      addFormInputs(properties, questionForm);
    }

    // Add extra values
    var dataPropertiesExtra = questionForm.data('job-answer-properties-extra');
    if (dataPropertiesExtra) {
      addCustomProperties(properties, resolveAnswerProperties(dataPropertiesExtra, questionForm));
    }

    return properties;
  }

  var addCustomProperties = function(properties, extra) {
      $.each(extra, function(key, value) {
        properties['qproperty_' + key] = value;
      });
  };

  var addFormInputs = function(properties, questionForm) {
    questionForm.serializeArray().each(function(entry) {
      var propertyValue = properties[entry.name];

      if (propertyValue) {
        if (Array.isArray(propertyValue)) {
          propertyValue.push(entry.value);
        } else {
          propertyValue = [propertyValue, entry.value];
        }
      } else {
        propertyValue = entry.value;
      }

      properties[entry.name] = propertyValue;
    });
  };

  var onQuestionAnswer = function(event) {
    // Disable standard form behavior
    event.preventDefault();

    var button = $(this);

    var questionForm = button.parents('.form-question');

    // Disable other buttons
    questionForm.find('btAnswerConfirm').prop('disabled', true);
    questionForm.find('btAnswerCancel').prop('disabled', true);

    if (questionForm.length) {
      var questionUI = questionForm.parents('.ui-question');

      if (questionUI.length) {
        var answerCallback = questionUI.data('answerCallback');

        if (typeof answerCallback === 'function') {
          var createAnswerRequest = questionForm.data('job-answer-createRequest');

          if (createAnswerRequest) {
            answerCallback(createAnswerRequest);
          } else {
            var properties = createAnswerProperties(questionForm);

            var answeringNotification =
              "$escapetool.javascript($services.localization.render('job.question.notification.answering'))";

            // Set cancel marker if needed
            if (button.hasClass('btAnswerCancel')) {
              properties.cancel = 'true';

              answeringNotification =
                "$escapetool.javascript($services.localization.render('job.question.notification.canceling'))";
            }

            var notif = new XWiki.widgets.Notification(
                answeringNotification,
                'inprogress'
              );

            // Send the answer
            answerCallback(properties).done(new function() {
              notif.hide();
            });
          }
        }
      }
    }
  };

  var updateStatus = function(job, answerCallback) {
    var jobUI = $(this);
    updateProgress(jobUI, job);
    updateQuestion(jobUI, job, answerCallback);
    updateLog(jobUI, job);
  };

  var notifyJobDone = function(job) {
    var jobUI = $(this);
    jobUI.find('.ui-progress').replaceWith(job.message);
  };

  var notifyConnectionFailure = function() {
  };

  $('.job-status').has('.ui-progress').each(function() {
    var jobStatus = $(this);
    var url = jobStatus.attr('data-url');
    if (url !== '') {
      var jobLog = jobStatus.find('.log');
      var runnerConfig = {};

      runnerConfig.createStatusRequest = function() {
            return {
              url: url,
              data: {
                'logOffset': jobLog.find('.log-item').size()
              }
            };
          };

      // Handle various question related actions
      var jobQuestion = jobStatus.find('.ui-question');
      if (jobQuestion.length) {
        jobQuestion.on('click', '.btAnswerConfirm', onQuestionAnswer);
        jobQuestion.on('click', '.btAnswerCancel', onQuestionAnswer);

        runnerConfig.createAnswerRequest = function(jobId, data) {
          if (typeof data === 'function') {
            return data();
          } else {
            var answerURL = '${request.contextPath}/job/question/' + jobId.join('/');

            return {
              url: answerURL,
              data: data
            };
          }
        };
      }

      new JobRunner(runnerConfig).resume()
        .progress($.proxy(updateStatus, this))
        .done($.proxy(notifyJobDone, this))
        .fail($.proxy(notifyConnectionFailure, this));
    }
  });
});
<|endoftext|>


<commit_before>!function(){"use strict";function n(n){return"function"==typeof n}function t(n){return"[object Array]"===Object.prototype.toString.call(n)}function r(n){return n instanceof Date?n.getTime():n instanceof Array?n.map(r):n}function e(n){return function(r,e){if(!t(e))return n(r,e);for(var u=0,o=e.length;o>u;u++)if(n(r,e[u]))return!0;return!1}}function u(n){return function(r,e){if(!t(e))return n(r,e);for(var u=0,o=e.length;o>u;u++)if(!n(r,e[u]))return!1;return!0}}function o(n,t){return n.v(n.a,t)}function i(n,t){for(var r=0;r<n.length;r++)if(o(t,n[r]))return r;return-1}function f(n,t){return{a:n,v:t}}function c(n,t){var r=[];return a(t,n.k,0,r),1===r.length?o(n.nv,r[0]):!!~i(r,n.nv)}function a(n,r,e,u){if(e===r.length||void 0==n)return void u.push(n);if(t(n))for(var o=0,i=n.length;i>o;o++)a(n[o],r,e,u);else a(n[r[e]],r,e+1,u)}function $(n,t){return{a:{k:n,nv:t},v:c}}function l(n){n=r(n),(!n||"Object"!==n.constructor.toString()&&"functionObject(){[nativecode]}"!==n.constructor.toString().replace(/\n/g,"").replace(/ /g,""))&&(n={$eq:n});var t=[];for(var e in n){var u=n[e];if(s[e])d[e]&&(u=d[e](u)),t.push(f(r(u),s[e]));else{if(36===e.charCodeAt(0))throw new Error("Unknown operation "+e);t.push($(e.split("."),l(u)))}}return 1===t.length?t[0]:f(t,s.$and)}function p(n,t){var r=l(n);return t&&(r={a:r,v:function(n,r){return o(n,t(r))}}),r}function v(t,r,e){function u(n){return o(i,n)}n(r)&&(e=r,r=void 0);var i=p(t,e);return r?r.filter(u):u}var s={$eq:e(function(n,t){return n(t)}),$ne:u(function(n,t){return!n(t)}),$or:function(n,t){for(var r=0,e=n.length;e>r;r++)if(o(n[r],t))return!0;return!1},$gt:e(function(n,t){return typeof r(t)==typeof n&&r(t)>n}),$gte:e(function(n,t){return typeof r(t)==typeof n&&r(t)>=n}),$lt:e(function(n,t){return typeof r(t)==typeof n&&r(t)<n}),$lte:e(function(n,t){return typeof r(t)==typeof n&&r(t)<=n}),$mod:e(function(n,t){return t%n[0]==n[1]}),$in:function(n,t){if(!(t instanceof Array))return!!~n.indexOf(r(t));for(var e=t.length;e--;)if(~n.indexOf(r(t[e])))return!0;return!1},$nin:function(n,t){return!s.$in(n,t)},$not:function(n,t){return!o(n,t)},$type:function(n,t){return void 0!=t?t instanceof n||t.constructor==n:!1},$all:function(n,t){t||(t=[]);for(var e=n.length;e--;)if(!~r(t).indexOf(n[e]))return!1;return!0},$size:function(n,t){return t?n===t.length:!1},$nor:function(n,t){for(var r=0,e=n.length;e>r;r++)if(o(n[r],t))return!1;return!0},$and:function(n,t){for(var r=0,e=n.length;e>r;r++)if(!o(n[r],t))return!1;return!0},$regex:function(n,t){return n.test(t)},$where:function(n,t){return n.call(t,t)},$elemMatch:function(n,r){return t(r)?!!~i(r,n):o(n,r)},$exists:function(n,t){return void 0!=t===n}},d={$eq:function(n){return n instanceof RegExp?function(t){return n.test(r(t))}:n instanceof Function?n:function(t){return n===r(t)}},$ne:function(n){return d.$eq(n)},$and:function(n){return n.map(l)},$or:function(n){return n.map(l)},$nor:function(n){return n.map(l)},$not:function(n){return l(n)},$regex:function(n){return new RegExp(n)},$where:function(n){return"string"==typeof n?new Function("obj","return "+n):n},$elemMatch:function(n){return l(n)},$exists:function(n){return!!n}};v.use=function(t){if(n(t))return t(v);for(var r in t)36===r.charCodeAt(0)&&(s[r]=t[r])},v.indexOf=function(n,t,r){return i(t,p(n,r))},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=v:"undefined"!=typeof window&&(window.sift=v)}();<commit_msg>add minified version<commit_after>!function(){"use strict";function n(n){return"function"==typeof n}function t(n){return"[object Array]"===Object.prototype.toString.call(n)}function r(n){return n instanceof Date?n.getTime():n instanceof Array?n.map(r):n}function e(n,t){return n.get?n.get(t):n[t]}function u(n){return function(r,u){if(!t(u)||!u.length)return n(r,u);for(var o=0,i=u.length;o<i;o++)if(n(r,e(u,o)))return!0;return!1}}function o(n){return function(r,u){if(!t(u)||!u.length)return n(r,u);for(var o=0,i=u.length;o<i;o++)if(!n(r,e(u,o)))return!1;return!0}}function i(n,t){return n.v(n.a,t)}function f(n,t){for(var r=0;r<n.length;r++)if(i(t,e(n,r)))return r;return-1}function c(n,t){return{a:n,v:t}}function a(n,t){var r=[];return l(t,n.k,0,r),1===r.length?i(n.nv,r[0]):!!~f(r,n.nv)}function l(n,r,u,o){if(u===r.length||void 0==n)return void o.push(n);var i=e(r,u);if(t(n)&&isNaN(Number(i)))for(var f=0,c=n.length;f<c;f++)l(e(n,f),r,u,o);else l(e(n,i),r,u+1,o)}function $(n,t){return{a:{k:n,nv:t},v:a}}function g(n){return"Object"===String(n.constructor)||"functionObject(){[nativecode]}"===String(n.constructor).replace(/[\r\n\s\t]/g,"")}function p(n){n=r(n),n&&g(n)||(n={$eq:n});var t=[];for(var e in n){var u=n[e];if("$options"!==e)if(d[e])h[e]&&(u=h[e](u,n)),t.push(c(r(u),d[e]));else{if(36===e.charCodeAt(0))throw new Error("Unknown operation "+e);t.push($(e.split("."),p(u)))}}return 1===t.length?t[0]:c(t,d.$and)}function s(n,t){var r=p(n);return t&&(r={a:r,v:function(n,r){return i(n,t(r))}}),r}function v(t,r,e){function u(n){return i(o,n)}n(r)&&(e=r,r=void 0);var o=s(t,e);return r?r.filter(u):u}var d={$eq:u(function(n,t){return n(t)}),$ne:o(function(n,t){return!n(t)}),$or:function(n,t){for(var r=0,u=n.length;r<u;r++)if(i(e(n,r),t))return!0;return!1},$gt:u(function(n,t){return v.compare(r(t),n)>0}),$gte:u(function(n,t){return v.compare(r(t),n)>=0}),$lt:u(function(n,t){return v.compare(r(t),n)<0}),$lte:u(function(n,t){return v.compare(r(t),n)<=0}),$mod:u(function(n,t){return t%n[0]==n[1]}),$in:function(n,t){if(!(t instanceof Array)){var u=r(t);if(u===t&&"object"==typeof t)for(var o=n.length;o--;)if(String(n[o])===String(t)&&"[object Object]"!==String(t))return!0;return!!~n.indexOf(r(t))}for(var o=t.length;o--;)if(~n.indexOf(r(e(t,o))))return!0;return!1},$nin:function(n,t){return!d.$in(n,t)},$not:function(n,t){return!i(n,t)},$type:function(n,t){return void 0!=t&&(t instanceof n||t.constructor==n)},$all:function(n,t){return d.$and(n,t)},$size:function(n,t){return!!t&&n===t.length},$nor:function(n,t){for(var r=0,u=n.length;r<u;r++)if(i(e(n,r),t))return!1;return!0},$and:function(n,t){t||(t=[]);for(var r=0,u=n.length;r<u;r++)if(!i(e(n,r),t))return!1;return!0},$regex:u(function(n,t){return"string"==typeof t&&n.test(t)}),$where:function(n,t){return n.call(t,t)},$elemMatch:function(n,r){return t(r)?!!~f(r,n):i(n,r)},$exists:function(n,t){return void 0!=t===n}},h={$eq:function(n){return n instanceof RegExp?function(t){return"string"==typeof t&&n.test(t)}:n instanceof Function?n:t(n)&&!n.length?function(n){return t(n)&&!n.length}:null===n?function(n){return null==n}:function(t){return 0===v.compare(r(t),n)}},$ne:function(n){return h.$eq(n)},$and:function(n){return n.map(p)},$all:function(n){return h.$and(n)},$or:function(n){return n.map(p)},$nor:function(n){return n.map(p)},$not:function(n){return p(n)},$regex:function(n,t){return new RegExp(n,t.$options)},$where:function(n){return"string"==typeof n?new Function("obj","return "+n):n},$elemMatch:function(n){return p(n)},$exists:function(n){return!!n}};v.use=function(t){if(n(t))return t(v);for(var r in t)36===r.charCodeAt(0)&&(d[r]=t[r])},v.indexOf=function(n,t,r){return f(t,s(n,r))},v.compare=function(n,t){if(n===t)return 0;if(typeof n==typeof t){if(n>t)return 1;if(n<t)return-1}},"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=v),"undefined"!=typeof window&&(window.sift=v)}();<|endoftext|>


<commit_before>// @flow

import type {BotResultActionDataType} from './bot';

function rateMoveAction(botResultActionData: BotResultActionDataType): number {
    return Math.random();
}

function rateMainAction(botResultActionData: BotResultActionDataType): number {
    return Math.random();
}

export function rateBotResultActionData(botResultActionData: BotResultActionDataType): number {
    const {unitAction} = botResultActionData;

    return unitAction === null ? rateMoveAction(botResultActionData) : rateMainAction(botResultActionData);
}
<commit_msg>bot - in progress...<commit_after>// @flow

import type {BotResultActionDataType} from './bot';

type PointType = {|
    +x: number,
    +y: number,
|};

export type RawRateType = {|
    +placeArmor: number,
    +attack: {|
        +damageGiven: number,
        +damageReceived: number,
    |},

    +pathSizeToNearNoOccupiedBuilding: number, // castle or farm, less better, will stimulate unit to move ahead
    +canRaiseSkeleton: boolean,

    // farm
    +canFixFarm: boolean,
    +canOccupyEnemyFarm: boolean,
    +canOccupyNoManFarm: boolean,
    +canDestroyEnemyFarm: boolean,
    // +canDestroyNoManFarm: boolean, // catapult can not destroy no man's farm

    // castle
    +canOccupyEnemyCastle: boolean,
    +canOccupyNoManCastle: boolean,
|};

function getEndPoint(botResultActionData: BotResultActionDataType): PointType {
    const {unit, moveAction} = botResultActionData;
    const {action} = moveAction;

    if (action) {
        return {
            x: action.to.x,
            y: action.to.y,
        };
    }

    const unitAttr = unit.getAttr();

    return {
        x: unitAttr.x,
        y: unitAttr.y,
    };
}

function rateMoveAction(botResultActionData: BotResultActionDataType): number {
    return Math.random();
}

function rateMainAction(botResultActionData: BotResultActionDataType): number {
    return Math.random();
}

export function rateBotResultActionData(botResultActionData: BotResultActionDataType): number {
    const {unitAction} = botResultActionData;

    return unitAction === null ? rateMoveAction(botResultActionData) : rateMainAction(botResultActionData);
}
<|endoftext|>