<commit_before>define(function(require) {
  "use strict";

  var $ = require("jquery");

  // Initialize variables.
  var resizeState = false;
  var dragState = false;
  var xInitPos;
  var yInitPos;
  var offsetLeft;
  var offsetTop;
  var initialCropBoxHeight;
  var initialCropBoxWidth;
  var previewImageWidth;
  var previewImageHeight;
  var resizeClickPositionX = 0;
  var resizeClickPositionY = 0;
  var $cropBox = $("

");
  var $previewImage;
  var origImage;
  var scale = 1;
  var degrees = 0;
  var minThreshold = 480;

  /**
   * Returns the coordinates of a touch or mouse event.
   */
  var getCoords = function(e) {
    var coords = {};
    var eventType = e.originalEvent.type;

    // Get the coordinates of a touchevent.
    if (eventType === "touchstart" || eventType === "touchmove" || eventType === "touchend") {
      coords = e.originalEvent.targetTouches[0];
    }
    // Get coordinates of mouse event.
    else {
      coords = {
        pageX: e.pageX,
        pageY: e.pageY,
      };
    }

    return coords;
  };

  /**
   * Returns a value equal to the minimum allowed crop size scaled down to fit the image.
   */
  var getMinimumSize = function() {
    return minThreshold / scale;
  };

  /**
   * This returns the amount to translate an image after it has been rotated so
   * so that it stays center in it's container.
   *
   * @param {jQuery} width      Width of the image.
   * @param {jQuery} height     height of the image.
   * @param {jQuery} degrees    How many degrees the image has been rotated.
   */
  var getTranslateDifference = function(width, height, degrees) {
    var translateDiff = (width / 2) - (height / 2);

    if (degrees === 90 || degrees === 270) {
      return (degrees === 270) ? -(translateDiff) : translateDiff;
    }
    else {
      return 0;
    }
  };

  /**
   * Turns on the ability to drag the crop box.
   */
  var dragCropBoxInit = function() {
    // Bind touch and mouse events.
    $cropBox.on("touchstart mousedown", function(event) {
      event.preventDefault();

      var coords = getCoords(event);

      // Set the initial position of the mouse.
      xInitPos = coords.pageX;
      yInitPos = coords.pageY;

      // Sets the initial positioning of the crop box.
      if ($cropBox.length) {
        offsetLeft = parseInt($cropBox.css("left"), 10);
        offsetTop = parseInt($cropBox.css("top"), 10);
      }

      // Turns on dragging.
      dragState = true;
    });
  };

  /**
   * Turns on the ability to resize the crop box.
   */
  var resizeCropBoxInit = function() {
    $(".resize-handle").on("touchstart mousedown", function(event) {
      event.preventDefault();

      // Grab the postioning of the event.
      var coords = getCoords(event);

      // Set the initial size of the crop box.
      if ($cropBox.length) {
        initialCropBoxHeight = parseInt($cropBox.css("height"), 10);
        initialCropBoxWidth = parseInt($cropBox.css("width"), 10);
      }

      // Set the position of the mouse.
      resizeClickPositionX = coords.pageX;
      resizeClickPositionY = coords.pageY;

      // Turn on resizing.
      resizeState = true;
    });
  };

  var croppingReset = function (width, height) {
    // Turn off any previously bound events so
    // we can rebind them later using new settings.
    $cropBox.off("touchmove mousemove");
    $cropBox.off("touchend mouseup");

    // Bind move events to the document.
    $(document).on("touchmove mousemove", function(event) {
      var coords = getCoords(event);

      var cropBoxHeight = parseInt($cropBox.css("height"),10);
      var cropBoxWidth = parseInt($cropBox.css("width"),10);
      var cropBoxTop = parseInt($cropBox.css("top"), 10);
      var cropBoxLeft = parseInt($cropBox.css("left"), 10);

      // If dragging, drag the crop box along.
      if (dragState) {
        // Calculate how far to move the box down and right based on the mouse position.
        var moveRight = offsetLeft + (coords.pageX - xInitPos);
        var moveDown = offsetTop + (coords.pageY - yInitPos);

        // Boundary threshold tests.
        var withinTopBounds = (height - cropBoxHeight) > moveDown ? true : false;
        var withinLeftBounds = (width - cropBoxWidth) > moveRight ? true : false;

        // Make sure we are still within the bounds of the image and then actully move the box.
        if (withinTopBounds && (moveDown > 0)) {
          $cropBox.css("top", moveDown);
        }
        if (withinLeftBounds && (moveRight > 0)) {
          $cropBox.css( "left", moveRight);
        }
      }

      // If resizing, resize the crop box.
      if (resizeState) {
        dragState = false;
        // Calculate how much to resize the cropbox.
        var resizeHorizontal = initialCropBoxWidth + (coords.pageX - resizeClickPositionX);
        var resizeVertical = initialCropBoxHeight + (coords.pageX - resizeClickPositionX);

        // Boundary threshold tests.
        var withinHeightBounds = (cropBoxHeight + cropBoxTop) < height ? true : false;
        var withinWidthBounds = (cropBoxWidth + cropBoxLeft) < width ? true : false;
        var cropBoxSizeAllowed = (cropBoxWidth > minThreshold) ? true : false;
        var increasingSize = (coords.pageX - resizeClickPositionX) > 0 ? true : false;
        var decreasingSize = (coords.pageX - resizeClickPositionX) < 0 ? true : false;

        // Make sure we are still in the boundaries of the image, and then resize the box.
        if (withinHeightBounds && withinWidthBounds && (cropBoxSizeAllowed || increasingSize)) {
          $cropBox.css( "height", resizeVertical);
          $cropBox.css( "width", resizeHorizontal);
        }
        else if (decreasingSize && cropBoxSizeAllowed) {
          $cropBox.css( "height", resizeVertical);
          $cropBox.css( "width", resizeHorizontal);
        }
      }
    });

    /**
     *  When the user stops moving the mouse or touching the screen, turn of the drag and resizing events.
     *  Get the final position and size of the crop and populate hidden form elements with them.
     */
    $cropBox.on("touchend mouseup", function() {
      dragState = false;
      resizeState = false;
    });
  };

  /**
   * This sets up the cropping interface with a given height and width.
   *
   * @param {jQuery} $image     Image to be rotated.
   * @param {jQuery} $container Container the image will be rotated in.
   * @param {jQuery} degrees    How many degrees to rotate the image.
   */
  var setupCrop = function(width, height) {
    if (!$previewImage.length) {
      return;
    }

    var $cropContainer = $previewImage.parent();

    // Expicitly set the dimensions of the crop area.
    $cropContainer.width(width);
    $cropContainer.height(height);

    $cropBox.insertBefore($previewImage).css({
      // Center the crop box on the image initially.
      "left"   : Math.floor((width / 2) - (minThreshold / 2)),
      "top"    : Math.floor((height / 2) - (minThreshold / 2)),
      "width"  : minThreshold,
      "height" : minThreshold,
    });

    // Initiate dragging and resizing.
    dragCropBoxInit();
    resizeCropBoxInit();

    croppingReset(width, height);
  };

  /**
   * Rotate an image in a container. When the image rotates, update the size
   * of the container so it fits. Then, translate the image to the center of
   * the new height of the container.
   *
   * @param {jQuery} $image     Image to be rotated.
   * @param {jQuery} $container Container the image will be rotated in.
   * @param {jQuery} degrees    How many degrees to rotate the image.
   */
  var rotateImage = function($image, degrees) {
    var width = $image.width();
    var height = $image.height();
    var $cropContainer = $previewImage.parent();

    // Calculate how much to translate the image by.
    var translateDiff = getTranslateDifference(width, height, degrees);

    if (degrees === 90 || degrees === 270) {
      $cropContainer.css({
        height: width,
      });

      // reset cropping events with new dimensions of crop area.
      setupCrop(height,width);
    }
    else {
      $cropContainer.css({
        height: height,
      });

      setupCrop(width,height);
    }

    // Actually do the rotation and translation.
    $image.css({
      "transform" : "rotate("+ degrees + "deg) translate(" + translateDiff + "px, " + translateDiff + "px)",
    });
  };

  /**
   * Populates fields in the main reportback form with values to use for cropping
   * and rotating on the backend.
   *
   * @param {jQuery} cropValues Object containing x, y, width and height of the crop.
   * @param {jQuery} degrees    (optional) How many degrees to rotate the image.
   */
  var populateFields = function($form) {
    // Get the hidden form elements.
    var $cropX = $form.find("input[name='crop_x']");
    var $cropY = $form.find("input[name='crop_y']");
    var $cropWidth = $form.find("input[name='crop_width']");
    var $cropHeight = $form.find("input[name='crop_height']");
    var $cropRotation = $form.find("input[name='crop_rotate']");
    var $captionField = $form.find("input[name='caption']");
    var caption = $("#dosomething-reportback-image-form").find("#caption").val();

    // Calculate cropping information.
    var cropValues = {
      top    :  Math.round(($cropBox.offset().top - $previewImage.offset().top) * scale),
      left   :  Math.round(($cropBox.offset().left - $previewImage.offset().left) * scale),
      width  :  Math.round($cropBox.outerWidth() * scale),
      height :  Math.round($cropBox.outerHeight() * scale),
      degrees:  degrees,
    };

    // Populate fields.
    $cropX.val(cropValues.left);
    $cropY.val(cropValues.top);
    $cropWidth.val(cropValues.width);
    $cropHeight.val(cropValues.height);
    $cropRotation.val(cropValues.degrees);
    $captionField.val(caption);
  };

  /**
   * Initiates cropping js.
   *
   * @param {jQuery} origImage  Image object to crop
   */
  var dsCropperInit = function(image) {
    // Store the image;
    origImage = image;

    // Get the preview image.
    $previewImage = $("#modal--crop").find(".preview");

    if (!$previewImage.length) {
      return;
    }

    // Set global valuea.
    previewImageWidth = $previewImage.width();
    previewImageHeight = $previewImage.height();
    scale = origImage.width / $previewImage.width();
    minThreshold = getMinimumSize();

    // Create the crop area.
    $previewImage.wrap($("

"));

    // Turn on cropping.
    setupCrop(previewImageWidth, previewImageHeight);

    // Rotation
    var $rotateButton = $(".image-editor").find(".-rotate");

    $rotateButton.click(function(e) {
      e.preventDefault();
      degrees = (degrees === 360) ? 90 : degrees + 90;
      rotateImage($previewImage, degrees);
    });
  };

  return {
    dsCropperInit  : dsCropperInit,
    populateFields : populateFields,
  };
});
<commit_msg>code style updates<commit_after>define(function(require) {
  "use strict";

  var $ = require("jquery");

  // Initialize variables.
  var xInitPos;
  var yInitPos;
  var offsetLeft;
  var offsetTop;
  var initialCropBoxHeight;
  var initialCropBoxWidth;
  var previewImageWidth;
  var previewImageHeight;
  var $previewImage;
  var origImage;
  var resizeState          = false;
  var dragState            = false;
  var $cropBox             = $("

");
  var resizeClickPositionX = 0;
  var resizeClickPositionY = 0;
  var scale                = 1;
  var degrees              = 0;
  var minThreshold         = 480;

  /**
   * Returns the coordinates of a touch or mouse event.
   */
  var getCoords = function(e) {
    var coords = {};
    var eventType = e.originalEvent.type;

    // Get the coordinates of a touchevent.
    if (eventType === "touchstart" || eventType === "touchmove" || eventType === "touchend") {
      coords = e.originalEvent.targetTouches[0];
    }
    // Get coordinates of mouse event.
    else {
      coords = {
        pageX: e.pageX,
        pageY: e.pageY,
      };
    }

    return coords;
  };

  /**
   * Returns a value equal to the minimum allowed crop size scaled down to fit the image.
   */
  var getMinimumSize = function() {
    return minThreshold / scale;
  };

  /**
   * Calculates what the initial size of the cropbox should be.
   *
   * @param {number} minimum     minimum size of the cropbox
   */
  // var getMinimumSize = function(minimum) {
  //   return minThreshold / scale;
  // };

  /**
   * This returns the amount to translate an image after it has been rotated so
   * so that it stays center in it's container.
   *
   * @param {number} width      Width of the image.
   * @param {number} height     height of the image.
   * @param {number} degrees    How many degrees the image has been rotated.
   */
  var getTranslateDifference = function(width, height, degrees) {
    var translateDiff = (width / 2) - (height / 2);

    if (degrees === 90 || degrees === 270) {
      return (degrees === 270) ? -(translateDiff) : translateDiff;
    }
    else {
      return 0;
    }
  };

  /**
   * Turns on the ability to drag the crop box.
   */
  var dragCropBoxInit = function() {
    // Bind touch and mouse events.
    $cropBox.on("touchstart mousedown", function(event) {
      event.preventDefault();

      var coords = getCoords(event);

      // Set the initial position of the mouse.
      xInitPos = coords.pageX;
      yInitPos = coords.pageY;

      // Sets the initial positioning of the crop box.
      if ($cropBox.length) {
        offsetLeft = parseInt($cropBox.css("left"), 10);
        offsetTop  = parseInt($cropBox.css("top"), 10);
      }

      // Turns on dragging.
      dragState = true;
    });
  };

  /**
   * Turns on the ability to resize the crop box.
   */
  var resizeCropBoxInit = function() {
    $(".resize-handle").on("touchstart mousedown", function(event) {
      event.preventDefault();

      // Grab the postioning of the event.
      var coords = getCoords(event);

      // Set the initial size of the crop box.
      if ($cropBox.length) {
        initialCropBoxHeight = parseInt($cropBox.css("height"), 10);
        initialCropBoxWidth  = parseInt($cropBox.css("width"), 10);
      }

      // Set the position of the mouse.
      resizeClickPositionX = coords.pageX;
      resizeClickPositionY = coords.pageY;

      // Turn on resizing.
      resizeState = true;
    });
  };

  /**
   * Sets up the mouse events on the cropping interface using a give width and height.
   *
   * @param {number} width     Width of the crop area.
   * @param {number} height    Height of the crop area.
   */
  var croppingReset = function (width, height) {
    // Turn off any previously bound events so
    // we can rebind them later using new settings.
    $cropBox.off("touchmove mousemove");
    $cropBox.off("touchend mouseup");

    // Bind move events to the document.
    $(document).on("touchmove mousemove", function(event) {
      var coords        = getCoords(event);
      var cropBoxHeight = parseInt($cropBox.css("height"),10);
      var cropBoxWidth  = parseInt($cropBox.css("width"),10);
      var cropBoxTop    = parseInt($cropBox.css("top"), 10);
      var cropBoxLeft   = parseInt($cropBox.css("left"), 10);

      // If dragging, drag the crop box along.
      if (dragState) {
        // Calculate how far to move the box down and right based on the mouse position.
        var moveRight = offsetLeft + (coords.pageX - xInitPos);
        var moveDown  = offsetTop + (coords.pageY - yInitPos);

        // Boundary threshold tests.
        var withinTopBounds  = (height - cropBoxHeight) > moveDown ? true : false;
        var withinLeftBounds = (width - cropBoxWidth) > moveRight ? true : false;

        // Make sure we are still within the bounds of the image and then actully move the box.
        if (withinTopBounds && (moveDown > 0)) {
          $cropBox.css("top", moveDown);
        }
        if (withinLeftBounds && (moveRight > 0)) {
          $cropBox.css( "left", moveRight);
        }
      }

      // If resizing, resize the crop box.
      if (resizeState) {
        dragState = false;
        // Calculate how much to resize the cropbox.
        var resizeHorizontal = initialCropBoxWidth + (coords.pageX - resizeClickPositionX);
        var resizeVertical   = initialCropBoxHeight + (coords.pageX - resizeClickPositionX);

        // Boundary threshold tests.
        var withinHeightBounds = (cropBoxHeight + cropBoxTop) < height ? true : false;
        var withinWidthBounds  = (cropBoxWidth + cropBoxLeft) < width ? true : false;
        var cropBoxSizeAllowed = (cropBoxWidth > minThreshold) ? true : false;
        var increasingSize     = (coords.pageX - resizeClickPositionX) > 0 ? true : false;
        var decreasingSize     = (coords.pageX - resizeClickPositionX) < 0 ? true : false;

        // Make sure we are still in the boundaries of the image, and then resize the box.
        if (withinHeightBounds && withinWidthBounds && (cropBoxSizeAllowed || increasingSize)) {
          $cropBox.css( "height", resizeVertical);
          $cropBox.css( "width", resizeHorizontal);
        }
        else if (decreasingSize && cropBoxSizeAllowed) {
          $cropBox.css( "height", resizeVertical);
          $cropBox.css( "width", resizeHorizontal);
        }
      }
    });

    /**
     *  When the user stops moving the mouse or touching the screen, turn of the drag and resizing events.
     *  Get the final position and size of the crop and populate hidden form elements with them.
     */
    $(document).on("touchend mouseup", function() {
      dragState   = false;
      resizeState = false;
    });
  };

  /**
   * This sets up the cropping interface with a given height and width.
   *
   * @param {number} width     Width of the crop area.
   * @param {number} height    Height of the crop area.
   */
  var setupCrop = function(width, height) {
    if (!$previewImage.length) {
      return;
    }

    var $cropContainer = $previewImage.parent();

    // Expicitly set the dimensions of the crop area.
    $cropContainer.width(width);
    $cropContainer.height(height);

    // Set the initial position of the cropbox in the center of the image
    // and with a minimum value of 480px.
    $cropBox.insertBefore($previewImage).css({
      "left"   : Math.floor((width / 2) - (minThreshold / 2)),
      "top"    : Math.floor((height / 2) - (minThreshold / 2)),
      "width"  : minThreshold,
      "height" : minThreshold,
    });

    // Initiate dragging and resizing.
    dragCropBoxInit();
    resizeCropBoxInit();

    croppingReset(width, height);
  };

  /**
   * Rotate an image in a container. When the image rotates, update the size
   * of the container so it fits. Then, translate the image to the center of
   * the new height of the container.
   *
   * @param {jQuery} $image     Image to be rotated.
   * @param {number} degrees    How many degrees to rotate the image.
   */
  var rotateImage = function($image, degrees) {
    var width          = $image.width();
    var height         = $image.height();
    var $cropContainer = $previewImage.parent();

    // Calculate how much to translate the image by.
    var translateDiff = getTranslateDifference(width, height, degrees);

    if (degrees === 90 || degrees === 270) {
      $cropContainer.css({
        height: width,
      });

      // reset cropping events with new dimensions of crop area.
      setupCrop(height,width);
    }
    else {
      $cropContainer.css({
        height: height,
      });

      setupCrop(width,height);
    }

    // Actually do the rotation and translation.
    $image.css({
      "transform" : "rotate("+ degrees + "deg) translate(" + translateDiff + "px, " + translateDiff + "px)",
    });
  };

  /**
   * Populates fields in the main reportback form with values to use for cropping
   * and rotating on the backend.
   *
   * @param {jQuery} form       The form to populate.
   */
  var populateFields = function($form) {
    // Get the hidden form elements.
    var $cropX        = $form.find("input[name='crop_x']");
    var $cropY        = $form.find("input[name='crop_y']");
    var $cropWidth    = $form.find("input[name='crop_width']");
    var $cropHeight   = $form.find("input[name='crop_height']");
    var $cropRotation = $form.find("input[name='crop_rotate']");
    var $captionField = $form.find("input[name='caption']");
    var caption       = $("#dosomething-reportback-image-form").find("#caption").val();

    // Calculate cropping information.
    var cropValues = {
      top     :  Math.round(($cropBox.offset().top - $previewImage.offset().top) * scale),
      left    :  Math.round(($cropBox.offset().left - $previewImage.offset().left) * scale),
      width   :  Math.round($cropBox.outerWidth() * scale),
      height  :  Math.round($cropBox.outerHeight() * scale),
      degrees :  degrees,
    };

    // Populate fields.
    $cropX.val(cropValues.left);
    $cropY.val(cropValues.top);
    $cropWidth.val(cropValues.width);
    $cropHeight.val(cropValues.height);
    $cropRotation.val(cropValues.degrees);
    $captionField.val(caption);
  };

  /**
   * Initiates cropping js.
   *
   * @param {Image} origImage  Image object to crop
   */
  var dsCropperInit = function(image) {
    // Store the image;
    origImage = image;

    // Get the preview image.
    $previewImage = $("#modal--crop").find(".preview");

    if (!$previewImage.length) {
      return;
    }

    // Set global valuea.
    previewImageWidth  = $previewImage.width();
    previewImageHeight = $previewImage.height();
    scale              = origImage.width / $previewImage.width();
    minThreshold       = getMinimumSize();

    // Create the crop area.
    $previewImage.wrap($("

"));

    // Turn on cropping.
    setupCrop(previewImageWidth, previewImageHeight);

    // Rotation
    var $rotateButton = $(".image-editor").find(".-rotate");

    $rotateButton.click(function(e) {
      e.preventDefault();
      degrees = (degrees === 360) ? 90 : degrees + 90;
      rotateImage($previewImage, degrees);
    });
  };

  return {
    dsCropperInit  : dsCropperInit,
    populateFields : populateFields,
  };
});
<|endoftext|>


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

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
/**
 * Internal dependencies
 */
import { STORY_VIEWING_LABELS } from './stories';
import { SAVED_TEMPLATES_VIEWING_LABELS } from './savedTemplates';
import { TEMPLATES_GALLERY_VIEWING_LABELS } from './templates';

export const KEYBOARD_USER_CLASS = `useskeyboard`;
export const KEYBOARD_USER_SELECTOR = `.${KEYBOARD_USER_CLASS}`;

export const Z_INDEX = {
  LAYOUT_SQUISHABLE: 2,
  LAYOUT_FIXED: 3,
  POPOVER_MENU: 10,
  TYPEAHEAD_OPTIONS: 10,
  POPOVER_PANEL: 10,
  TOASTER: 15,
};

export const APP_ROUTES = {
  MY_STORIES: '/',
  SAVED_TEMPLATES: '/saved-templates',
  TEMPLATES_GALLERY: '/templates-gallery',
  TEMPLATE_DETAIL: 'template-detail',

  EDITOR_SETTINGS: '/editor-settings',
  SUPPORT: '/support',
  STORY_ANIM_TOOL: '/story-anim-tool',
};

export const NESTED_APP_ROUTES = {
  TEMPLATES_GALLERY_DETAIL: `${APP_ROUTES.TEMPLATES_GALLERY}/${APP_ROUTES.TEMPLATE_DETAIL}`,
  SAVED_TEMPLATE_DETAIL: `${APP_ROUTES.SAVED_TEMPLATES}/${APP_ROUTES.TEMPLATE_DETAIL}`,
};

export const primaryPaths = [
  { value: APP_ROUTES.MY_STORIES, label: __('My Stories', 'web-stories') },
  {
    value: APP_ROUTES.SAVED_TEMPLATES,
    label: __('Saved Templates', 'web-stories'),
    inProgress: true,
  },
  {
    value: APP_ROUTES.TEMPLATES_GALLERY,
    label: __('Explore Templates', 'web-stories'),
  },
];

export const secondaryPaths = [
  {
    value: APP_ROUTES.EDITOR_SETTINGS,
    label: __('Editor Settings', 'web-stories'),
    inProgress: true,
  },
  {
    value: APP_ROUTES.SUPPORT,
    label: __('Support', 'web-stories'),
    inProgress: true,
  },
];

export const VIEW_STYLE = {
  GRID: 'GRID',
  LIST: 'LIST',
};

export const VIEW_STYLE_LABELS = {
  [VIEW_STYLE.GRID]: __('Switch to List View', 'web-stories'),
  [VIEW_STYLE.LIST]: __('Switch to Grid View', 'web-stories'),
};

export const ICON_METRICS = {
  VIEW_STYLE: { width: 17, height: 14 },
  LEFT_RIGHT_ARROW: { width: 16, height: 16 },
};

export const ITEMS_PER_PAGE = 20;

export const DASHBOARD_VIEWS = {
  MY_STORIES: 'MY_STORIES',
  SAVED_TEMPLATES: 'SAVED_TEMPLATES',
  TEMPLATES_GALLERY: 'TEMPLATES_GALLERY',
};
export const RESULT_LABELS = {
  [DASHBOARD_VIEWS.MY_STORIES]: { ...STORY_VIEWING_LABELS },
  [DASHBOARD_VIEWS.SAVED_TEMPLATES]: { ...SAVED_TEMPLATES_VIEWING_LABELS },
  [DASHBOARD_VIEWS.TEMPLATES_GALLERY]: { ...TEMPLATES_GALLERY_VIEWING_LABELS },
};

export * from './animation';
export * from './components';
export * from './direction';
export * from './pageStructure';
export * from './savedTemplates';
export * from './stories';
export * from './templates';
<commit_msg>request max stories possible per request<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
/**
 * Internal dependencies
 */
import { STORY_VIEWING_LABELS } from './stories';
import { SAVED_TEMPLATES_VIEWING_LABELS } from './savedTemplates';
import { TEMPLATES_GALLERY_VIEWING_LABELS } from './templates';

export const KEYBOARD_USER_CLASS = `useskeyboard`;
export const KEYBOARD_USER_SELECTOR = `.${KEYBOARD_USER_CLASS}`;

export const Z_INDEX = {
  LAYOUT_SQUISHABLE: 2,
  LAYOUT_FIXED: 3,
  POPOVER_MENU: 10,
  TYPEAHEAD_OPTIONS: 10,
  POPOVER_PANEL: 10,
  TOASTER: 15,
};

export const APP_ROUTES = {
  MY_STORIES: '/',
  SAVED_TEMPLATES: '/saved-templates',
  TEMPLATES_GALLERY: '/templates-gallery',
  TEMPLATE_DETAIL: 'template-detail',

  EDITOR_SETTINGS: '/editor-settings',
  SUPPORT: '/support',
  STORY_ANIM_TOOL: '/story-anim-tool',
};

export const NESTED_APP_ROUTES = {
  TEMPLATES_GALLERY_DETAIL: `${APP_ROUTES.TEMPLATES_GALLERY}/${APP_ROUTES.TEMPLATE_DETAIL}`,
  SAVED_TEMPLATE_DETAIL: `${APP_ROUTES.SAVED_TEMPLATES}/${APP_ROUTES.TEMPLATE_DETAIL}`,
};

export const primaryPaths = [
  { value: APP_ROUTES.MY_STORIES, label: __('My Stories', 'web-stories') },
  {
    value: APP_ROUTES.SAVED_TEMPLATES,
    label: __('Saved Templates', 'web-stories'),
    inProgress: true,
  },
  {
    value: APP_ROUTES.TEMPLATES_GALLERY,
    label: __('Explore Templates', 'web-stories'),
  },
];

export const secondaryPaths = [
  {
    value: APP_ROUTES.EDITOR_SETTINGS,
    label: __('Editor Settings', 'web-stories'),
    inProgress: true,
  },
  {
    value: APP_ROUTES.SUPPORT,
    label: __('Support', 'web-stories'),
    inProgress: true,
  },
];

export const VIEW_STYLE = {
  GRID: 'GRID',
  LIST: 'LIST',
};

export const VIEW_STYLE_LABELS = {
  [VIEW_STYLE.GRID]: __('Switch to List View', 'web-stories'),
  [VIEW_STYLE.LIST]: __('Switch to Grid View', 'web-stories'),
};

export const ICON_METRICS = {
  VIEW_STYLE: { width: 17, height: 14 },
  LEFT_RIGHT_ARROW: { width: 16, height: 16 },
};

export const ITEMS_PER_PAGE = 100; // default max per request

export const DASHBOARD_VIEWS = {
  MY_STORIES: 'MY_STORIES',
  SAVED_TEMPLATES: 'SAVED_TEMPLATES',
  TEMPLATES_GALLERY: 'TEMPLATES_GALLERY',
};
export const RESULT_LABELS = {
  [DASHBOARD_VIEWS.MY_STORIES]: { ...STORY_VIEWING_LABELS },
  [DASHBOARD_VIEWS.SAVED_TEMPLATES]: { ...SAVED_TEMPLATES_VIEWING_LABELS },
  [DASHBOARD_VIEWS.TEMPLATES_GALLERY]: { ...TEMPLATES_GALLERY_VIEWING_LABELS },
};

export * from './animation';
export * from './components';
export * from './direction';
export * from './pageStructure';
export * from './savedTemplates';
export * from './stories';
export * from './templates';
<|endoftext|>


<commit_before>/*
  Bootstrap - File Input
  ======================

  This is meant to convert all file input tags into a set of elements that displays consistently in all browsers.

  Converts all
  <input type="file">
  into Bootstrap buttons
  Browse

*/
$(function() {

$.fn.bootstrapFileInput = function() {

  this.each(function(i,elem){

    var $elem = $(elem);

    // Maybe some fields don't need to be standardized.
    if (typeof $elem.attr('data-bfi-disabled') != 'undefined') {
      return;
    }

    // Set the word to be displayed on the button
    var buttonWord = 'Browse';

    if (typeof $elem.attr('title') != 'undefined') {
      buttonWord = $elem.attr('title');
    }

    var className = '';

    if (!!$elem.attr('class')) {
      className = ' ' + $elem.attr('class');
    }

    // Now we're going to wrap that input field with a Bootstrap button.
    // The input will actually still be there, it will just be float above and transparent (done with the CSS).
    $elem.wrap('').parent().prepend(buttonWord);
  })

  // After we have found all of the file inputs let's apply a listener for tracking the mouse movement.
  // This is important because the in order to give the illusion that this is a button in FF we actually need to move the button from the file input under the cursor. Ugh.
  .promise().done( function(){

    // As the cursor moves over our new Bootstrap button we need to adjust the position of the invisible file input Browse button to be under the cursor.
    // This gives us the pointer cursor that FF denies us
    $('.file-input-wrapper').mousemove(function(cursor) {

      var input, wrapper,
        wrapperX, wrapperY,
        inputWidth, inputHeight,
        cursorX, cursorY;

      // This wrapper element (the button surround this file input)
      wrapper = $(this);
      // The invisible file input element
      input = wrapper.find("input");
      // The left-most position of the wrapper
      wrapperX = wrapper.offset().left;
      // The top-most position of the wrapper
      wrapperY = wrapper.offset().top;
      // The with of the browsers input field
      inputWidth= input.width();
      // The height of the browsers input field
      inputHeight= input.height();
      //The position of the cursor in the wrapper
      cursorX = cursor.pageX;
      cursorY = cursor.pageY;

      //The positions we are to move the invisible file input
      // The 20 at the end is an arbitrary number of pixels that we can shift the input such that cursor is not pointing at the end of the Browse button but somewhere nearer the middle
      moveInputX = cursorX - wrapperX - inputWidth + 20;
      // Slides the invisible input Browse button to be positioned middle under the cursor
      moveInputY = cursorY- wrapperY - (inputHeight/2);

      // Apply the positioning styles to actually move the invisible file input
      input.css({
        left:moveInputX,
        top:moveInputY
      });
    });

    $('body').on('change', '.file-input-wrapper input[type=file]', function(){

      var fileName;
      fileName = $(this).val();

      // Remove any previous file names
      $(this).parent().next('.file-input-name').remove();
      if (!!$(this).prop('files') && $(this).prop('files').length > 1) {
        fileName = $(this)[0].files.length+' files';
        //$(this).parent().after(''+$(this)[0].files.length+' files');
      }
      else {
        // var fakepath = 'C:\\fakepath\\';
        // fileName = $(this).val().replace('C:\\fakepath\\','');
        fileName = fileName.substring(fileName.lastIndexOf('\\')+1,fileName.length);
      }

      $(this).parent().after(''+fileName+'');
    });

  });

};

// Add the styles before the first stylesheet
// This ensures they can be easily overridden with developer styles
var cssHtml = '';
$('link[rel=stylesheet]').eq(0).before(cssHtml);

});<commit_msg>changes to file input plugin - PR'd grevory/bootstrap-file-input#27<commit_after>/*
  Bootstrap - File Input
  ======================

  This is meant to convert all file input tags into a set of elements that displays consistently in all browsers.

  Converts all
  <input type="file">
  into Bootstrap buttons
  Browse

*/

$.fn.bootstrapFileInput = function(prependIcon) {

  this.each(function(i,elem){

    var $elem = $(elem);

    // Maybe some fields don't need to be standardized.
    if (typeof $elem.attr('data-bfi-disabled') != 'undefined') {
      return;
    }

    // Set the word to be displayed on the button
    var buttonWord = 'Browse';

    if (typeof $elem.attr('title') != 'undefined') {
      buttonWord = $elem.attr('title');
    }

    var className = '';

    if (!!$elem.attr('class')) {
      className = ' ' + $elem.attr('class');
    }

    // Now we're going to wrap that input field with a Bootstrap button.
    // The input will actually still be there, it will just be float above and transparent (done with the CSS).
    $elem.wrap('').parent().prepend(buttonWord);

    if(prependIcon)
      $elem.parent().prepend(' ')
  })

  // After we have found all of the file inputs let's apply a listener for tracking the mouse movement.
  // This is important because the in order to give the illusion that this is a button in FF we actually need to move the button from the file input under the cursor. Ugh.
  .promise().done( function(){

    // As the cursor moves over our new Bootstrap button we need to adjust the position of the invisible file input Browse button to be under the cursor.
    // This gives us the pointer cursor that FF denies us
    $('.file-input-wrapper').mousemove(function(cursor) {

      var input, wrapper,
        wrapperX, wrapperY,
        inputWidth, inputHeight,
        cursorX, cursorY;

      // This wrapper element (the button surround this file input)
      wrapper = $(this);
      // The invisible file input element
      input = wrapper.find("input");
      // The left-most position of the wrapper
      wrapperX = wrapper.offset().left;
      // The top-most position of the wrapper
      wrapperY = wrapper.offset().top;
      // The with of the browsers input field
      inputWidth= input.width();
      // The height of the browsers input field
      inputHeight= input.height();
      //The position of the cursor in the wrapper
      cursorX = cursor.pageX;
      cursorY = cursor.pageY;

      //The positions we are to move the invisible file input
      // The 20 at the end is an arbitrary number of pixels that we can shift the input such that cursor is not pointing at the end of the Browse button but somewhere nearer the middle
      moveInputX = cursorX - wrapperX - inputWidth + 20;
      // Slides the invisible input Browse button to be positioned middle under the cursor
      moveInputY = cursorY- wrapperY - (inputHeight/2);

      // Apply the positioning styles to actually move the invisible file input
      input.css({
        left:moveInputX,
        top:moveInputY
      });
    });

    $('body').on('change', '.file-input-wrapper input[type=file]', function(){

      var fileName;
      fileName = $(this).val();

      // Remove any previous file names
      $(this).parent().next('.file-input-name').remove();
      if (!!$(this).prop('files') && $(this).prop('files').length > 1) {
        fileName = $(this)[0].files.length+' files';
        //$(this).parent().after(''+$(this)[0].files.length+' files');
      }
      else {
        // var fakepath = 'C:\\fakepath\\';
        // fileName = $(this).val().replace('C:\\fakepath\\','');
        fileName = fileName.substring(fileName.lastIndexOf('\\')+1,fileName.length);
      }

      $(this).parent().after(''+fileName+'');
    });

  });

};

$(function(){

// Add the styles before the first stylesheet
// This ensures they can be easily overridden with developer styles
var cssHtml = '';
$('link[rel=stylesheet]').eq(0).before(cssHtml);

});<|endoftext|>


<commit_before>var map = require('map-stream')
  , zmq = require('zmq')
  , client = zmq.socket('sub')
  , port = 'tcp://127.0.0.1:10000';

/**
 * dispatcher
 * @returns {Stream}
 */
module.exports = function () {
  var stream = map(function (data, fn) {
    fn(null, JSON.stringify(data));
  });
  client.connect(port);
  client.subscribe('badjs');
  socket.on('mesage', function (data) {
    stream.write(data);
  });
  return stream;
};<commit_msg>update<commit_after>var map = require('map-stream')
  , zmq = require('zmq')
  , client = zmq.socket('sub')
  , port = 'tcp://127.0.0.1:10000';

/**
 * dispatcher
 * @returns {Stream}
 */
module.exports = function () {
  var stream = map(function (data, fn) {
    fn(null, JSON.stringify(data));
  });
  client.connect(port);
  client.subscribe('badjs');
  client.on('mesage', function (data) {
    stream.write(data);
  });
  return stream;
};<|endoftext|>


<commit_before>/* eslint-env browser */
/* exported post */

function log() {
    var txt = [];
    for (var it in arguments) {
        txt.push(arguments[it]);
    }
    nlapiLogExecution('DEBUG', 'log', JSON.stringify(txt));
}

var post = function (datain) {
    'use strict';

    //ROUTER

    switch (datain.action) {
    case 'download':
        return download(datain);
    case 'upload':
        return upload(datain);
    case 'url':
        return url(datain);
    default:
        return {message: 'invalid action'};
    }
};

var upload = function (datain) {

    if (!datain.filepath) throw nlapiCreateError('PARAM_ERR', 'No file path specified', true);
    if (!datain.rootpath) throw nlapiCreateError('PARAM_ERR', 'No destination root path specified', true);

    var info = pathInfo(datain.filepath, datain.rootpath, true);
    var body = datain.content;
    if (~NON_BINARY_FILETYPES.indexOf(info.nsfileext))
        body = nlapiDecrypt(datain.content, 'base64');

    if (info.filename) {
        var file = nlapiCreateFile(info.filename, info.nsfileext, body);
        file.setFolder(info.folderid);
        if (datain.isonline){
            file.setIsOnline(true);
        }
        var r = JSON.stringify(nlapiSubmitFile(file));
        nlapiLogExecution('DEBUG', 'up!', r);
        return {message: 'Uploaded ' + info.filename + ' to file id ' + r, fileid: Number(r)};
    }
};

var download = function (datain) {
    if (!(datain.files instanceof Array)) {
        datain.files = [datain.files];
    }

    var errors = [];
    function getFileData(file, info, folder) {
        var contents = file.getValue();

        if (~NON_BINARY_FILETYPES.indexOf(file.getType()))
            contents = nlapiEncrypt(contents, 'base64');

        var base;
        if (info.tails) {
            var curr = info.tails.filter(function(t){
                return t.folderid == folder;
            })[0];
            if (!curr) throw nlapiCreateError('RECURSIVE_SEARCH', 'Unexpected execution.', true);
            base = curr.baserelative;
        } else {
            base = info.baserelative;
        }

        return {
            path: base + '/' + file.getName(),
            contents: contents
        };
    }

    var outfiles = [];

    datain.files.forEach(function (glob) {
        var info = pathInfo(glob, datain.rootpath);

        //found out nlapiSearchRecord('file') filtered by folder returns a recursive search,
        //which turns out to be nasty for performance.
        //so, split in 2 cases. If the path seems to be absolute, load directly. If not, execute the search.
        if ( /\*|\%/g.test(glob) ) {

            var folders_in = ( info.tails ) ?
                info.tails.map( function(t) { return t.folderid; } ) :
                [info.folderid];

            var filter = ['folder', 'anyof', folders_in];

            if ( info.filename == '*' || info.filename == '*.*' || info.filename == '**' ) { /* -- */}
            else if( /\*/g.test(info.filename) ) {
                filter.push('and');
                filter.push(['name', 'contains', info.filename.replace(/\*/g, '%')]);
            } else {
                filter.push('and');
                filter.push(['name', 'is', info.filename]);
            }

            var columns = ['name', 'filetype', 'folder'].map(function (i) {
                return new nlobjSearchColumn(i);
            });

            var files = nlapiSearchRecord('file', null, filter, columns) || [];
            var addFiles = files.filter(function (resFile) {
                return folders_in.filter(function(f){
                    return f == resFile.getValue('folder');
                }).length > 0;
            }).map(function (resFile) {
                var file = nlapiLoadFile(resFile.getId());
                return getFileData(file, info, resFile.getValue('folder') );
            });

            outfiles = outfiles.concat(addFiles);
            //case 2: direct load
        } else {
            try {
                var file = nlapiLoadFile(info.pathabsolute.substr(1));
                outfiles = outfiles.concat([getFileData(file, info)]);
            } catch (e) {
                errors.push(e);
            }
        }
    });

    var out = {files: outfiles};
    if (errors.length) out.error = errors;
    log(out);
    return out;

};

function url(inp) {
    var file = nlapiLoadFile(inp.path);
    return {
        url : file.getURL()
    };
}

var NON_BINARY_FILETYPES = [
    'CSV',
    'HTMLDOC',
    'JAVASCRIPT',
    'MESSAGERFC',
    'PLAINTEXT',
    'POSTSCRIPT',
    'RTF',
    'SMS',
    'STYLESHEET',
    'XMLDOC'
];

var EXT_TYPES = {
      bmp: 'BMPIMAGE',
      css: 'STYLESHEET',
      csv: 'CSV',
      doc: 'WORD',
      dwg: 'AUTOCAD',
      eml: 'MESSAGERFC',
      eot : 'EOT',
      gif: 'GIFIMAGE',
      gz: 'GZIP',
      htm: 'HTMLDOC',
      html: 'HTMLDOC',
      ico: 'ICON',
      jpg: 'JPGIMAGE',
      js: 'JAVASCRIPT',
      mov: 'QUICKTIME',
      mp3: 'MP3',
      mpg: 'MPEGMOVIE',
      mpp: 'MSPROJECT',
      pdf: 'PDF',
      pjpeg: 'PJPGIMAGE',
      png: 'PNGIMAGE',
      ppt: 'POWERPOINT',
      ps: 'POSTSCRIPT',
      rtf: 'RTF',
      sms: 'SMS',
      svg : 'SVG',
      swf: 'FLASH',
      tiff: 'TIFFIMAGE',
      ttf : 'TTF',
      txt: 'PLAINTEXT',
      vsd: 'VISIO',
      woff : 'WOFF',
      woff2: 'WOFF2',
      xls: 'EXCEL',
      xml: 'XMLDOC',
      zip: 'ZIP'
};

function pathInfo(pathIn, baseIn, createFolders) {
    if (baseIn === void 0) { baseIn = '/'; }
    if (createFolders === void 0) { createFolders = false; }
    if (pathIn.charAt(0) == '/') {
        pathIn = pathIn.substr(1);
        baseIn = '/';
    }
    if (baseIn.substr(-1) != '/')
        baseIn += '/';
    var absPath = (baseIn + pathIn)
        .replace(/[\\]/g, '/');
    var _split = absPath.split('/');
    var filename = _split[_split.length - 1];
    _split.length = _split.length - 1;
    var absBase = _split.join('/');
    var absBaseSplit = _split.slice(1);
    var hasWildcard = absBaseSplit.some(function (i) { return i == '**'; });
    var _ext = filename && (filename.indexOf('.') > 0) ? filename.split('.').pop() : null;
    var prevFolder = null;
    if (!hasWildcard) {
        absBaseSplit.forEach(function (folderName) {
            var filters = [
                ['name', 'is', folderName],
                'and',
                ['parent', 'anyof', (prevFolder || '@NONE@')]
            ];
            var res_folder = nlapiSearchRecord('folder', null, filters);
            if (!res_folder && !createFolders) {
                throw nlapiCreateError('FOLDER_NOT_FOUND', 'Folder ' + folderName + ' not found!', true);
            }
            else if (!res_folder && createFolders) {
                var newFolderRec = nlapiCreateRecord('folder');
                newFolderRec.setFieldValue('name', folderName);
                newFolderRec.setFieldValue('parent', prevFolder);
                prevFolder = nlapiSubmitRecord(newFolderRec);
            }
            else {
                prevFolder = res_folder[0].getId();
            }
        });
        return {
            folderid: prevFolder,
            filename: filename ? filename : null,
            fileext: _ext,
            nsfileext: _ext ? EXT_TYPES[_ext] : null,
            pathabsolute: filename ? absPath : null,
            pathrelative: filename ? _relativePath(absPath, baseIn) : null,
            baseabsolute: absBase,
            baserelative: _relativePath(absBase, baseIn)
        };
    }
    else {
        var preWildcard_1 = '', postWildcard_1 = '', isAfter_1 = false;
        absBaseSplit.forEach(function (item) {
            if (item == '**')
                isAfter_1 = true;
            else if (isAfter_1)
                postWildcard_1 += '/' + item;
            else {
                preWildcard_1 += '/' + item;
            }
        });
        var found = allFolders().filter(function (folder) {
            var pre = !preWildcard_1.length || (folder.abspath.substr(0, preWildcard_1.length) == preWildcard_1);
            var post = !postWildcard_1.length || (folder.abspath.substr(-postWildcard_1.length) == postWildcard_1);
            return pre && post;
        }).map(function (folder) {
            var pabs = filename ? folder.abspath + '/' + filename : null;
            return {
                folderid: folder.id,
                pathabsolute: pabs,
                pathrelative: filename ? _relativePath(pabs, baseIn) : null,
                baseabsolute: folder.abspath,
                baserelative: _relativePath(folder.abspath, baseIn)
            };
        });
        return {
            filename: filename ? filename : null,
            fileext: _ext,
            nsfileext: _ext ? EXT_TYPES[_ext] : null,
            baseabsolute: preWildcard_1,
            baserelative: _relativePath(preWildcard_1, baseIn),
            tails: found
        };
    }
}

var __allFoldersMemo;
function allFolders() {
    if (__allFoldersMemo) return __allFoldersMemo;
    var _allFolders = Search.big('folder', null, Search.cols(['name', 'parent']));
    var allFolders = _allFolders.map(Search.collection);
    var foldersIdxParent = allFolders.reduce(function (bef, curr) {
        curr.parent = curr.parent || '_ROOT';
        bef[curr.parent] = bef[curr.parent] || [];
        bef[curr.parent].push(curr);
        return bef;
    }, {});
    foldersIdxParent['_ROOT'].forEach(function (item) {
        function swipe(f) {
            if (foldersIdxParent[f.id]) {
                foldersIdxParent[f.id].forEach(function (inner) {
                    inner.abspath = f.abspath + '/' + inner.name;
                    swipe(inner);
                });
            }
        }
        item.abspath = '/' + item.name;
        swipe(item);
    });
    __allFoldersMemo = allFolders;
    return allFolders;
}

function _relativePath(src, relativeTo) {
    var o;
    if (src.substr(0, relativeTo.length) == relativeTo) {
        o = src.substr(relativeTo.length);
    }
    else {
        var s_src = src.split('/').filter(function (i) { return i == true; });
        var s_rel = relativeTo.split('/').filter(function (i) { return i == true; });
        var count = 0, walk = '';
        for (var x = 0; x < s_src.length; x++) {
            if (s_rel[x] == s_src[x])
                count++;
            else {
                walk += '/' + s_src[x];
            }
        }
        for (x = 0; x < count; x++) {
            walk = '../' + walk;
        }
        o = walk;
    }
    return o || '.';
}

// ----

var Search = {};

Search.big = function (recordtype, filters, columns) {
    var res = nlapiCreateSearch(recordtype, filters, columns).runSearch();
    var res_chunk, start_idx = 0, res_final = [];
    do {
        res_chunk = res.getResults(start_idx, start_idx + 1000) || [];
        res_final = res_final.concat(res_chunk);
        start_idx += 1000;
    } while (res_chunk.length);
    return res_final;
};

Search.cols = function (cols) {
    return cols.map(function (coluna) {
        if (typeof coluna == 'string') {
            var split = coluna.split('.');
            if (split[1])
                return new nlobjSearchColumn(split[1], split[0]);
            return new nlobjSearchColumn(split[0]);
        }
        else if (coluna instanceof nlobjSearchColumn) {
            return coluna;
        }
        else
            throw nlapiCreateError('mapSearchCol', 'Entrada inválida');
    });
};

Search.collection = function (result) {
    var columns = result.getAllColumns() || [];
    var ret = columns.reduce(function (prev, curr) {
        var name, join = curr.getJoin();
        if (join) {
            name = join + '.' + curr.getName();
        }
        else {
            name = curr.getName();
        }
        prev[name] = result.getValue(curr);
        if (result.getText(curr))
            prev.textref[name] = result.getText(curr);
        return prev;
    }, { textref: {} });
    ret['id'] = result.getId();
    return ret;
};
<commit_msg>Add support for JSON files<commit_after>/* eslint-env browser */
/* exported post */

function log() {
    var txt = [];
    for (var it in arguments) {
        txt.push(arguments[it]);
    }
    nlapiLogExecution('DEBUG', 'log', JSON.stringify(txt));
}

var post = function (datain) {
    'use strict';

    //ROUTER

    switch (datain.action) {
    case 'download':
        return download(datain);
    case 'upload':
        return upload(datain);
    case 'url':
        return url(datain);
    default:
        return {message: 'invalid action'};
    }
};

var upload = function (datain) {

    if (!datain.filepath) throw nlapiCreateError('PARAM_ERR', 'No file path specified', true);
    if (!datain.rootpath) throw nlapiCreateError('PARAM_ERR', 'No destination root path specified', true);

    var info = pathInfo(datain.filepath, datain.rootpath, true);
    var body = datain.content;
    if (~NON_BINARY_FILETYPES.indexOf(info.nsfileext))
        body = nlapiDecrypt(datain.content, 'base64');

    if (info.filename) {
        var file = nlapiCreateFile(info.filename, info.nsfileext, body);
        file.setFolder(info.folderid);
        if (datain.isonline){
            file.setIsOnline(true);
        }
        var r = JSON.stringify(nlapiSubmitFile(file));
        nlapiLogExecution('DEBUG', 'up!', r);
        return {message: 'Uploaded ' + info.filename + ' to file id ' + r, fileid: Number(r)};
    }
};

var download = function (datain) {
    if (!(datain.files instanceof Array)) {
        datain.files = [datain.files];
    }

    var errors = [];
    function getFileData(file, info, folder) {
        var contents = file.getValue();

        if (~NON_BINARY_FILETYPES.indexOf(file.getType()))
            contents = nlapiEncrypt(contents, 'base64');

        var base;
        if (info.tails) {
            var curr = info.tails.filter(function(t){
                return t.folderid == folder;
            })[0];
            if (!curr) throw nlapiCreateError('RECURSIVE_SEARCH', 'Unexpected execution.', true);
            base = curr.baserelative;
        } else {
            base = info.baserelative;
        }

        return {
            path: base + '/' + file.getName(),
            contents: contents
        };
    }

    var outfiles = [];

    datain.files.forEach(function (glob) {
        var info = pathInfo(glob, datain.rootpath);

        //found out nlapiSearchRecord('file') filtered by folder returns a recursive search,
        //which turns out to be nasty for performance.
        //so, split in 2 cases. If the path seems to be absolute, load directly. If not, execute the search.
        if ( /\*|\%/g.test(glob) ) {

            var folders_in = ( info.tails ) ?
                info.tails.map( function(t) { return t.folderid; } ) :
                [info.folderid];

            var filter = ['folder', 'anyof', folders_in];

            if ( info.filename == '*' || info.filename == '*.*' || info.filename == '**' ) { /* -- */}
            else if( /\*/g.test(info.filename) ) {
                filter.push('and');
                filter.push(['name', 'contains', info.filename.replace(/\*/g, '%')]);
            } else {
                filter.push('and');
                filter.push(['name', 'is', info.filename]);
            }

            var columns = ['name', 'filetype', 'folder'].map(function (i) {
                return new nlobjSearchColumn(i);
            });

            var files = nlapiSearchRecord('file', null, filter, columns) || [];
            var addFiles = files.filter(function (resFile) {
                return folders_in.filter(function(f){
                    return f == resFile.getValue('folder');
                }).length > 0;
            }).map(function (resFile) {
                var file = nlapiLoadFile(resFile.getId());
                return getFileData(file, info, resFile.getValue('folder') );
            });

            outfiles = outfiles.concat(addFiles);
            //case 2: direct load
        } else {
            try {
                var file = nlapiLoadFile(info.pathabsolute.substr(1));
                outfiles = outfiles.concat([getFileData(file, info)]);
            } catch (e) {
                errors.push(e);
            }
        }
    });

    var out = {files: outfiles};
    if (errors.length) out.error = errors;
    log(out);
    return out;

};

function url(inp) {
    var file = nlapiLoadFile(inp.path);
    return {
        url : file.getURL()
    };
}

var NON_BINARY_FILETYPES = [
    'CSV',
    'HTMLDOC',
    'JAVASCRIPT',
    'MESSAGERFC',
    'PLAINTEXT',
    'POSTSCRIPT',
    'RTF',
    'SMS',
    'STYLESHEET',
    'XMLDOC'
];

var EXT_TYPES = {
      bmp: 'BMPIMAGE',
      css: 'STYLESHEET',
      csv: 'CSV',
      doc: 'WORD',
      dwg: 'AUTOCAD',
      eml: 'MESSAGERFC',
      eot : 'EOT',
      gif: 'GIFIMAGE',
      gz: 'GZIP',
      htm: 'HTMLDOC',
      html: 'HTMLDOC',
      ico: 'ICON',
      jpg: 'JPGIMAGE',
      js: 'JAVASCRIPT',
      json: 'PLAINTEXT',
      mov: 'QUICKTIME',
      mp3: 'MP3',
      mpg: 'MPEGMOVIE',
      mpp: 'MSPROJECT',
      pdf: 'PDF',
      pjpeg: 'PJPGIMAGE',
      png: 'PNGIMAGE',
      ppt: 'POWERPOINT',
      ps: 'POSTSCRIPT',
      rtf: 'RTF',
      sms: 'SMS',
      svg : 'SVG',
      swf: 'FLASH',
      tiff: 'TIFFIMAGE',
      ttf : 'TTF',
      txt: 'PLAINTEXT',
      vsd: 'VISIO',
      woff : 'WOFF',
      woff2: 'WOFF2',
      xls: 'EXCEL',
      xml: 'XMLDOC',
      zip: 'ZIP'
};

function pathInfo(pathIn, baseIn, createFolders) {
    if (baseIn === void 0) { baseIn = '/'; }
    if (createFolders === void 0) { createFolders = false; }
    if (pathIn.charAt(0) == '/') {
        pathIn = pathIn.substr(1);
        baseIn = '/';
    }
    if (baseIn.substr(-1) != '/')
        baseIn += '/';
    var absPath = (baseIn + pathIn)
        .replace(/[\\]/g, '/');
    var _split = absPath.split('/');
    var filename = _split[_split.length - 1];
    _split.length = _split.length - 1;
    var absBase = _split.join('/');
    var absBaseSplit = _split.slice(1);
    var hasWildcard = absBaseSplit.some(function (i) { return i == '**'; });
    var _ext = filename && (filename.indexOf('.') > 0) ? filename.split('.').pop() : null;
    var prevFolder = null;
    if (!hasWildcard) {
        absBaseSplit.forEach(function (folderName) {
            var filters = [
                ['name', 'is', folderName],
                'and',
                ['parent', 'anyof', (prevFolder || '@NONE@')]
            ];
            var res_folder = nlapiSearchRecord('folder', null, filters);
            if (!res_folder && !createFolders) {
                throw nlapiCreateError('FOLDER_NOT_FOUND', 'Folder ' + folderName + ' not found!', true);
            }
            else if (!res_folder && createFolders) {
                var newFolderRec = nlapiCreateRecord('folder');
                newFolderRec.setFieldValue('name', folderName);
                newFolderRec.setFieldValue('parent', prevFolder);
                prevFolder = nlapiSubmitRecord(newFolderRec);
            }
            else {
                prevFolder = res_folder[0].getId();
            }
        });
        return {
            folderid: prevFolder,
            filename: filename ? filename : null,
            fileext: _ext,
            nsfileext: _ext ? EXT_TYPES[_ext] : null,
            pathabsolute: filename ? absPath : null,
            pathrelative: filename ? _relativePath(absPath, baseIn) : null,
            baseabsolute: absBase,
            baserelative: _relativePath(absBase, baseIn)
        };
    }
    else {
        var preWildcard_1 = '', postWildcard_1 = '', isAfter_1 = false;
        absBaseSplit.forEach(function (item) {
            if (item == '**')
                isAfter_1 = true;
            else if (isAfter_1)
                postWildcard_1 += '/' + item;
            else {
                preWildcard_1 += '/' + item;
            }
        });
        var found = allFolders().filter(function (folder) {
            var pre = !preWildcard_1.length || (folder.abspath.substr(0, preWildcard_1.length) == preWildcard_1);
            var post = !postWildcard_1.length || (folder.abspath.substr(-postWildcard_1.length) == postWildcard_1);
            return pre && post;
        }).map(function (folder) {
            var pabs = filename ? folder.abspath + '/' + filename : null;
            return {
                folderid: folder.id,
                pathabsolute: pabs,
                pathrelative: filename ? _relativePath(pabs, baseIn) : null,
                baseabsolute: folder.abspath,
                baserelative: _relativePath(folder.abspath, baseIn)
            };
        });
        return {
            filename: filename ? filename : null,
            fileext: _ext,
            nsfileext: _ext ? EXT_TYPES[_ext] : null,
            baseabsolute: preWildcard_1,
            baserelative: _relativePath(preWildcard_1, baseIn),
            tails: found
        };
    }
}

var __allFoldersMemo;
function allFolders() {
    if (__allFoldersMemo) return __allFoldersMemo;
    var _allFolders = Search.big('folder', null, Search.cols(['name', 'parent']));
    var allFolders = _allFolders.map(Search.collection);
    var foldersIdxParent = allFolders.reduce(function (bef, curr) {
        curr.parent = curr.parent || '_ROOT';
        bef[curr.parent] = bef[curr.parent] || [];
        bef[curr.parent].push(curr);
        return bef;
    }, {});
    foldersIdxParent['_ROOT'].forEach(function (item) {
        function swipe(f) {
            if (foldersIdxParent[f.id]) {
                foldersIdxParent[f.id].forEach(function (inner) {
                    inner.abspath = f.abspath + '/' + inner.name;
                    swipe(inner);
                });
            }
        }
        item.abspath = '/' + item.name;
        swipe(item);
    });
    __allFoldersMemo = allFolders;
    return allFolders;
}

function _relativePath(src, relativeTo) {
    var o;
    if (src.substr(0, relativeTo.length) == relativeTo) {
        o = src.substr(relativeTo.length);
    }
    else {
        var s_src = src.split('/').filter(function (i) { return i == true; });
        var s_rel = relativeTo.split('/').filter(function (i) { return i == true; });
        var count = 0, walk = '';
        for (var x = 0; x < s_src.length; x++) {
            if (s_rel[x] == s_src[x])
                count++;
            else {
                walk += '/' + s_src[x];
            }
        }
        for (x = 0; x < count; x++) {
            walk = '../' + walk;
        }
        o = walk;
    }
    return o || '.';
}

// ----

var Search = {};

Search.big = function (recordtype, filters, columns) {
    var res = nlapiCreateSearch(recordtype, filters, columns).runSearch();
    var res_chunk, start_idx = 0, res_final = [];
    do {
        res_chunk = res.getResults(start_idx, start_idx + 1000) || [];
        res_final = res_final.concat(res_chunk);
        start_idx += 1000;
    } while (res_chunk.length);
    return res_final;
};

Search.cols = function (cols) {
    return cols.map(function (coluna) {
        if (typeof coluna == 'string') {
            var split = coluna.split('.');
            if (split[1])
                return new nlobjSearchColumn(split[1], split[0]);
            return new nlobjSearchColumn(split[0]);
        }
        else if (coluna instanceof nlobjSearchColumn) {
            return coluna;
        }
        else
            throw nlapiCreateError('mapSearchCol', 'Entrada inválida');
    });
};

Search.collection = function (result) {
    var columns = result.getAllColumns() || [];
    var ret = columns.reduce(function (prev, curr) {
        var name, join = curr.getJoin();
        if (join) {
            name = join + '.' + curr.getName();
        }
        else {
            name = curr.getName();
        }
        prev[name] = result.getValue(curr);
        if (result.getText(curr))
            prev.textref[name] = result.getText(curr);
        return prev;
    }, { textref: {} });
    ret['id'] = result.getId();
    return ret;
};
<|endoftext|>


<commit_before>///import core
///commands 超链接,取消链接
///commandsName  Link,Unlink
///commandsTitle  超链接,取消链接
///commandsDialog  dialogs\link\link.html
/**
 * 超链接
 * @function
 * @name baidu.editor.execCommand
 * @param   {String}   cmdName     link插入超链接
 * @param   {Object}  options         url地址，title标题，target是否打开新页
 * @author zhanyi
 */
/**
 * 取消链接
 * @function
 * @name baidu.editor.execCommand
 * @param   {String}   cmdName     unlink取消链接
 * @author zhanyi
 */
(function() {
    function optimize( range ) {
        var start = range.startContainer,end = range.endContainer;

        if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {
            range.setStartBefore( start );
        }
        if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {
            range.setEndAfter( end );
        }
    }

    UE.commands['unlink'] = {
        execCommand : function() {
            var range = this.selection.getRange(),
                bookmark;
            if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){
                return;
            }
            bookmark = range.createBookmark();
            optimize( range );
            range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();
        },
        queryCommandState : function(){
            return !this.highlight && this.queryCommandValue('link') ?  0 : -1;
        }

    };
    function doLink(range,opt,me){
        var rngClone = range.cloneRange(),
            link = me.queryCommandValue('link');
        optimize( range = range.adjustmentBoundary() );
        var start = range.startContainer;
        if(start.nodeType == 1 && link){
            start = start.childNodes[range.startOffset];
            if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){
                start[browser.ie ? 'innerText' : 'textContent'] =  utils.html(opt.textValue||opt.href);

            }
        }
        if( !rngClone.collapsed || link){
            range.removeInlineStyle( 'a' );
            rngClone = range.cloneRange();
        }

        if ( rngClone.collapsed ) {
            var a = range.document.createElement( 'a'),
                text = '';
            if(opt.textValue){

                text =   utils.html(opt.textValue);
                delete opt.textValue;
            }else{
                text =   utils.html(opt.href);

            }
            domUtils.setAttributes( a, opt );
            start =  domUtils.findParentByTagName( rngClone.startContainer, 'a', true );
            if(start && domUtils.isInNodeEndBoundary(rngClone,start)){
                range.setStartAfter(start).collapse(true);

            }
            a[browser.ie ? 'innerText' : 'textContent'] = text;
            range.insertNode(a).selectNode( a );
        } else {
            range.applyInlineStyle( 'a', opt );

        }
    }
    UE.commands['link'] = {
        execCommand : function( cmdName, opt ) {
            var range;
            opt.data_ue_src && (opt.data_ue_src = utils.unhtml(opt.data_ue_src,/[<">]/g));
            opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g));
            opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g));
            doLink(range=this.selection.getRange(),opt,this);
            //闭合都不加占位符，如果加了会在a后边多个占位符节点，导致a是图片背景组成的列表，出现空白问题
            range.collapse().select(true);

        },
        queryCommandValue : function() {
            var range = this.selection.getRange(),
                node;

            if ( range.collapsed ) {
//                    node = this.selection.getStart();
                //在ie下getstart()取值偏上了
                node = range.startContainer;
                node = node.nodeType == 1 ? node : node.parentNode;

                if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {

                    return node;
                }
            } else {
                //trace:1111  如果是
xx
 startContainer是p就会找不到a
                range.shrinkBoundary();
                var start = range.startContainer.nodeType  == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],
                    end =  range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],

                    common = range.getCommonAncestor();

                node = domUtils.findParentByTagName( common, 'a', true );
                if ( !node && common.nodeType == 1){

                    var as = common.getElementsByTagName( 'a' ),
                        ps,pe;

                    for ( var i = 0,ci; ci = as[i++]; ) {
                        ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);
                        if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
                            &&
                            (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
                            ) {
                            node = ci;
                            break;
                        }
                    }
                }
                return node;
            }

        }
    };
})();
<commit_msg>by zhanyi<commit_after>///import core
///commands 超链接,取消链接
///commandsName  Link,Unlink
///commandsTitle  超链接,取消链接
///commandsDialog  dialogs\link\link.html
/**
 * 超链接
 * @function
 * @name baidu.editor.execCommand
 * @param   {String}   cmdName     link插入超链接
 * @param   {Object}  options         url地址，title标题，target是否打开新页
 * @author zhanyi
 */
/**
 * 取消链接
 * @function
 * @name baidu.editor.execCommand
 * @param   {String}   cmdName     unlink取消链接
 * @author zhanyi
 */
(function() {
    function optimize( range ) {
        var start = range.startContainer,end = range.endContainer;

        if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {
            range.setStartBefore( start );
        }
        if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {
            range.setEndAfter( end );
        }
    }

    UE.commands['unlink'] = {
        execCommand : function() {
            var range = this.selection.getRange(),
                bookmark;
            if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){
                return;
            }
            bookmark = range.createBookmark();
            optimize( range );
            range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();
        },
        queryCommandState : function(){
            return !this.highlight && this.queryCommandValue('link') ?  0 : -1;
        }

    };
    function doLink(range,opt,me){
        var rngClone = range.cloneRange(),
            link = me.queryCommandValue('link');
        optimize( range = range.adjustmentBoundary() );
        var start = range.startContainer;
        if(start.nodeType == 1 && link){
            start = start.childNodes[range.startOffset];
            if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){
                start[browser.ie ? 'innerText' : 'textContent'] =  utils.html(opt.textValue||opt.href);

            }
        }
        if( !rngClone.collapsed || link){
            range.removeInlineStyle( 'a' );
            rngClone = range.cloneRange();
        }

        if ( rngClone.collapsed ) {
            var a = range.document.createElement( 'a'),
                text = '';
            if(opt.textValue){

                text =   utils.html(opt.textValue);
                delete opt.textValue;
            }else{
                text =   utils.html(opt.href);

            }
            domUtils.setAttributes( a, opt );
            start =  domUtils.findParentByTagName( rngClone.startContainer, 'a', true );
            if(start && domUtils.isInNodeEndBoundary(rngClone,start)){
                range.setStartAfter(start).collapse(true);

            }
            a[browser.ie ? 'innerText' : 'textContent'] = text;
            range.insertNode(a).selectNode( a );
        } else {
            range.applyInlineStyle( 'a', opt );

        }
    }
    UE.commands['link'] = {
        execCommand : function( cmdName, opt ) {
            var range;
            opt.data_ue_src && (opt.data_ue_src = utils.unhtml(opt.data_ue_src,/[<">]/g));
            opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g));
            opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g));
            doLink(range=this.selection.getRange(),opt,this);
            //闭合都不加占位符，如果加了会在a后边多个占位符节点，导致a是图片背景组成的列表，出现空白问题
            range.collapse().select(true);

        },
        queryCommandValue : function() {
            var range = this.selection.getRange(),
                node;

            if ( range.collapsed ) {
//                    node = this.selection.getStart();
                //在ie下getstart()取值偏上了
                node = range.startContainer;
                node = node.nodeType == 1 ? node : node.parentNode;

                if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {

                    return node;
                }
            } else {
                //trace:1111  如果是
xx
 startContainer是p就会找不到a
                range.shrinkBoundary();
                var start = range.startContainer.nodeType  == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],
                    end =  range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],
                    common = range.getCommonAncestor();
                node = domUtils.findParentByTagName( common, 'a', true );
                if ( !node && common.nodeType == 1){

                    var as = common.getElementsByTagName( 'a' ),
                        ps,pe;

                    for ( var i = 0,ci; ci = as[i++]; ) {
                        ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);
                        if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
                            &&
                            (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
                            ) {
                            node = ci;
                            break;
                        }
                    }
                }
                return node;
            }

        }
    };
})();
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mailChimp = require('../../node_modules/mailchimp-api/mailchimp'),
	validator = require('../../node_modules/email-validator'),
	config = require('../../config/mc-config.json');

var mc = new mailChimp.Mailchimp(config.apikey);

exports.index = function(req, res) {
	res.render('index', {
		user: req.user || null,
		request: req
	});
};

exports.emailSubscribe = function(req, res) {
	var validEmail = validator.validate(req.params.email);

	if (process.env.NODE_ENV == 'production' && validEmail) {
		mc.lists.subscribe({id: req.params.listId, email:{email:req.params.email}},
		function(data) {
			res.send({email: req.params.eamil});
		},
		function(error) {
			res.send({email: null, error: 'There was an error subscribing that email.\n' + error.error});
		});
	} else if (process.env.NODE_ENV == 'development') {
		res.send({email: null, error: 'This email "' + req.params.email + '" would have been subscribe - but you are hitting a dev server.'});
	} else {
		res.send({email: req.params.email + ' - Running on dev - no email sent.', error: 'Invalid email address format'});
	}
};
<commit_msg>Fix bug in email subscription server function - if no valid email was sent, respond with email null.<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mailChimp = require('../../node_modules/mailchimp-api/mailchimp'),
	validator = require('../../node_modules/email-validator'),
	config = require('../../config/mc-config.json');

var mc = new mailChimp.Mailchimp(config.apikey);

exports.index = function(req, res) {
	res.render('index', {
		user: req.user || null,
		request: req
	});
};

exports.emailSubscribe = function(req, res) {
	var validEmail = validator.validate(req.params.email);

	if (process.env.NODE_ENV == 'production' && validEmail) {
		mc.lists.subscribe({id: req.params.listId, email:{email:req.params.email}},
		function(data) {
			res.send({email: req.params.eamil});
		},
		function(error) {
			res.send({email: null, error: 'There was an error subscribing that email.\n' + error.error});
		});
	} else if (process.env.NODE_ENV == 'development') {
		res.send({email: null, error: 'This email "' + req.params.email + '" would have been subscribe - but you are hitting a dev server.'});
	} else {
		res.send({email: null, error: 'Invalid email address format'});
	}
};
<|endoftext|>


<commit_before>const express = require('express')
const bodyParser = require('body-parser')
const log = require('winston')
const config = require('../config')
const allowCors = require('./allowCors')
const fileServer = require('./fileServer')

const app = express()

app.use(bodyParser.json())
app.use(allowCors)
app.use('/donation', require('./routes/donation'))
app.use('/', fileServer)

const listen = () => {
  return new Promise((resolve) => {
    const server = app.listen(config.http.port, () => {
      const addr = server.address()
      resolve(`Server running on: http://${addr.address}:${addr.port}`)
    })
  })
}

// eslint-disable-next-line
app.use((err, req, res, next) => {
  const status = err.status || 500
  res.status(status)

  if(status === 500) {
    log.error(err.message || 'Server error')
    return res.end()
  }

  res.json({message: err.message})
})

module.exports = {
  listen
}
<commit_msg>Log stack trace if server error<commit_after>const express = require('express')
const bodyParser = require('body-parser')
const log = require('winston')
const config = require('../config')
const allowCors = require('./allowCors')
const fileServer = require('./fileServer')

const app = express()

app.use(bodyParser.json())
app.use(allowCors)
app.use('/donation', require('./routes/donation'))
app.use('/', fileServer)

const listen = () => {
  return new Promise((resolve) => {
    const server = app.listen(config.http.port, () => {
      const addr = server.address()
      resolve(`Server running on: http://${addr.address}:${addr.port}`)
    })
  })
}

// eslint-disable-next-line
app.use((err, req, res, next) => {
  const status = err.status || 500
  res.status(status)

  if(status === 500) {
    log.error(err.message || 'Server error')
    log.error(err.stack)
    return res.end()
  }

  res.json({message: err.message})
})

module.exports = {
  listen
}
<|endoftext|>


<commit_before>// var STORAGE_KEY = 'sites'

const types = {
  ADD_SITE: 'ADD_SITE',
  MODIFY_SITE: 'MODIFY_SITE',
  REMOVE_SITE: 'REMOVE_SITE',
  SET_SELECTED: 'SET_SELECTED'
}

const state = {
  selected: null,
  all: [] // JSON.parse(window.localStorage.getItem(STORAGE_KEY || '[]'))
}

const mutations = {
  [types.ADD_SITE] (state, data) {
    state.all.push(data)
  },
  [types.MODIFY_SITE] (state, {site, key, value}) {
    site[key] = value
  },
  [types.REMOVE_SITE] (state, {site}) {
    state.all.splice(state.all.indexOf(site), 1)
  },
  [types.SET_SELECTED] (state, data) {
    state.selected = data
  }
}

const actions = {
  addSite ({state, dispatch, commit}, payload) {
    commit(types.ADD_SITE, {
      test: payload.count || 'Hello world'
    })
  }
}

const getters = {}

export default {state, mutations, actions, getters, types}
<commit_msg>:bug: fixed local storage retrieval bug<commit_after>var STORAGE_KEY = 'sites'

const types = {
  ADD_SITE: 'ADD_SITE',
  MODIFY_SITE: 'MODIFY_SITE',
  REMOVE_SITE: 'REMOVE_SITE',
  SET_SELECTED: 'SET_SELECTED'
}

const state = {
  selected: null,
  all: JSON.parse(window.localStorage.getItem(STORAGE_KEY) || '[]')
}

const mutations = {
  [types.ADD_SITE] (state, data) {
    state.all.push(data)
  },
  [types.MODIFY_SITE] (state, {site, key, value}) {
    site[key] = value
  },
  [types.REMOVE_SITE] (state, {site}) {
    state.all.splice(state.all.indexOf(site), 1)
  },
  [types.SET_SELECTED] (state, data) {
    state.selected = data
  }
}

const actions = {
  addSite ({state, dispatch, commit}, payload) {
    commit(types.ADD_SITE, {
      test: payload.count || 'Hello world'
    })
  }
}

const getters = {}

export default {state, mutations, actions, getters, types}
<|endoftext|>


<commit_before>'use strict';

var $directive = function($type, $childs) {
  console.warn($type + ': надо в сервисы/провайдеры перефигачить');
	$.contextMenu({
		selector: 'div.context-menu.' + $type,
		items: $.contextMenu.fromMenu('menu#' + $type)
	});
  return ['skuapso-data', function(data) {
    var def = {};

    def.link = function($scope, $element, $attrs) {
      var obj = data.get({type: $type, id: $attrs[$type]});
      var d = 'data-type="' + $type + '" data-id="' + $attrs[$type] + '"';
      $element.find('>div.'+obj.type).remove();
      $element.prepend('
'
          + obj.title + '
');
    };

    return def;
  }]
};

var skuapsoModule = angular.module('skuapso',
    [
    'ui.bootstrap',
    'skuapso-init',
    'skuapso-tree',
    'skuapso-map',
    'skuapso.test'
    ]);

skuapsoModule
.run(['$rootScope', 'skuapso-data', function(root, data) {
  root.data = data;
}])
.run(['$http', '$templateCache', function(http, templateCache) {
  templateCache.put('template/timepicker/timepicker.html', "" +
    " " +
    "<input type='text' class='timepicker' ng-model='hours' maxlength='2'>" +
    " : " +
    "<input type='text' class='timepicker' ng-model='minutes' maxlength='2'>" +
    "");
}])
.controller('management', ['$rootScope', function(root) {
  root['toDateTime'] = new Date();
  root['fromDateTime'] = new Date();
  root['fromDateTime'].setDate(root['toDateTime'].getDate() - 1);
  root['sensor'] = true;
}])
.controller('listRoot', ['$scope', 'skuapso-data', function(scope, data) {
  var id;
  scope.node = {};
  Object.defineProperty(scope.node, 'childs', {
    get: function() {
      return data.childs({type: 'owner', id: null})
    }
  });
}])
.directive('owner', $directive('owner', ['owner', 'group']))
.directive('group', $directive('group', ['group', 'object']))
.directive('object', $directive('object', []))
.directive('skIf', ['$compile', function(compile) {
  var def = {};

  def.controller = ['$scope', '$element', function(scope, element) {
    scope.$html = element.html();
  }];

  def.link = function(scope, element, attr) {
    scope.$watch(attr.skIf, function(value, oldValue) {
      if (value && !oldValue) {
        element.html(scope.$html);
      } else {
        element.html('');
      }
      compile(element.contents())(scope);
    });
  };

  def.terminal = true;

  def.priority = 10000;

  return def;
}])
.config(['datepickerConfig', function(config) {
  config.showWeeks = false;
  config.startingDay = 1;
}])
.config(['datepickerPopupConfig', function(config) {
  config.dateFormat = 'shortDate';
}])
.config(['timepickerConfig', function(config) {
  console.debug('%o', config);
  config.showMeridian = false;
}])
;
<commit_msg>removed dbg msg<commit_after>'use strict';

var $directive = function($type, $childs) {
  console.warn($type + ': надо в сервисы/провайдеры перефигачить');
	$.contextMenu({
		selector: 'div.context-menu.' + $type,
		items: $.contextMenu.fromMenu('menu#' + $type)
	});
  return ['skuapso-data', function(data) {
    var def = {};

    def.link = function($scope, $element, $attrs) {
      var obj = data.get({type: $type, id: $attrs[$type]});
      var d = 'data-type="' + $type + '" data-id="' + $attrs[$type] + '"';
      $element.find('>div.'+obj.type).remove();
      $element.prepend('
'
          + obj.title + '
');
    };

    return def;
  }]
};

var skuapsoModule = angular.module('skuapso',
    [
    'ui.bootstrap',
    'skuapso-init',
    'skuapso-tree',
    'skuapso-map',
    'skuapso.test'
    ]);

skuapsoModule
.run(['$rootScope', 'skuapso-data', function(root, data) {
  root.data = data;
}])
.run(['$http', '$templateCache', function(http, templateCache) {
  templateCache.put('template/timepicker/timepicker.html', "" +
    " " +
    "<input type='text' class='timepicker' ng-model='hours' maxlength='2'>" +
    " : " +
    "<input type='text' class='timepicker' ng-model='minutes' maxlength='2'>" +
    "");
}])
.controller('management', ['$rootScope', function(root) {
  root['toDateTime'] = new Date();
  root['fromDateTime'] = new Date();
  root['fromDateTime'].setDate(root['toDateTime'].getDate() - 1);
  root['sensor'] = true;
}])
.controller('listRoot', ['$scope', 'skuapso-data', function(scope, data) {
  var id;
  scope.node = {};
  Object.defineProperty(scope.node, 'childs', {
    get: function() {
      return data.childs({type: 'owner', id: null})
    }
  });
}])
.directive('owner', $directive('owner', ['owner', 'group']))
.directive('group', $directive('group', ['group', 'object']))
.directive('object', $directive('object', []))
.directive('skIf', ['$compile', function(compile) {
  var def = {};

  def.controller = ['$scope', '$element', function(scope, element) {
    scope.$html = element.html();
  }];

  def.link = function(scope, element, attr) {
    scope.$watch(attr.skIf, function(value, oldValue) {
      if (value && !oldValue) {
        element.html(scope.$html);
      } else {
        element.html('');
      }
      compile(element.contents())(scope);
    });
  };

  def.terminal = true;

  def.priority = 10000;

  return def;
}])
.config(['datepickerConfig', function(config) {
  config.showWeeks = false;
  config.startingDay = 1;
}])
.config(['datepickerPopupConfig', function(config) {
  config.dateFormat = 'shortDate';
}])
.config(['timepickerConfig', function(config) {
  config.showMeridian = false;
}])
;
<|endoftext|>


<commit_before>/* Copyright (c) 2013 The Tagspaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */

define(function(require, exports, module) {
  "use strict";

  console.log("Loading viewerImage");

  var extensionTitle = "Image Viewer";
  var extensionID = "viewerImage"; // ID should be equal to the directory name where the ext. is located
  var extensionType = "viewer";
  var extensionIcon = "icon-list"; // A name of an icon from the font-awesome set
  var extensionSupportedFileTypes = ["jpeg", "jpg", "png", "gif", "bmp", "ico", "webp"];

  var TSCORE = require("tscore");

  var extensionDirectory = TSCORE.Config.getExtensionPath() + "/" + extensionID;
  var UI;

  var currentFilePath,
    $containerElement;

  exports.init = function(filePath, elementID) {
    console.log("Initalization Browser Image Viewer...");

    $containerElement = $('#' + elementID);
    currentFilePath = filePath;

    var lng = $.i18n.lng();

    $containerElement.append($('<iframe>', {
      id: "iframeViewer",
      sandbox: "allow-same-origin allow-scripts",
      scrolling: "no",
      src: extensionDirectory + "/index.html?cp=" + filePath + "&setLng=" + lng,
      "nwdisable": "",
      "nwfaketop": ""
    }));

    /* $("#iframeViewer")
			.hammer().on("swipeleft", function() {
				TSCORE.FileOpener.openFile(TSCORE.PerspectiveManager.getNextFile(internPath));
			})
			.hammer().on("swiperight", function() {
				TSCORE.FileOpener.openFile(TSCORE.PerspectiveManager.getPrevFile(internPath));
			}); */
  };

  exports.viewerMode = function(isViewerMode) {
    console.log("viewerMode not supported on this extension");
  };

  exports.setContent = function(content) {
    console.log("setContent not supported on this extension");
  };

  exports.getContent = function() {
    console.log("getContent not supported on this extension");
  };

  // Extension Vars
  exports.Title = extensionTitle;
  exports.ID = extensionID;
  exports.Type = extensionType;
  exports.Icon = extensionIcon;
  exports.SupportedFileTypes = extensionSupportedFileTypes;

});
<commit_msg>allow printing of images in the webdav version<commit_after>/* Copyright (c) 2013 The Tagspaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */

define(function(require, exports, module) {
  "use strict";

  console.log("Loading viewerImage");

  var extensionTitle = "Image Viewer";
  var extensionID = "viewerImage"; // ID should be equal to the directory name where the ext. is located
  var extensionType = "viewer";
  var extensionIcon = "icon-list"; // A name of an icon from the font-awesome set
  var extensionSupportedFileTypes = ["jpeg", "jpg", "png", "gif", "bmp", "ico", "webp"];

  var TSCORE = require("tscore");

  var extensionDirectory = TSCORE.Config.getExtensionPath() + "/" + extensionID;
  var UI;

  var currentFilePath,
    $containerElement;

  exports.init = function(filePath, elementID) {
    console.log("Initalization Browser Image Viewer...");

    $containerElement = $('#' + elementID);
    currentFilePath = filePath;

    var lng = $.i18n.lng();

    $containerElement.append($('<iframe>', {
      id: "iframeViewer",
      sandbox: "allow-same-origin allow-scripts allow-modals",
      scrolling: "no",
      type: "content",
      src: extensionDirectory + "/index.html?cp=" + filePath + "&setLng=" + lng,
      "nwdisable": "",
      "nwfaketop": ""
    }));

    /* $("#iframeViewer")
			.hammer().on("swipeleft", function() {
				TSCORE.FileOpener.openFile(TSCORE.PerspectiveManager.getNextFile(internPath));
			})
			.hammer().on("swiperight", function() {
				TSCORE.FileOpener.openFile(TSCORE.PerspectiveManager.getPrevFile(internPath));
			}); */
  };

  exports.viewerMode = function(isViewerMode) {
    console.log("viewerMode not supported on this extension");
  };

  exports.setContent = function(content) {
    console.log("setContent not supported on this extension");
  };

  exports.getContent = function() {
    console.log("getContent not supported on this extension");
  };

  // Extension Vars
  exports.Title = extensionTitle;
  exports.ID = extensionID;
  exports.Type = extensionType;
  exports.Icon = extensionIcon;
  exports.SupportedFileTypes = extensionSupportedFileTypes;

});
<|endoftext|>


<commit_before>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview
 *
 * @author Lukas Vlcek (lvlcek@redhat.com)
 */

goog.provide('org.jboss.search.list.project.Project');

goog.require('goog.object');
goog.require('goog.array');
goog.require('goog.async.Deferred');

/**
 * Creates a new instance of Project list.
 * @param {!goog.async.Deferred} deferred source that will provide the actual data
 * @param {Function=} opt_canceller A function that will be called if the
 *     deferred is cancelled.
 * @param {Object=} opt_defaultScope The default scope to call callbacks with.
 * @constructor
 * @extends {goog.async.Deferred}
 */
org.jboss.search.list.project.Project = function(deferred, opt_canceller, opt_defaultScope) {

    goog.async.Deferred.call(this, opt_canceller, opt_defaultScope);

    /**
     * @type {!goog.async.Deferred}
     * @private
     */
    this.deferred_ = deferred;

    /**
     * @type {Object}
     * @private
     */
    this.map = {};

    // when deferred has the results, parse them, keep them in the map and let the callee know.
    this.deferred_.addCallback(function(data){
        this.map = this.parseProjectData(data);
        this.callback();
    }, this);
};
goog.inherits(org.jboss.search.list.project.Project, goog.async.Deferred);

/**
 * Knows how to parse response from http://docs.jbossorg.apiary.io/#managementapi%20-%20projects
 * into simple map representation.
 * @param {*} json
 * @return {Object}
 */
org.jboss.search.list.project.Project.prototype.parseProjectData = function(json) {
    var map_ = {};
    if (goog.isDefAndNotNull(json.hits) && goog.isArray(json.hits)) {

        goog.array.forEach(json.hits, function(item){
            var id_ = item['id'];
            var name_ = item['data']['name'];
            if (goog.isDefAndNotNull(id_) && goog.isDefAndNotNull(name_)) {
                map_[id_] = name_;
            }
        }, this);
    }
    return map_
};

/**
 * Return DCP Project Name for given Project DCP ID.
 * @param {!string} dcpId
 * @return {!string}
 */
org.jboss.search.list.project.Project.prototype.getDcpProjectName = function(dcpId) {
    return goog.object.get(this.map, dcpId, "Unknown").valueOf();
};

/**
 * Return
 * @return {*}
 */
org.jboss.search.list.project.Project.prototype.getMap = function() {
    return this.map;
};

<commit_msg>get 'code' from correct field<commit_after>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview
 *
 * @author Lukas Vlcek (lvlcek@redhat.com)
 */

goog.provide('org.jboss.search.list.project.Project');

goog.require('goog.object');
goog.require('goog.array');
goog.require('goog.async.Deferred');

/**
 * Creates a new instance of Project list.
 * @param {!goog.async.Deferred} deferred source that will provide the actual data
 * @param {Function=} opt_canceller A function that will be called if the
 *     deferred is cancelled.
 * @param {Object=} opt_defaultScope The default scope to call callbacks with.
 * @constructor
 * @extends {goog.async.Deferred}
 */
org.jboss.search.list.project.Project = function(deferred, opt_canceller, opt_defaultScope) {

    goog.async.Deferred.call(this, opt_canceller, opt_defaultScope);

    /**
     * @type {!goog.async.Deferred}
     * @private
     */
    this.deferred_ = deferred;

    /**
     * @type {Object}
     * @private
     */
    this.map = {};

    // when deferred has the results, parse them, keep them in the map and let the callee know.
    this.deferred_.addCallback(function(data){
        this.map = this.parseProjectData(data);
        this.callback();
    }, this);
};
goog.inherits(org.jboss.search.list.project.Project, goog.async.Deferred);

/**
 * Knows how to parse response from http://docs.jbossorg.apiary.io/#managementapi%20-%20projects
 * into simple map representation.
 * @param {*} json
 * @return {Object}
 */
org.jboss.search.list.project.Project.prototype.parseProjectData = function(json) {
    var map_ = {};
    if (goog.isDefAndNotNull(json.hits) && goog.isArray(json.hits)) {

        goog.array.forEach(json.hits, function(item){
            // TODO add more checks (item.data undefined?)
            var id_ = item['data']['code'];
            var name_ = item['data']['name'];
            if (goog.isDefAndNotNull(id_) && goog.isDefAndNotNull(name_)) {
                map_[id_] = name_;
            }
        }, this);
    }
    return map_
};

/**
 * Return DCP Project Name for given Project DCP ID.
 * @param {!string} dcpId
 * @return {!string}
 */
org.jboss.search.list.project.Project.prototype.getDcpProjectName = function(dcpId) {
    return goog.object.get(this.map, dcpId, "Unknown").valueOf();
};

/**
 * Return
 * @return {*}
 */
org.jboss.search.list.project.Project.prototype.getMap = function() {
    return this.map;
};

<|endoftext|>