<commit_before>/**
 * Created by xiayiqian on 1/4/16.
 */

'use strict';

angular.module('sbAdminApp')
    .controller('reservationQuantityController', function ($scope, $http, $cookies) {
        $scope.token = $cookies.get('token');

        $scope.restaurantToSearch = {};

        $scope.today = function() {
            $scope.restaurantToSearch.endDate = new Date();
        };
        $scope.today();

        $scope.clear = function () {
            $scope.endDate = null;
        };

        // Disable weekend selection
        $scope.disabled = function(date, mode) {
            return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
        };

        $scope.toggleMin = function() {
            $scope.minDate = $scope.minDate ? null : new Date();
        };

        //禁用此函数,让用户可以选择当日之前的日期
        //$scope.toggleMin();
        $scope.maxDate = new Date(2020, 5, 22);

        $scope.open = function($event) {
            $scope.status.opened = true;
        };

        $scope.setDate = function(year, month, day) {
            $scope.endDate = new Date(year, month, day);
        };

        $scope.dateOptions = {
            formatYear: 'yy',
            startingDay: 1
        };

        $scope.formats = ['yyyy-MM-dd', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
        $scope.format = $scope.formats[0];

        $scope.status = {
            opened: false
        };

        $scope.endDateStatus = {
            opened: false
        };

        $scope.openEndDate = function($event) {
            $scope.endDateStatus.opened = true;
        };

        var tomorrow = new Date();
        tomorrow.setDate(tomorrow.getDate() + 1);
        var afterTomorrow = new Date();
        afterTomorrow.setDate(tomorrow.getDate() + 2);
        $scope.events =
            [
                {
                    date: tomorrow,
                    status: 'full'
                },
                {
                    date: afterTomorrow,
                    status: 'partially'
                }
            ];

        $scope.getDayClass = function(date, mode) {
            if (mode === 'day') {
                var dayToCheck = new Date(date).setHours(0,0,0,0);

                for (var i=0;i<$scope.events.length;i++){
                    var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

                    if (dayToCheck === currentDay) {
                        return $scope.events[i].status;
                    }
                }
            }

            return '';
        };

        function setCities(cityArray) {
            for (var i = 0; i < cityArray.length; i++) {
                $scope.cities.push(cityArray[i]);
            }
        }

        $scope.cities = [];
        $scope.getCites = function() {
            $http({
                method: 'GET',
                url: 'http://localhost:8080/cities',
                headers: {
                    //'Content-Type': 'application/json',
                    'x-auth-token': $scope.token
                },
                crossDomain: true
            }).success(function (cityArray) {
                setCities(cityArray);
            }).error(function () {
                console.log("getCites failed");
            });
        };
        $scope.getCites();

        $scope.line = {
            labels: ['', '', '', '', '', ''],
            series: ['预订数量'],
            data: [
                [0, 0, 0, 0, 0, 0, 0]
            ],
            onClick: function (points, evt) {
                console.log(points, evt);
            }
        };

        //$scope.searchBtnClicked = function() {
        //    // 城市,餐厅名,查询起止日期
        //    console.log($scope.restaurantToSearch.city + " " + $scope.restaurantToSearch.name + " " +
        //        $scope.restaurantToSearch.startDate + " " + $scope.restaurantToSearch.endDate);
        //    $scope.line.data = [
        //        [65, 30, 80, 81, 56, 55, 40],
        //        [28, 48, 40, 19, 64, 27, 20]
        //    ];
        //};

        $scope.searchReservationQuantity = function(restaurant) {
            console.log($scope.restaurantToSearch.endDate);
            $http({
                method: 'GET',
                url: 'http://202.120.40.175:21104/order/orderCountInfo',
                params: {
                    restaurantId: restaurant.restaurantId,
                    date: '2016-01-06'
                },
                crossDomain: true
            }).success(function(data) {
                console.log(data);
                $scope.getDatasFromSearchingResult(data);
            }).error(function () {
                console.log("user delete failed");
            });
        };

        $scope.getDatasFromSearchingResult = function(data) {
            var makeNums = [];
            var labels = [];
            for (var i = 0; i < data.length; i++) {
                console.log(data[i].dorderMakeNum);
                makeNums.push(data[i].dorderMakeNum);
                labels.push(i+1);
            }
            $scope.line.data = [makeNums];
            $scope.line.labels = labels;
        };

        $scope.searchBtnClicked = function() {
            $http({
                method: 'GET',
                url: 'http://202.120.40.175:21104/restaurant/search/namecity',
                params: {
                    restaurantName: $scope.restaurantToSearch.name,
                    city: $scope.restaurantToSearch.city
                },
                crossDomain: true
            }).success(function(data) {
                console.log(data);
                $scope.rowCollection = data;
                $scope.displayedCollection = data;
            }).error(function () {
                console.log("user delete failed");
            });
        };
    });
<commit_msg>use date filter<commit_after>/**
 * Created by xiayiqian on 1/4/16.
 */

'use strict';

angular.module('sbAdminApp')
    .controller('reservationQuantityController', function ($scope, $http, $cookies, $filter) {
        $scope.token = $cookies.get('token');

        $scope.restaurantToSearch = {};

        $scope.today = function() {
            $scope.restaurantToSearch.endDate = new Date();
        };
        $scope.today();

        $scope.clear = function () {
            $scope.endDate = null;
        };

        // Disable weekend selection
        $scope.disabled = function(date, mode) {
            return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
        };

        $scope.toggleMin = function() {
            $scope.minDate = $scope.minDate ? null : new Date();
        };

        //禁用此函数,让用户可以选择当日之前的日期
        //$scope.toggleMin();
        $scope.maxDate = new Date(2020, 5, 22);

        $scope.open = function($event) {
            $scope.status.opened = true;
        };

        $scope.setDate = function(year, month, day) {
            $scope.endDate = new Date(year, month, day);
        };

        $scope.dateOptions = {
            formatYear: 'yy',
            startingDay: 1
        };

        $scope.formats = ['yyyy-MM-dd', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
        $scope.format = $scope.formats[0];

        $scope.status = {
            opened: false
        };

        $scope.endDateStatus = {
            opened: false
        };

        $scope.openEndDate = function($event) {
            $scope.endDateStatus.opened = true;
        };

        var tomorrow = new Date();
        tomorrow.setDate(tomorrow.getDate() + 1);
        var afterTomorrow = new Date();
        afterTomorrow.setDate(tomorrow.getDate() + 2);
        $scope.events =
            [
                {
                    date: tomorrow,
                    status: 'full'
                },
                {
                    date: afterTomorrow,
                    status: 'partially'
                }
            ];

        $scope.getDayClass = function(date, mode) {
            if (mode === 'day') {
                var dayToCheck = new Date(date).setHours(0,0,0,0);

                for (var i=0;i<$scope.events.length;i++){
                    var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

                    if (dayToCheck === currentDay) {
                        return $scope.events[i].status;
                    }
                }
            }

            return '';
        };

        function setCities(cityArray) {
            for (var i = 0; i < cityArray.length; i++) {
                $scope.cities.push(cityArray[i]);
            }
        }

        $scope.cities = [];
        $scope.getCites = function() {
            $http({
                method: 'GET',
                url: 'http://localhost:8080/cities',
                headers: {
                    //'Content-Type': 'application/json',
                    'x-auth-token': $scope.token
                },
                crossDomain: true
            }).success(function (cityArray) {
                setCities(cityArray);
            }).error(function () {
                console.log("getCites failed");
            });
        };
        $scope.getCites();

        $scope.line = {
            labels: ['', '', '', '', '', ''],
            series: ['预订数量'],
            data: [
                [0, 0, 0, 0, 0, 0, 0]
            ],
            onClick: function (points, evt) {
                console.log(points, evt);
            }
        };

        //$scope.searchBtnClicked = function() {
        //    // 城市,餐厅名,查询起止日期
        //    console.log($scope.restaurantToSearch.city + " " + $scope.restaurantToSearch.name + " " +
        //        $scope.restaurantToSearch.startDate + " " + $scope.restaurantToSearch.endDate);
        //    $scope.line.data = [
        //        [65, 30, 80, 81, 56, 55, 40],
        //        [28, 48, 40, 19, 64, 27, 20]
        //    ];
        //};

        $scope.searchReservationQuantity = function(restaurant) {
            $http({
                method: 'GET',
                url: 'http://202.120.40.175:21104/order/orderCountInfo',
                params: {
                    restaurantId: restaurant.restaurantId,
                    date: $filter('date')($scope.restaurantToSearch.endDate, 'yyyy-MM-dd')
                },
                crossDomain: true
            }).success(function(data) {
                console.log(data);
                $scope.getDatasFromSearchingResult(data);
            }).error(function () {
                console.log("user delete failed");
            });
        };

        $scope.getDatasFromSearchingResult = function(data) {
            var makeNums = [];
            var labels = [];
            for (var i = 0; i < data.length; i++) {
                console.log(data[i].dorderMakeNum);
                makeNums.push(data[i].dorderMakeNum);
                labels.push(i+1);
            }
            $scope.line.data = [makeNums];
            $scope.line.labels = labels;
        };

        $scope.searchBtnClicked = function() {
            $http({
                method: 'GET',
                url: 'http://202.120.40.175:21104/restaurant/search/namecity',
                params: {
                    restaurantName: $scope.restaurantToSearch.name,
                    city: $scope.restaurantToSearch.city
                },
                crossDomain: true
            }).success(function(data) {
                $scope.rowCollection = data;
                $scope.displayedCollection = data;
            }).error(function () {
                console.log("user delete failed");
            });
        };
    });
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2014 Google Inc. 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.
 */

MODEL({
  name: 'XHR',

  properties: [
    { model_: 'IntProperty', name: 'delay', defaultValue: 0 },
    { model_: 'IntProperty', name: 'retries', defaultValue: 0 },
    { name: 'authAgent' },
    { name: 'responseType', defaultValue: 'text' }
  ],

  methods: {
    init: function(args) {
      this.SUPER(args);

      if ( this.delay ) this.addDecorator(DelayDecorator.create({ delayMs: this.delay }));
      if ( this.authAgent ) this.addDecorator(OAuthXhrDecorator.create({ authAgent: this.authAgent }));
      if ( this.retries ) this.addDecorator(RetryDecorator.create({ maxAttempts: this.retries }));
    },

    makeXhr: function() {
      return new XMLHttpRequest();
    },
    open: function(xhr, method, url) {
      xhr.open(method, url);
    },
    setRequestHeader: function(xhr, header, value) {
      xhr.setRequestHeader(header, value);
    },
    configure: function(xhr) {
      xhr.responseType = this.responseType;
    },
    bindListeners: function(xhr, ret) {
      xhr.onreadystatechange = function() {
        if ( xhr.readyState == 4 ) {
          ret(xhr.response, xhr);
        }
      }
    },
    send: function(xhr, data) {
      xhr.send(data);
    },
    asend: function(ret, url, data, method) {
      var xhr = this.makeXhr();
      this.open(xhr, method || "GET", url);
      this.configure(xhr);
      this.bindListeners(xhr, ret);
      this.send(xhr, (data && data.toJSON) ? data.toJSON() : data);
    },
  }
});

MODEL({
  name: "OAuthXhrDecorator",

  properties: [
    'authAgent'
  ],

  methods: {
    configure: function(decorator, delegate, args) {
      var xhr = args[0];
      xhr.setRequestHeader("Authorization", "Bearer " + decorator.authAgent.accessToken);
      return delegate.apply(this, args);
    },
    asend: function(decorator, delegate, args) {
      var ret = args[0];
      args[0] = function(response, xhr) {
        if ( xhr.status === 401 || xhr.status === 403 ) {
          decorator.authAgent.refresh(function() {
            ret(response, xhr);
          });
        } else {
          ret(response, xhr);
        }
      };
      return delegate.apply(null, args);
    }
  }
});

MODEL({
  name: 'RetryDecorator',

  properties: [
    { model_: 'IntProperty', name: 'maxAttempts', defaultValue: 3 }
  ],

 methods: {
    asend: function(decorator, delegate, args) {
      var originalRet = args[0];
      var attempts = 0;
      var self = this;
      var response;

      awhile(function() { return true; },
             aseq(
               function(ret) {
                 args[0] = ret;
                 delegate.apply(self, args);
               },
               function(ret, response, xhr) {
                 if ( ( xhr.status >= 200 && xhr.status < 300 ) ||
                      ++attempts >= decorator.maxAttempts ) {
                   finished = true;
                   originalRet(response, xhr);
                   return;
                 }
                 ret();
               }))(function(){});
    }
  }
});

MODEL({
  name: 'DelayDecorator',

  properties: [
    { model_: 'IntProperty', name: 'delayMs' },
  ],

  methods: {
    decorateObject: function(target) {
      var asend = adelay(target.asend.bind(target), this.delayMs);
      target.decorate('asend', function(_, _, args) {
        asend.apply(null, args);
      });
    }
  }
});

MODEL({
  name: 'XhrMessenger',
  properties: [
    { model_: 'URLProperty', name: 'url' },
    { model_: 'StringProperty', name: 'method', defaultValue: "POST" }
  ],

  methods: {
    put: function(obj, sink) {
      var xhr = this.X.XHR.create();
      xhr.asend(function(response, xhr) {
        if ( xhr.status >= 200 && xhr.status < 300 ) {
          sink && sink.put && sink.put(response);
          return;
        }
        sink && sink.error && sink.error([response, xhr]);
      }, this.url, obj, this.method);
    }
  }
});
<commit_msg>Default XHR requests to Content-Type application/json Don't retry on 404 errors.<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. 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.
 */

MODEL({
  name: 'XHR',

  properties: [
    { model_: 'IntProperty', name: 'delay', defaultValue: 0 },
    { model_: 'IntProperty', name: 'retries', defaultValue: 0 },
    { name: 'authAgent' },
    { name: 'responseType', defaultValue: 'text' }
  ],

  methods: {
    init: function(args) {
      this.SUPER(args);

      if ( this.delay ) this.addDecorator(DelayDecorator.create({ delayMs: this.delay }));
      if ( this.authAgent ) this.addDecorator(OAuthXhrDecorator.create({ authAgent: this.authAgent }));
      if ( this.retries ) this.addDecorator(RetryDecorator.create({ maxAttempts: this.retries }));
    },

    makeXhr: function() {
      return new XMLHttpRequest();
    },
    open: function(xhr, method, url) {
      xhr.open(method, url);
    },
    setRequestHeader: function(xhr, header, value) {
      xhr.setRequestHeader(header, value);
    },
    configure: function(xhr) {
      xhr.responseType = this.responseType;
      this.setRequestHeader(xhr, "Content-Type", "application/json");
    },
    bindListeners: function(xhr, ret) {
      xhr.onreadystatechange = function() {
        if ( xhr.readyState == 4 ) {
          ret(xhr.response, xhr);
        }
      }
    },
    send: function(xhr, data) {
      xhr.send(data);
    },
    asend: function(ret, url, data, method) {
      var xhr = this.makeXhr();
      this.open(xhr, method || "GET", url);
      this.configure(xhr);
      this.bindListeners(xhr, ret);
      this.send(xhr, (data && data.toJSON) ? data.toJSON() : data);
    },
  }
});

MODEL({
  name: "OAuthXhrDecorator",

  properties: [
    'authAgent'
  ],

  methods: {
    configure: function(decorator, delegate, args) {
      var xhr = args[0];
      xhr.setRequestHeader("Authorization", "Bearer " + decorator.authAgent.accessToken);
      return delegate.apply(this, args);
    },
    asend: function(decorator, delegate, args) {
      var ret = args[0];
      args[0] = function(response, xhr) {
        if ( xhr.status === 401 || xhr.status === 403 ) {
          decorator.authAgent.refresh(function() {
            ret(response, xhr);
          });
        } else {
          ret(response, xhr);
        }
      };
      return delegate.apply(null, args);
    }
  }
});

MODEL({
  name: 'RetryDecorator',

  properties: [
    { model_: 'IntProperty', name: 'maxAttempts', defaultValue: 3 }
  ],

 methods: {
    asend: function(decorator, delegate, args) {
      var originalRet = args[0];
      var attempts = 0;
      var self = this;
      var response;

      awhile(function() { return true; },
             aseq(
               function(ret) {
                 args[0] = ret;
                 delegate.apply(self, args);
               },
               function(ret, response, xhr) {
                 if ( ( xhr.status >= 200 && xhr.status < 300 ) ||
                      xhr.status === 404 ||
                      ++attempts >= decorator.maxAttempts ) {
                   finished = true;
                   originalRet(response, xhr);
                   return;
                 }
                 ret();
               }))(function(){});
    }
  }
});

MODEL({
  name: 'DelayDecorator',

  properties: [
    { model_: 'IntProperty', name: 'delayMs' },
  ],

  methods: {
    decorateObject: function(target) {
      var asend = adelay(target.asend.bind(target), this.delayMs);
      target.decorate('asend', function(_, _, args) {
        asend.apply(null, args);
      });
    }
  }
});

MODEL({
  name: 'XhrMessenger',
  properties: [
    { model_: 'URLProperty', name: 'url' },
    { model_: 'StringProperty', name: 'method', defaultValue: "POST" }
  ],

  methods: {
    put: function(obj, sink) {
      var xhr = this.X.XHR.create();
      xhr.asend(function(response, xhr) {
        if ( xhr.status >= 200 && xhr.status < 300 ) {
          sink && sink.put && sink.put(response);
          return;
        }
        sink && sink.error && sink.error([response, xhr]);
      }, this.url, obj, this.method);
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Pos - [x:N, y:N]
 * Size - {w:N, h:N}
 * Tile - {pos:Pos, size:Size}
 * Rect - {left:N, top:N, width:N, height:N}
 * Grid - {size:Size, bounds:Rect, gutter:N}
 */

var Grid = (function(document, React, Velocity) {
  const ERR = {
    NO_PARAMS: "Must specify parameter object.",
    NO_BOUNDS: "Must specify either explicit bounds or a bounding container.",
    NO_GRID: "Must provide a valid grid to work within.",
    NO_TILE: "Must provide a valid tile.",
    NO_POS: "Must provide a valid grid position.",
    NO_SIZE: "Must provide a valid size in grid cells."
  };

  function make2DArray(width, height, defaultValue) {
    var arr = new Array(width);
    for(var x = 0; x < width; x++) {
      arr[x] = [];
      for(var y = 0; y < height; y++) {
        arr[x][y] = defaultValue;
      }
    }
    return arr;
  }

  function assertTile(tile) {
    if(!tile) { throw new Error(ERR.NO_TILE); }
    if(!tile.pos) { throw new Error(ERR.NO_POS); }
    if(!tile.size) { throw new Error(ERR.NO_SIZE); }
    return true;
  }

  return {
    DEFAULT_SIZE: [6, 3],
    makeGrid: function makeGrid(params) { // (Any) -> Grid
      if(!params) { throw new Error(ERR.NO_PARAMS); }
      var bounds = params.bounds || params.container;
      if(typeof bounds === "string") {
        bounds = document.querySelector(bounds);
      }
      if(bounds && bounds.nodeType) {
        bounds = bounds.getBoundingClientRect();
      }
      if(!bounds) { throw new Error(ERR.NO_BOUNDS); }

      var grid = {
        size: params.size || [12, 12],
        bounds: {top: bounds.top, left: bounds.left, bottom: bounds.bottom, right: bounds.right, width: bounds.width, height: bounds.height},
        gutter: params.gutter || 0,
      };

      var gapWidth = grid.gutter * (grid.size[0] - 1);
      var gapHeight = grid.gutter * (grid.size[1] - 1);
      grid.calculated = {
        cellWidth: (grid.bounds.width - gapWidth) / grid.size[0],
        cellHeight: (grid.bounds.height - gapHeight) / grid.size[1],
        snapWidth: grid.bounds.width / grid.size[0],
        snapHeight: grid.bounds.height / grid.size[1]
      };
      return grid;
    },
    getRect: function getRect(grid, tile) { // (Grid, Tile) -> Rect
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);

      var rect = {
        left: grid.bounds.left + tile.pos[0] * grid.calculated.cellWidth + tile.pos[0] * grid.gutter,
        top: grid.bounds.top + tile.pos[1] * grid.calculated.cellHeight + tile.pos[1] * grid.gutter,
        width: tile.size[0] * grid.calculated.cellWidth + (tile.size[0] - 1) * grid.gutter,
        height: tile.size[1] * grid.calculated.cellHeight + (tile.size[1] - 1) * grid.gutter
      };
      // rect.right = grid.bounds.right - (rect.left + rect.width);
      // rect.bottom = grid.bounds.bottom - (rect.top + rect.height);
      return rect;
    },
    evacuateTile: function evacuateRect(grid, tile, from, force) { // (Grid, Tile, Pos?, Bool?) -> Tile
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      from = from || [grid.size[0] / 2, grid.size[1] / 2];

      var xOffset = tile.pos[0] - from[0];
      var yOffset = tile.pos[1] - from[1];
      var xEdge = xOffset > 0 ? grid.size[0] + 1 : (xOffset < 0 ? -tile.size[0] - 1 : tile.pos[0]);
      var yEdge = yOffset > 0 ? grid.size[1] + 1 : (yOffset < 0 ? -tile.size[1] - 1 : tile.pos[0]);

      if(force && xEdge === tile.pos[0] && yEdge === tile.pos[1]) {
        yEdge = grid.size[1] + 1;
      }

      return {pos: [xEdge, yEdge], size: tile.size};
    },
    confineTile: function confineRect(grid, tile, to) { // (Grid, Tile, Tile) -> Tile
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      assertTile(to);
      var result = {pos: to.pos, size: []};
      if(tile.size[0] < to.size[0]) { result.size[0] = tile.size[0]; }
      else { result.size[0] = to.size[0]; }
      if(tile.size[1] < to.size[1]) { result.size[1] = tile.size[1]; }
      else { result.size[1] = to.size[1]; }
      return result;
    },
    coordsToPos: function coordsToPos(grid, x, y, round) { // (Grid, N, N, Bool?) -> Pos
      if(!grid) { throw new Error(ERR.NO_GRID); }
      x = (x - grid.bounds.left) / grid.calculated.snapWidth;
      y = (y - grid.bounds.top) / grid.calculated.snapHeight;
      if(round) { return [Math.round(x), Math.round(y)]; }
      else { return [Math.floor(x), Math.floor(y)]; }
    },
    coordsToSize: function coordsToSize(grid, w, h, round) { // (Grid, N, N, Bool?) -> Size
      if(!grid) { throw new Error(ERR.NO_GRID); }
      w = w / grid.calculated.snapWidth;
      h = h / grid.calculated.snapHeight;
      if(round) { return [Math.round(w), Math.round(h)]; }
      else { return [Math.floor(w), Math.floor(h)]; }
    },
    tilesToMap: function tilesToMap(grid, tiles) { // (Grid, Tile[]) -> TileMap
      var map = make2DArray(grid.size[0], grid.size[1], 0);
      for(var ix = 0, len = tiles.length; ix < len; ix++) {
        var tile = tiles[ix];
        for(var x = tile.pos[0]; x < tile.pos[0] + tile.size[0]; x++) {
          for(var y = tile.pos[1]; y < tile.pos[1] + tile.size[1]; y++) {
            map[x][y]++;
          }
        }
      }
      return map;
    },
    hasGapAt: function hasGapAt(grid, tiles, tile, map) { // (Grid, Tile[], Pos, Size, TileMap?) -> Bool
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      if(!map) { map = Grid.tilesToMap(grid, tiles); }

      if(tile.pos[0] < 0) { return false; }
      if(tile.pos[1] < 0) { return false; }
      if(tile.pos[0] + tile.size[0] > grid.size[0]) { return false; }
      if(tile.pos[1] + tile.size[1] > grid.size[1]) { return false; }

      for(var x = tile.pos[0]; x < tile.pos[0] + tile.size[0]; x++) {
        for(var y = tile.pos[1]; y < tile.pos[1] + tile.size[1]; y++) {
          if(map[x][y] > 0) {
            return false;
          }
        }
      }
      return true;
    },
    findGap: function findGap(grid, tiles, size) { // (Grid, Tile[], Size) -> Pos?
      if(!grid) { throw new Error(ERR.NO_GRID); }
      if(!size) { throw new Error(ERR.NO_SIZE); }
      var map = Grid.tilesToMap(grid, tiles);
      var tile = {pos: undefined, size: size};
      for(var x = 0; x <= grid.size[0] - size[0]; x++) {
        for(var y = 0; y <= grid.size[1] - size[1]; y++) {
          if(map[x][y] > 0) { continue; }
          tile.pos = [x, y];
          if(Grid.hasGapAt(grid, tiles, tile, map)) {
            return [x, y];
          }
        }
      }
    },
    tilesToText: function(grid, tiles) {
      var map = Grid.tilesToMap(grid, tiles);
      var result = [];
      for(var x = 0; x < map.length; x++) {
        for(var y = 0; y < map[x].length; y++) {
          result[y] = result[y] || [];
          result[y][x] = map[x][y];
        }
      }
      return result.map(function(row) { return row.join(" | "); }).join("\n");
    }
  };
})(window.document, React, Velocity);
window.Grid = Grid;
<commit_msg>Smarter confine logic<commit_after>/**
 * Pos - [x:N, y:N]
 * Size - {w:N, h:N}
 * Tile - {pos:Pos, size:Size}
 * Rect - {left:N, top:N, width:N, height:N}
 * Grid - {size:Size, bounds:Rect, gutter:N}
 */

var Grid = (function(document, React, Velocity) {
  const ERR = {
    NO_PARAMS: "Must specify parameter object.",
    NO_BOUNDS: "Must specify either explicit bounds or a bounding container.",
    NO_GRID: "Must provide a valid grid to work within.",
    NO_TILE: "Must provide a valid tile.",
    NO_POS: "Must provide a valid grid position.",
    NO_SIZE: "Must provide a valid size in grid cells."
  };

  function make2DArray(width, height, defaultValue) {
    var arr = new Array(width);
    for(var x = 0; x < width; x++) {
      arr[x] = [];
      for(var y = 0; y < height; y++) {
        arr[x][y] = defaultValue;
      }
    }
    return arr;
  }

  function assertTile(tile) {
    if(!tile) { throw new Error(ERR.NO_TILE); }
    if(!tile.pos) { throw new Error(ERR.NO_POS); }
    if(!tile.size) { throw new Error(ERR.NO_SIZE); }
    return true;
  }

  return {
    DEFAULT_SIZE: [6, 3],
    makeGrid: function makeGrid(params) { // (Any) -> Grid
      if(!params) { throw new Error(ERR.NO_PARAMS); }
      var bounds = params.bounds || params.container;
      if(typeof bounds === "string") {
        bounds = document.querySelector(bounds);
      }
      if(bounds && bounds.nodeType) {
        bounds = bounds.getBoundingClientRect();
      }
      if(!bounds) { throw new Error(ERR.NO_BOUNDS); }

      var grid = {
        size: params.size || [12, 12],
        bounds: {top: bounds.top, left: bounds.left, bottom: bounds.bottom, right: bounds.right, width: bounds.width, height: bounds.height},
        gutter: params.gutter || 0,
      };

      var gapWidth = grid.gutter * (grid.size[0] - 1);
      var gapHeight = grid.gutter * (grid.size[1] - 1);
      grid.calculated = {
        cellWidth: (grid.bounds.width - gapWidth) / grid.size[0],
        cellHeight: (grid.bounds.height - gapHeight) / grid.size[1],
        snapWidth: grid.bounds.width / grid.size[0],
        snapHeight: grid.bounds.height / grid.size[1]
      };
      return grid;
    },
    getRect: function getRect(grid, tile) { // (Grid, Tile) -> Rect
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);

      var rect = {
        left: grid.bounds.left + tile.pos[0] * grid.calculated.cellWidth + tile.pos[0] * grid.gutter,
        top: grid.bounds.top + tile.pos[1] * grid.calculated.cellHeight + tile.pos[1] * grid.gutter,
        width: tile.size[0] * grid.calculated.cellWidth + (tile.size[0] - 1) * grid.gutter,
        height: tile.size[1] * grid.calculated.cellHeight + (tile.size[1] - 1) * grid.gutter
      };
      // rect.right = grid.bounds.right - (rect.left + rect.width);
      // rect.bottom = grid.bounds.bottom - (rect.top + rect.height);
      return rect;
    },
    evacuateTile: function evacuateRect(grid, tile, from, force) { // (Grid, Tile, Pos?, Bool?) -> Tile
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      from = from || [grid.size[0] / 2, grid.size[1] / 2];

      var xOffset = tile.pos[0] - from[0];
      var yOffset = tile.pos[1] - from[1];
      var xEdge = xOffset > 0 ? grid.size[0] + 1 : (xOffset < 0 ? -tile.size[0] - 1 : tile.pos[0]);
      var yEdge = yOffset > 0 ? grid.size[1] + 1 : (yOffset < 0 ? -tile.size[1] - 1 : tile.pos[0]);

      if(force && xEdge === tile.pos[0] && yEdge === tile.pos[1]) {
        yEdge = grid.size[1] + 1;
      }

      return {pos: [xEdge, yEdge], size: tile.size};
    },
    confineTile: function confineRect(grid, tile, to) { // (Grid, Tile, Tile) -> Tile
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      assertTile(to);
      var res = {pos: [tile.pos[0], tile.pos[1]], size: [tile.size[0], tile.size[1]]};
      // Lower bounds
      if(res.pos[0] < to.pos[0]) { res.pos[0] = to.pos[0]; }
      if(res.pos[1] < to.pos[1]) { res.pos[1] = to.pos[1]; }

      // Upper bounds
      if(res.size[0] > to.size[0]) {res.size[0] = to.size[0]; }
      if(res.size[1] > to.size[1]) {res.size[1] = to.size[1]; }

      // Preserve size to greatest possible extent.
      var dx = res.pos[0] + res.size[0] - (to.pos[0] + to.size[0]);
      if(dx > 0) { res.pos[0] = Math.max(res.pos[0] - dx, to.pos[0]); }
      var dy = res.pos[1] + res.size[1] - (to.pos[1] + to.size[1]);
      if(dy > 0) { res.pos[1] = Math.max(res.pos[1] - dy, to.pos[1]); }

      return res;
    },
    coordsToPos: function coordsToPos(grid, x, y, round) { // (Grid, N, N, Bool?) -> Pos
      if(!grid) { throw new Error(ERR.NO_GRID); }
      x = (x - grid.bounds.left) / grid.calculated.snapWidth;
      y = (y - grid.bounds.top) / grid.calculated.snapHeight;
      if(round) { return [Math.round(x), Math.round(y)]; }
      else { return [Math.floor(x), Math.floor(y)]; }
    },
    coordsToSize: function coordsToSize(grid, w, h, round) { // (Grid, N, N, Bool?) -> Size
      if(!grid) { throw new Error(ERR.NO_GRID); }
      w = w / grid.calculated.snapWidth;
      h = h / grid.calculated.snapHeight;
      if(round) { return [Math.round(w), Math.round(h)]; }
      else { return [Math.floor(w), Math.floor(h)]; }
    },
    tilesToMap: function tilesToMap(grid, tiles) { // (Grid, Tile[]) -> TileMap
      var map = make2DArray(grid.size[0], grid.size[1], 0);
      for(var ix = 0, len = tiles.length; ix < len; ix++) {
        var tile = tiles[ix];
        for(var x = tile.pos[0]; x < tile.pos[0] + tile.size[0]; x++) {
          for(var y = tile.pos[1]; y < tile.pos[1] + tile.size[1]; y++) {
            map[x][y]++;
          }
        }
      }
      return map;
    },
    hasGapAt: function hasGapAt(grid, tiles, tile, map) { // (Grid, Tile[], Pos, Size, TileMap?) -> Bool
      if(!grid) { throw new Error(ERR.NO_GRID); }
      assertTile(tile);
      if(!map) { map = Grid.tilesToMap(grid, tiles); }

      if(tile.pos[0] < 0) { return false; }
      if(tile.pos[1] < 0) { return false; }
      if(tile.pos[0] + tile.size[0] > grid.size[0]) { return false; }
      if(tile.pos[1] + tile.size[1] > grid.size[1]) { return false; }

      for(var x = tile.pos[0]; x < tile.pos[0] + tile.size[0]; x++) {
        for(var y = tile.pos[1]; y < tile.pos[1] + tile.size[1]; y++) {
          if(map[x][y] > 0) {
            return false;
          }
        }
      }
      return true;
    },
    findGap: function findGap(grid, tiles, size) { // (Grid, Tile[], Size) -> Pos?
      if(!grid) { throw new Error(ERR.NO_GRID); }
      if(!size) { throw new Error(ERR.NO_SIZE); }
      var map = Grid.tilesToMap(grid, tiles);
      var tile = {pos: undefined, size: size};
      for(var x = 0; x <= grid.size[0] - size[0]; x++) {
        for(var y = 0; y <= grid.size[1] - size[1]; y++) {
          if(map[x][y] > 0) { continue; }
          tile.pos = [x, y];
          if(Grid.hasGapAt(grid, tiles, tile, map)) {
            return [x, y];
          }
        }
      }
    },
    tilesToText: function(grid, tiles) {
      var map = Grid.tilesToMap(grid, tiles);
      var result = [];
      for(var x = 0; x < map.length; x++) {
        for(var y = 0; y < map[x].length; y++) {
          result[y] = result[y] || [];
          result[y][x] = map[x][y];
        }
      }
      return result.map(function(row) { return row.join(" | "); }).join("\n");
    }
  };
})(window.document, React, Velocity);
window.Grid = Grid;
<|endoftext|>


<commit_before>var SMB = require( '../../smb' )
var Packet = require( '../../packet' )
var inherit = require( 'bloodline' )

/**
 * TreeConnectResponse Constructor
 * @return {TreeConnectResponse}
 */
function TreeConnectResponse( options ) {

  if( !(this instanceof TreeConnectResponse) )
    return new TreeConnectResponse( options )

  Packet.call( this )

}

/**
 * TreeConnectResponse Prototype
 * @type {Object}
 */
TreeConnectResponse.prototype = {

  constructor: TreeConnectResponse,

  parsePayload: function( buffer ) {

    return this

  },

  serialize: function() {
    return buffer
  },

}

inherit( TreeConnectResponse, Packet )
// Exports
module.exports = TreeConnectResponse
<commit_msg>Implemented tree-connect/response<commit_after>var SMB = require( '../../smb' )
var Packet = require( '../../packet' )
var inherit = require( 'bloodline' )

/**
 * TreeConnectResponse Constructor
 * The TREE_CONNECT Response packet is sent by the server
 * when a TREE_CONNECT request is processed successfully by the server.
 * The server MUST set the 'TreeId' of the newly created tree connect
 * in the SMB Protocol header of the response.
 * @return {TreeConnectResponse}
 */
function TreeConnectResponse( options ) {

  if( !(this instanceof TreeConnectResponse) )
    return new TreeConnectResponse( options )

  Packet.call( this )

  this.header.command = SMB.COMMAND.TREE_CONNECT

  this.structureSize = TreeConnectResponse.size
  this.shareType = 0x00
  this.reserved = 0x00
  this.shareFlags = 0x00000000
  this.capabilities = 0x00000000
  this.maximalAccess = 0x00000000

}

/**
 * TREE_CONNECT Response structure size
 * @type {Number}
 */
TreeConnectResponse.size = 0x0010

/**
 * TreeConnectResponse Prototype
 * @type {Object}
 */
TreeConnectResponse.prototype = {

  constructor: TreeConnectResponse,

  parsePayload: function( buffer ) {

    this.structureSize = buffer.readUInt16LE( 0 )
    this.shareType = buffer.readUInt8( 2 )
    this.reserved = buffer.readUInt8( 3 )
    this.shareFlags = buffer.readUInt32LE( 4 )
    this.capabilities = buffer.readUInt32LE( 8 )
    this.maximalAccess = buffer.readUInt32LE( 12 )

    return this

  },

  serialize: function() {

    var buffer = new Buffer( this.structureSize )
    buffer.fill( 0 )

    buffer.writeUInt16LE( this.structureSize, 0 )
    buffer.writeUInt8( this.shareType, 2 )
    buffer.writeUInt8( this.reserved, 3 )
    buffer.writeUInt32LE( this.shareFlags, 4 )
    buffer.writeUInt32LE( this.capabilities, 8 )
    buffer.writeUInt32LE( this.maximalAccess, 12 )

    return buffer

  },

}

inherit( TreeConnectResponse, Packet )
// Exports
module.exports = TreeConnectResponse
<|endoftext|>


<commit_before>if (typeof(lowpoly) === 'undefined')
{
	var lowpoly = {
	linesWithAnchor: {},
	anchorsForLine: {},
	currentLayer: undefined,
	layers: {},
	lastAnchors: [],
	trianglesForAnchor: []
	};
}

lowpoly.init = function()
{
	var width = window.innerWidth;
	var height = window.innerHeight;

	lowpoly.stage = new Konva.Stage({
		container: 'container',
		width: width,
		height: height
	});

	var bg_image_obj = new Image();
	bg_image_obj.src = 'test.jpg';
	bg_image_obj.onload = function()
	{
		var image_layer = new Konva.Layer();
		var image = new Konva.Image({
			image: bg_image_obj,
			x: 0,
			y: 0
		});
		image_layer.add(image);
		lowpoly.stage.add(image_layer);
		image_layer.moveToBottom();
		image.on('click', lowpoly.stageClick);
	}

	var anchor_layer = new Konva.Layer();
	var line_layer = new Konva.Layer();
	var poly_layer = new Konva.Layer();
	lowpoly.layers["main"] = {
		anchors: anchor_layer,
		lines: line_layer,
		polys: poly_layer
	}
	lowpoly.currentLayer = "main";

	lowpoly.stage.add(anchor_layer);
	lowpoly.stage.add(line_layer);
	lowpoly.stage.add(poly_layer);
}

lowpoly.stageClick = function(event)
{
	if (!event.evt.shiftKey && !event.evt.altKey)
		lowpoly.lastAnchors = [];
	if (event.evt.shiftKey && lowpoly.lastAnchors.length == 2)
		lowpoly.lastAnchors.shift();
	var x = event.evt.x;
	var y = event.evt.y;
	// draw new anchor
	var anchor = new Konva.Circle({
		radius: 5,
		x: x,
		y: y,
		fill: 'white',
		stroke: 'black',
		draggable: 'true'
	});
	anchor.on("click", lowpoly.anchorClick);
	anchor.on("dragstart dragmove dragend", lowpoly.anchorDrag);
	var layer = lowpoly.layers[lowpoly.currentLayer];
	layer.anchors.add(anchor);
	lowpoly.stage.add(layer.anchors);

	lowpoly.linesWithAnchor[anchor._id] = [];
	lowpoly.trianglesForAnchor[anchor._id] = [];

	// draw lines
	if (lowpoly.lastAnchors.length > 0)
	{
		var prev = lowpoly.lastAnchors[0];
		lowpoly.connectAnchors(prev, anchor);
	}
	if (lowpoly.lastAnchors.length == 2)
	{
		var prev = lowpoly.lastAnchors[1];
		lowpoly.connectAnchors(prev, anchor);
		lowpoly.lastAnchors.shift();
	}
	lowpoly.lastAnchors.push(anchor);
	lowpoly.stage.add(layer.lines);
	lowpoly.stage.add(layer.anchors);
}

lowpoly.connectAnchors = function(a1, a2)
{
	var line = new Konva.Line({
		points: [a1.x(), a1.y(), a2.x(), a2.y()],
		stroke: 'black'
	});
	var layer = lowpoly.layers[lowpoly.currentLayer];
	layer.lines.add(line);
	lowpoly.linesWithAnchor[a1._id].push(line);
	lowpoly.linesWithAnchor[a2._id].push(line);
	lowpoly.anchorsForLine[line._id] = [a1, a2];
	// detect new triangles
	a1neighbours = {};
	lines = lowpoly.linesWithAnchor[a1._id];
	for (line in lines)
	{
		lineId = lines[line]._id;
		lineAnchors = lowpoly.anchorsForLine[lineId];
		if (a1 != lineAnchors[0] && a2 != lineAnchors[0])
			a1neighbours[lineAnchors[0]._id] = lineAnchors[0];
		else if (a1 != lineAnchors[1] && a2 != lineAnchors[1])
			a1neighbours[lineAnchors[1]._id] = lineAnchors[1];
	}
	a2neighbours = {};
	lines = lowpoly.linesWithAnchor[a2._id];
	for (line in lines)
	{
		lineId = lines[line]._id;
		lineAnchors = lowpoly.anchorsForLine[lineId];
		if (a2 != lineAnchors[0] && a1 != lineAnchors[0])
			a2neighbours[lineAnchors[0]._id] = lineAnchors[0];
		else if (a2 != lineAnchors[1] && a1 != lineAnchors[1])
			a2neighbours[lineAnchors[1]._id] = lineAnchors[1];
	}

	if (a1neighbours.size < a2neighbours.size)
	{
		n1 = a1neighbours;
		n2 = a2neighbours;
	}
	else
	{
		n1 = a2neighbours;
		n2 = a1neighbours;
	}

	for (n in n1)
	{
		if (n in n2)
		{
			fill_colour = lowpoly.getColourForTriangle(a1, a2, n1[n]);
			tri = new Konva.Line({
				points: [a1.x(), a1.y(), a2.x(), a2.y(), n1[n].x(), n1[n].y()],
				strokeWidth: 0,
				closed: true,
				fill: fill_colour
			})
			lowpoly.trianglesForAnchor[a1._id].push(tri);
			lowpoly.trianglesForAnchor[a2._id].push(tri);
			lowpoly.trianglesForAnchor[n1[n]._id].push(tri);
			lowpoly.layers[lowpoly.currentLayer].polys.add(tri);
			lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].polys);
		}
	}
}

lowpoly.anchorClick = function(event)
{
	if (lowpoly.lastAnchors.length == 0)
	{
		lowpoly.lastAnchors.push(event.target);
		return;
	}
	if (lowpoly.lastAnchors.length == 2)
		lowpoly.lastAnchors.shift();
	if (event.evt.shiftKey)
	{
		lowpoly.connectAnchors(lowpoly.lastAnchors[0], event.target);
	}
	lowpoly.lastAnchors.push(event.target);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].lines);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].anchors);
}

lowpoly.redrawLine = function(line)
{
	a1 = lowpoly.anchorsForLine[line._id][0];
	a2 = lowpoly.anchorsForLine[line._id][1];
	line.setPoints([a1.x(), a1.y(), a2.x(), a2.y()]);
}

lowpoly.anchorDrag = function(event)
{
	anchor = event.target;
	lines = lowpoly.linesWithAnchor[anchor._id];
	for (line in lines)
	{
		lowpoly.redrawLine(lines[line]);
	}
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].lines);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].anchors);
}

lowpoly.getColourForTriangle = function(a1, a2, a3)
{
	var x = (a1.x() + a2.x() + a3.x()) / 3;
	var y = (a1.y() + a2.y() + a3.y()) / 3;
	var colour = lowpoly.stage.children[0].canvas._canvas.getContext('2d').getImageData(x, y, 1, 1).data;
	var ret = 'rgb(' + colour[0] + ', ' + colour[1] + ', ' + colour[2] + ')';
	return ret;
}
<commit_msg>Change order of layers to keep anchors selectable.<commit_after>if (typeof(lowpoly) === 'undefined')
{
	var lowpoly = {
	linesWithAnchor: {},
	anchorsForLine: {},
	currentLayer: undefined,
	layers: {},
	lastAnchors: [],
	trianglesForAnchor: []
	};
}

lowpoly.init = function()
{
	var width = window.innerWidth;
	var height = window.innerHeight;

	lowpoly.stage = new Konva.Stage({
		container: 'container',
		width: width,
		height: height
	});

	var bg_image_obj = new Image();
	bg_image_obj.src = 'test.jpg';
	bg_image_obj.onload = function()
	{
		var image_layer = new Konva.Layer();
		var image = new Konva.Image({
			image: bg_image_obj,
			x: 0,
			y: 0
		});
		image_layer.add(image);
		lowpoly.stage.add(image_layer);
		image_layer.moveToBottom();
		image.on('click', lowpoly.stageClick);
	}

	var anchor_layer = new Konva.Layer();
	var line_layer = new Konva.Layer();
	var poly_layer = new Konva.Layer();
	lowpoly.layers["main"] = {
		anchors: anchor_layer,
		lines: line_layer,
		polys: poly_layer
	}
	lowpoly.currentLayer = "main";

	lowpoly.stage.add(line_layer);
	lowpoly.stage.add(poly_layer);
	lowpoly.stage.add(anchor_layer);
}

lowpoly.stageClick = function(event)
{
	if (!event.evt.shiftKey && !event.evt.altKey)
		lowpoly.lastAnchors = [];
	if (event.evt.shiftKey && lowpoly.lastAnchors.length == 2)
		lowpoly.lastAnchors.shift();
	var x = event.evt.x;
	var y = event.evt.y;
	// draw new anchor
	var anchor = new Konva.Circle({
		radius: 5,
		x: x,
		y: y,
		fill: 'white',
		stroke: 'black',
		draggable: 'true'
	});
	anchor.on("click", lowpoly.anchorClick);
	anchor.on("dragstart dragmove dragend", lowpoly.anchorDrag);
	var layer = lowpoly.layers[lowpoly.currentLayer];
	layer.anchors.add(anchor);
	lowpoly.stage.add(layer.anchors);

	lowpoly.linesWithAnchor[anchor._id] = [];
	lowpoly.trianglesForAnchor[anchor._id] = [];

	// draw lines
	if (lowpoly.lastAnchors.length > 0)
	{
		var prev = lowpoly.lastAnchors[0];
		lowpoly.connectAnchors(prev, anchor);
	}
	if (lowpoly.lastAnchors.length == 2)
	{
		var prev = lowpoly.lastAnchors[1];
		lowpoly.connectAnchors(prev, anchor);
		lowpoly.lastAnchors.shift();
	}
	lowpoly.lastAnchors.push(anchor);
	lowpoly.stage.add(layer.lines);
	lowpoly.stage.add(layer.anchors);
}

lowpoly.connectAnchors = function(a1, a2)
{
	var line = new Konva.Line({
		points: [a1.x(), a1.y(), a2.x(), a2.y()],
		stroke: 'black'
	});
	var layer = lowpoly.layers[lowpoly.currentLayer];
	layer.lines.add(line);
	lowpoly.linesWithAnchor[a1._id].push(line);
	lowpoly.linesWithAnchor[a2._id].push(line);
	lowpoly.anchorsForLine[line._id] = [a1, a2];
	// detect new triangles
	a1neighbours = {};
	lines = lowpoly.linesWithAnchor[a1._id];
	for (line in lines)
	{
		lineId = lines[line]._id;
		lineAnchors = lowpoly.anchorsForLine[lineId];
		if (a1 != lineAnchors[0] && a2 != lineAnchors[0])
			a1neighbours[lineAnchors[0]._id] = lineAnchors[0];
		else if (a1 != lineAnchors[1] && a2 != lineAnchors[1])
			a1neighbours[lineAnchors[1]._id] = lineAnchors[1];
	}
	a2neighbours = {};
	lines = lowpoly.linesWithAnchor[a2._id];
	for (line in lines)
	{
		lineId = lines[line]._id;
		lineAnchors = lowpoly.anchorsForLine[lineId];
		if (a2 != lineAnchors[0] && a1 != lineAnchors[0])
			a2neighbours[lineAnchors[0]._id] = lineAnchors[0];
		else if (a2 != lineAnchors[1] && a1 != lineAnchors[1])
			a2neighbours[lineAnchors[1]._id] = lineAnchors[1];
	}

	if (a1neighbours.size < a2neighbours.size)
	{
		n1 = a1neighbours;
		n2 = a2neighbours;
	}
	else
	{
		n1 = a2neighbours;
		n2 = a1neighbours;
	}

	for (n in n1)
	{
		if (n in n2)
		{
			fill_colour = lowpoly.getColourForTriangle(a1, a2, n1[n]);
			tri = new Konva.Line({
				points: [a1.x(), a1.y(), a2.x(), a2.y(), n1[n].x(), n1[n].y()],
				strokeWidth: 0,
				closed: true,
				fill: fill_colour
			})
			lowpoly.trianglesForAnchor[a1._id].push(tri);
			lowpoly.trianglesForAnchor[a2._id].push(tri);
			lowpoly.trianglesForAnchor[n1[n]._id].push(tri);
			lowpoly.layers[lowpoly.currentLayer].polys.add(tri);
			lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].polys);
		}
	}
}

lowpoly.anchorClick = function(event)
{
	if (lowpoly.lastAnchors.length == 0)
	{
		lowpoly.lastAnchors.push(event.target);
		return;
	}
	if (lowpoly.lastAnchors.length == 2)
		lowpoly.lastAnchors.shift();
	if (event.evt.shiftKey)
	{
		lowpoly.connectAnchors(lowpoly.lastAnchors[0], event.target);
	}
	lowpoly.lastAnchors.push(event.target);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].lines);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].anchors);
}

lowpoly.redrawLine = function(line)
{
	a1 = lowpoly.anchorsForLine[line._id][0];
	a2 = lowpoly.anchorsForLine[line._id][1];
	line.setPoints([a1.x(), a1.y(), a2.x(), a2.y()]);
}

lowpoly.anchorDrag = function(event)
{
	anchor = event.target;
	lines = lowpoly.linesWithAnchor[anchor._id];
	for (line in lines)
	{
		lowpoly.redrawLine(lines[line]);
	}
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].lines);
	lowpoly.stage.add(lowpoly.layers[lowpoly.currentLayer].anchors);
}

lowpoly.getColourForTriangle = function(a1, a2, a3)
{
	var x = (a1.x() + a2.x() + a3.x()) / 3;
	var y = (a1.y() + a2.y() + a3.y()) / 3;
	var colour = lowpoly.stage.children[0].canvas._canvas.getContext('2d').getImageData(x, y, 1, 1).data;
	var ret = 'rgb(' + colour[0] + ', ' + colour[1] + ', ' + colour[2] + ')';
	return ret;
}
<|endoftext|>


<commit_before>import assert from 'assert';

import bucketclient from 'bucketclient';

import Config from '../../Config';

class BucketClientInterface {
    constructor() {
        const config = new Config();
        assert(config.bucketd.bootstrap.length > 0,
               'bucketd bootstrap list is empty');
        this.client = new bucketclient.RESTClient(config.bucketd.bootstrap,
                                                  config.log);
    }

    createBucket(bucketName, bucketMD, log, cb) {
        this.client.createBucket(bucketName, log.getSerializedUids(),
            JSON.stringify(bucketMD), err => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err);
            });
    }

    getBucketAttributes(bucketName, log, cb) {
        this.client.getBucketAttributes(bucketName, log.getSerializedUids(),
            (err, data) => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    putBucketAttributes(bucketName, bucketMD, log, cb) {
        this.client.putBucketAttributes(bucketName, log.getSerializedUids(),
            JSON.stringify(bucketMD), (err, data) => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err, data);
            });
    }

    deleteBucket(bucketName, log, cb) {
        this.client.deleteBucket(bucketName, log.getSerializedUids(), err => {
            if (err instanceof Error) {
                return cb(err);
            }
            return cb(err);
        });
    }

    putObject(bucketName, objName, objVal, log, cb) {
        this.client.putObject(bucketName, objName, JSON.stringify(objVal),
            log.getSerializedUids(), err => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err);
            });
    }

    getObject(bucketName, objName, log, cb) {
        this.client.getObject(bucketName, objName, log.getSerializedUids(),
            (err, data) => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    deleteObject(bucketName, objName, log, cb) {
        this.client.deleteObject(bucketName, objName, log.getSerializedUids(),
            err => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err);
            });
    }

    listObject(bucketName, params, log, cb) {
        this.client.listObject(bucketName, log.getSerializedUids(), params,
            (err, data) => {
                if (err instanceof Error) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    listMultipartUploads(bucketName, params, log, cb) {
        this.client.listObject(bucketName, log.getSerializedUids(), params,
            (err, data) => {
                return cb(err, JSON.parse(data));
            });
    }
}

export default BucketClientInterface;
<commit_msg>CLEANUP - metadata bucketclient backend<commit_after>import assert from 'assert';

import bucketclient from 'bucketclient';

import Config from '../../Config';

class BucketClientInterface {
    constructor() {
        const config = new Config();
        assert(config.bucketd.bootstrap.length > 0,
               'bucketd bootstrap list is empty');
        this.client = new bucketclient.RESTClient(config.bucketd.bootstrap,
                                                  config.log);
    }

    createBucket(bucketName, bucketMD, log, cb) {
        this.client.createBucket(bucketName, log.getSerializedUids(),
            JSON.stringify(bucketMD), cb);
    }

    getBucketAttributes(bucketName, log, cb) {
        this.client.getBucketAttributes(bucketName, log.getSerializedUids(),
            (err, data) => {
                if (err) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    putBucketAttributes(bucketName, bucketMD, log, cb) {
        this.client.putBucketAttributes(bucketName, log.getSerializedUids(),
            JSON.stringify(bucketMD), cb);
    }

    deleteBucket(bucketName, log, cb) {
        this.client.deleteBucket(bucketName, log.getSerializedUids(), cb);
    }

    putObject(bucketName, objName, objVal, log, cb) {
        this.client.putObject(bucketName, objName, JSON.stringify(objVal),
            log.getSerializedUids(), cb);
    }

    getObject(bucketName, objName, log, cb) {
        this.client.getObject(bucketName, objName, log.getSerializedUids(),
            (err, data) => {
                if (err) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    deleteObject(bucketName, objName, log, cb) {
        this.client.deleteObject(bucketName, objName, log.getSerializedUids(),
                                 cb);
    }

    listObject(bucketName, params, log, cb) {
        this.client.listObject(bucketName, log.getSerializedUids(), params,
            (err, data) => {
                if (err) {
                    return cb(err);
                }
                return cb(err, JSON.parse(data));
            });
    }

    listMultipartUploads(bucketName, params, log, cb) {
        this.client.listObject(bucketName, log.getSerializedUids(), params,
            (err, data) => {
                return cb(err, JSON.parse(data));
            });
    }
}

export default BucketClientInterface;
<|endoftext|>


<commit_before><commit_msg>Removed unused file.<commit_after><|endoftext|>


<commit_before>"use strict";

define([
    "/jquery.js"
], function () {

    var self;

    function init(config) {
        self = this;

        if(config.sample) {
            buildSampleConfiguration(config);
        }

        var container = $(config.container, self.dom);

        // On tab click
        $(config.tabs, self.dom).on('click', function() {
            // Change the hash in URL
            if (config.options.hash) {
                window.location.hash = $(this).attr('data-hash');
                return;
            }
            activateTab(config, $(this));
            return false;
        });

        // hashchange handler
        $(window).on('hashchange', function () {
            var tab = $("[data-hash=" + window.location.hash.substring(1) +  "]");
            activateTab(config, tab);
        })

        // Load first content
        if((config.options.first) && (!window.location.hash)) {
            M(config.container, config.options.first);
            return;
        }

        // Load the right content for hash
        if((window.location.hash) && (config.options.hash)) {
            var tab = $("[data-hash=" + window.location.hash.substring(1) +  "]");
            activateTab(config, tab);
            return;
        }
    }

    function activateTab(config, tab) {
        // Removes the active class
        $(config.tabs).removeClass(config.options.classes.selected);

        // Removes the content of container
        $(config.container).html("");

        // Adds active class
        tab.addClass(config.options.classes.selected);

        // Sets the content in container
        M(config.container, tab.attr("data-miid"));
    }

    function buildSampleConfiguration(config) {
        config.container = "#content";
        config.tabs = ".nav-tabs li";
        config.options = {};
        config.options.classes = { selected: "active" };
        config.options.first = "tabContent1";
        config.options.hash = true;
    }

    return init;
});
<commit_msg>Replaced return with return false.<commit_after>"use strict";

define([
    "/jquery.js"
], function () {

    var self;

    function init(config) {
        self = this;

        if(config.sample) {
            buildSampleConfiguration(config);
        }

        var container = $(config.container, self.dom);

        // On tab click
        $(config.tabs, self.dom).on('click', function() {
            // Change the hash in URL
            if (config.options.hash) {
                window.location.hash = $(this).attr('data-hash');
                return false;
            }
            activateTab(config, $(this));
            return false;
        });

        // hashchange handler
        $(window).on('hashchange', function () {
            var tab = $("[data-hash=" + window.location.hash.substring(1) +  "]");
            activateTab(config, tab);
        })

        // Load first content
        if((config.options.first) && (!window.location.hash)) {
            M(config.container, config.options.first);
            return;
        }

        // Load the right content for hash
        if((window.location.hash) && (config.options.hash)) {
            var tab = $("[data-hash=" + window.location.hash.substring(1) +  "]");
            activateTab(config, tab);
            return;
        }
    }

    function activateTab(config, tab) {
        // Removes the active class
        $(config.tabs).removeClass(config.options.classes.selected);

        // Removes the content of container
        $(config.container).html("");

        // Adds active class
        tab.addClass(config.options.classes.selected);

        // Sets the content in container
        M(config.container, tab.attr("data-miid"));
    }

    function buildSampleConfiguration(config) {
        config.container = "#content";
        config.tabs = ".nav-tabs li";
        config.options = {};
        config.options.classes = { selected: "active" };
        config.options.first = "tabContent1";
        config.options.hash = true;
    }

    return init;
});
<|endoftext|>


<commit_before>/**
 * Nextcloud - passman
 *
 * @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

(function () {
	'use strict';
	/**
	 * @ngdoc directive
	 * @name passmanApp.directive:passwordGen
	 * @description
	 * # passwordGen
	 */

	angular.module('passmanApp')
		.directive('credentialField', ['$timeout', '$translate', function ($timeout, $translate) {
			return {
				scope: {
					value: '=value',
					secret: '=secret',
					inputField: '=useInput',
					inputFieldplaceholder: '=inputPlaceholder',
					isURL: '=isurl'
				},
				restrict: 'A',
				replace: 'true',
				template: "" +
				'' +
				'
' +
				'*' +
				'' +
				'<input type="text" ng-model="value" select-on-click placeholder="{{ inputFieldplaceholder }}!"' +
				'
' +
				'
' +
				'

' +
				'

' +
                '

' +
				'
',
				link: function (scope) {
                    var expression = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
					var regex = new RegExp(expression);
					$translate(['toggle.visibility','copy.field', 'copy', 'copied']).then(function (translations) {
						scope.tggltxt = translations['toggle.visibility'];
						scope.copy_msg = translations['copy.field'];
					});

					scope.$watch("value", function () {
						if (scope.value) {
							if (scope.secret) {
								scope.valueVisible = false;
							}
							if (regex.test(scope.value)) {
								scope.isLink = true;
							} else if (regex.test('http://'+scope.value) && scope.isURL){
                                //This part is added to check if the user did not add http or https to the url and match it nonetheless
                                scope.isLink = true;
							} else {
                                scope.isLink = false;
							}
						}
					});
					if (!scope.toggle) {
						if (scope.secret) {
							scope.toggle = true;
						}
					}

					var timer;
					scope.onSuccess = function () {
						scope.copy_msg = $translate.instant('copied') ;
						$timeout.cancel(timer);
						timer = $timeout(function () {
							scope.copy_msg = $translate.instant('copy');
						}, 5000);
					};
					scope.valueVisible = true;
					scope.toggleVisibility = function () {
						scope.valueVisible = !scope.valueVisible;
					};
				}
			};
		}]);

}());
<commit_msg>Fixed Linkdetection<commit_after>/**
 * Nextcloud - passman
 *
 * @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

(function () {
	'use strict';
	/**
	 * @ngdoc directive
	 * @name passmanApp.directive:passwordGen
	 * @description
	 * # passwordGen
	 */

	angular.module('passmanApp')
		.directive('credentialField', ['$timeout', '$translate', function ($timeout, $translate) {
			return {
				scope: {
					value: '=value',
					secret: '=secret',
					inputField: '=useInput',
					inputFieldplaceholder: '=inputPlaceholder',
					isURL: '=isurl'
				},
				restrict: 'A',
				replace: 'true',
				template: "" +
				'' +
				'
' +
				'*' +
				'' +
				'<input type="text" ng-model="value" select-on-click placeholder="{{ inputFieldplaceholder }}!"' +
				'
' +
				'
' +
				'

' +
				'

' +
                		'

' +
				'
',
				link: function (scope) {
                    			var expression = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
					var regex = new RegExp(expression);
					$translate(['toggle.visibility','copy.field', 'copy', 'copied']).then(function (translations) {
						scope.tggltxt = translations['toggle.visibility'];
						scope.copy_msg = translations['copy.field'];
					});

					scope.$watch("value", function () {
						if (scope.value) {
							if (scope.secret) {
								scope.valueVisible = false;
							}
							if (regex.test(scope.value)) {
								scope.isLink = true;
								if(scope.value.substr(0,4) !== 'http'){
									var val = scope.value;
									scope.value =val.substr(val.indexOf("://")+3,val.length);
								}
							} else if (regex.test('http://'+scope.value) && scope.isURL){
                                				//This part is added to check if the user did not add http or https to the url and match it nonetheless
                                				scope.isLink = true;
							} else {
                                				scope.isLink = false;
							}
						}
					});
					if (!scope.toggle) {
						if (scope.secret) {
							scope.toggle = true;
						}
					}

					var timer;
					scope.onSuccess = function () {
						scope.copy_msg = $translate.instant('copied') ;
						$timeout.cancel(timer);
						timer = $timeout(function () {
							scope.copy_msg = $translate.instant('copy');
						}, 5000);
					};
					scope.valueVisible = true;
					scope.toggleVisibility = function () {
						scope.valueVisible = !scope.valueVisible;
					};
				}
			};
		}]);

}());
<|endoftext|>


<commit_before>'use strict';

// Polyfill for requestAnimationFrame() / cancelAnimationFrame()
(function() {
  var lastTime = 0;
  var vendors = ['webkit', 'moz', 'ms', 'o'];

  for (var i = 0; i < vendors.length && !window.requestAnimationFrame; i++) {
    window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] ||
      window[vendors[i] + 'RequestCancelAnimationFrame'];
  }

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      var currTime = Date.now();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() {
        callback(currTime + timeToCall);
      }, timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  }

  if (!window.cancelAnimationFrame) {
    window.cancelAnimationFrame = function(id) {
      window.clearTimeout(id);
    };
  }
})();

var SKScrollEventType = {
  ScrollStart: 'SKScrollStart',
  ScrollEnd: 'SKScrollEnd'
};

var SKScrollBarType = {
  Horizontal: 0,
  Vertical: 1
};

var SKScrollView = function(element) {
  var kBounceTransitionDuration = 0.35;
  var kAccelerationTimeout = 250;
  var kAcceleration = 15;
  var kElasticDeceleration = 0.03;
  var kElasticAcceleration = 0.08;
  var kMinimumDecelerationVelocity = 1;
  var kDecelerationFactor = 0.95;
  var kMinimumVelocity = 0.01;
  var kScrollBarHideTimeout = 100;

  var _isDragging = false;
  var _isDecelerating = false;
  var _isScrolling = false;
  var _startAccelerateX = 0;
  var _startAccelerateY = 0;
  var _lastMouseX = -1;
  var _lastMouseY = -1;
  var _lastTimeStamp = Date.now();
  var _decelerationAnimationInterval = null;

  var $window = $(window['addEventListener'] ? window : document.body);
  var $element = this.$element = $(element);
  element = this.element = $(element).get(0);

  var content = this.content = new SKScrollContent(this);
  var horizontalScrollBar = this.horizontalScrollBar = new SKScrollBar(this, SKScrollBarType.Horizontal);
  var verticalScrollBar = this.verticalScrollBar = new SKScrollBar(this, SKScrollBarType.Vertical);
  var self = this;

  var startDeceleration = function(startTime) {
    var acceleration = (startTime - _lastTimeStamp) / kAcceleration;
    var accelerateDeltaX = self.x - _startAccelerateX;
    var accelerateDeltaY = self.y - _startAccelerateY;
    var velocityX = accelerateDeltaX / acceleration;
    var velocityY = accelerateDeltaY / acceleration;
    var minimumX = self.minimumX;
    var minimumY = self.minimumY;
    var elasticDeceleration = kElasticDeceleration;
    var elasticAcceleration = kElasticAcceleration;
    var lastFrameTime = 0;

    var stepAnimation = function (currentFrameTime) {
      if (!_isDecelerating) return;

      var deltaTime = currentFrameTime - lastFrameTime;
      var x = self.x = self.x + (!self.canScrollHorizontal() ? 0 : velocityX);
      var y = self.y = self.y + (!self.canScrollVertical() ? 0 : velocityY);

      velocityX *= kDecelerationFactor;
      velocityY *= kDecelerationFactor;

      if (Math.abs(velocityX) <= kMinimumVelocity &&
          Math.abs(velocityY) <= kMinimumVelocity) {
        _isDecelerating = false;
        scrollEnd();
        return;
      }

      content.translate(x, y);
      _decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);

      var elasticX = (x < minimumX) ? minimumX - x : (x > 0) ? -x : 0;
      var elasticY = (y < minimumY) ? minimumY - y : (y > 0) ? -y : 0;

      if (elasticX) velocityX = (elasticX * velocityX <= 0) ?
        velocityX + (elasticX * elasticDeceleration) : elasticX * elasticAcceleration;

      if (elasticY) velocityY = (elasticY * velocityY <= 0) ?
        velocityY + (elasticY * elasticDeceleration) : elasticY * elasticAcceleration;

      lastFrameTime = currentFrameTime;
    };

    if (Math.abs(velocityX) > kMinimumDecelerationVelocity ||
        Math.abs(velocityY) > kMinimumDecelerationVelocity) {
      _isDecelerating = true;
      _decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);
      lastFrameTime = Date.now();
    } else {
      scrollEnd();
    }
  };

  var stopDeceleration = function() {
    _isDecelerating = false;
    window.cancelAnimationFrame(_decelerationAnimationInterval);
  };

  var scrollStart = function() {
    if (_isScrolling) return;

    _isScrolling = true;

    if (self.canScrollHorizontal()) horizontalScrollBar.show();
    if (self.canScrollVertical()) verticalScrollBar.show();

    $element.trigger(SKScrollEventType.ScrollStart);
  };

  var scrollEnd = function() {
    if (!_isScrolling) return;

    _isScrolling = false;

    content.translate(self.x = Math.round(self.x), self.y = Math.round(self.y));

    if (self.canScrollHorizontal()) horizontalScrollBar.hide();
    if (self.canScrollVertical()) verticalScrollBar.hide();

    $element.trigger(SKScrollEventType.ScrollEnd);
  };

  var bounceTransitionEndHandler = function(evt) {
    $element.unbind(evt);
    scrollEnd();
  };

  $element.bind('mousedown touchstart', function(evt) {
    var scrollViewSize = self.getSize();
    var contentSize = content.getSize();

    self.minimumX = scrollViewSize.width - contentSize.width;
    self.minimumY = scrollViewSize.height - contentSize.height;

    _isDragging = true;
    _startAccelerateX = self.x;
    _startAccelerateY = self.y;
    _lastMouseX = (evt.type === 'touchstart') ? evt.originalEvent.touches[0].pageX : evt.pageX;
    _lastMouseY = (evt.type === 'touchstart') ? evt.originalEvent.touches[0].pageY : evt.pageY;
    _lastTimeStamp = evt.timeStamp;

    stopDeceleration();

    if (self.canScrollHorizontal()) horizontalScrollBar.update(true);
    if (self.canScrollVertical()) verticalScrollBar.update(true);

    if (evt.type === 'mousedown') evt.preventDefault();
  });

  $window.bind('mousemove touchmove', function(evt) {
    if (!_isDragging) return;

    var mouseX = (evt.type === 'touchmove') ? evt.originalEvent.touches[0].pageX : evt.pageX;
    var mouseY = (evt.type === 'touchmove') ? evt.originalEvent.touches[0].pageY : evt.pageY;
    var deltaX = mouseX - _lastMouseX;
    var deltaY = mouseY - _lastMouseY;
    var x = self.x + deltaX;
    var y = self.y + deltaY;

    x -= ((x < self.minimumX) ? deltaX : (x > 0) ? deltaX : 0) / 2;
    y -= ((y < self.minimumY) ? deltaY : (y > 0) ? deltaY : 0) / 2;
    x = self.x = !self.canScrollHorizontal() ? 0 : x;
    y = self.y = !self.canScrollVertical() ? 0 : y;

    content.translate(x, y);

    var accelerationTime = evt.timeStamp - _lastTimeStamp;

    if (accelerationTime > kAccelerationTimeout) {
      _startAccelerateX = x;
      _startAccelerateY = y;
      _lastTimeStamp = evt.timeStamp;
    }

    if (self.canScrollHorizontal()) horizontalScrollBar.update();
    if (self.canScrollVertical()) verticalScrollBar.update();
    if (!_isScrolling) scrollStart();

    _lastMouseX = mouseX;
    _lastMouseY = mouseY;

    evt.preventDefault();
  });

  $window.bind('mouseup touchend', function(evt) {
    if (!_isDragging) return;

    var timeStamp = evt.timeStamp;
    var accelerationTime = timeStamp - _lastTimeStamp;
    var x = Math.min(Math.max(self.minimumX, self.x), 0);
    var y = Math.min(Math.max(self.minimumY, self.y), 0);

    var bounce = function() {
      $element.bind('webkitTransitionEnd transitionend MSTransitionEnd oTransitionEnd transitionEnd', bounceTransitionEndHandler);
      content.translate(x, y, kBounceTransitionDuration);

      if (self.canScrollHorizontal()) horizontalScrollBar.hide();
      if (self.canScrollVertical()) verticalScrollBar.hide();

      self.x = _startAccelerateX = !self.canScrollHorizontal() ? 0 : x;
      self.y = _startAccelerateY = !self.canScrollVertical() ? 0 : y;
    };

    if (accelerationTime < kAccelerationTimeout) {
      if (x !== self.x || y !== self.y) {
        bounce();
      } else {
        startDeceleration(timeStamp);
      }
    } else if (x !== self.x || y !== self.y) {
      bounce();
    } else {
      scrollEnd();
    }

    _isDragging = false;
    _lastMouseX = -1;
    _lastMouseY = -1;
    _lastTimeStamp = timeStamp;

    evt.preventDefault();
  });

  $element.data('scrollView', this);
};

SKScrollView.prototype = {
  minimumX: 0,
  minimumY: 0,
  element: null,
  $element: null,
  content: null,
  horizontalScrollBar: null,
  verticalScrollBar: null,
  x: 0,
  y: 0,
  canScrollHorizontal: function() { return (this.minimumX < 0); },
  canScrollVertical: function() { return (this.minimumY < 0); },
  getSize: function() {
    var $element = this.$element;
    return { width: $element.width(), height: $element.height() };
  }
};

var SKScrollContent = function(scrollView) {
  this.scrollView = scrollView;
  scrollView.$element.wrapInner('
');

  var $element = this.$element = scrollView.$element.children('.sk-scroll-content');
  var element = this.element = $element.get(0);
};

SKScrollContent.prototype = {
  element: null,
  $element: null,
  scrollView: null,
  getSize: function() {
    var $element = this.$element;
    return { width: $element.width(), height: $element.height() };
  },
  translate: function(x, y, duration) {
    var translate3d = 'translate3d(' + x + 'px, ' + y + 'px, 0)';
    var translate = 'translate(' + x + 'px, ' + y + 'px)';

    duration = (duration) ? duration + 's' : '0s';

    this.$element.css({
      '-webkit-transition-duration': duration,
      '-moz-transition-duration': duration,
      '-ms-transition-duration': duration,
      '-o-transition-duration': duration,
      'transition-duration': duration,
      '-webkit-transform': translate3d,
      '-moz-transform': translate,
      '-ms-transform': translate,
      '-o-transform': translate,
      'transform': translate
    });

    var scrollView = this.scrollView;

    if (scrollView.canScrollHorizontal()) scrollView.horizontalScrollBar.update();
    if (scrollView.canScrollVertical()) scrollView.verticalScrollBar.update();
  }
};

var SKScrollBar = function(scrollView, type) {
  this.scrollView = scrollView;
  this.type = type;

  var $element = this.$element = $('
');
  var element = this.element = $element.get(0);

  scrollView.$element.append($element);

  if (this.type === SKScrollBarType.Horizontal) {
    this.thickness = parseInt($element.css('height'), 10);
    $element.css({ 'bottom': '0', 'left': '0' });
  } else {
    this.thickness = parseInt($element.css('width'), 10);
    $element.css({ 'top': '0', 'right': '0' });
  }
};

SKScrollBar.prototype = {
  _size: 0,
  _scrollViewSize: null,
  _contentSize: null,
  element: null,
  $element: null,
  scrollView: null,
  type: SKScrollBarType.Horizontal,
  minimumSize: 34,
  thickness: 5,
  setSize: function(value) {
    this._size = value;
    this.$element.css((this.type === SKScrollBarType.Horizontal) ? 'width' : 'height', value + 'px');
  },
  update: function(recalculateSize) {
    var scrollView = this.scrollView;
    var minimumSize = this.minimumSize;
    var thickness = this.thickness;
    var type = this.type;
    var content = scrollView.content;
    var scrollViewSize, contentSize

    if (recalculateSize) {
      scrollViewSize = this._scrollViewSize = scrollView.getSize();
      contentSize = this._contentSize = content.getSize();
    } else {
      scrollViewSize = this._scrollViewSize;
      contentSize = this._contentSize;
    }

    var canScrollHorizontal = scrollView.canScrollHorizontal();
    var canScrollVertical = scrollView.canScrollVertical();
    var margin, size, scrollPosition, minimumPosition, position, translate3d, translate;

    if (type === SKScrollBarType.Horizontal) {
      margin = (canScrollVertical ? thickness * 2 : thickness) + 1;
      scrollPosition = scrollView.x;
      size = (!recalculateSize && minimumPosition < scrollPosition && scrollPosition < 0) ?
        this._size : Math.max(minimumSize, Math.round(
          (scrollViewSize.width / contentSize.width) * (scrollViewSize.width - margin)
        ));

      minimumPosition = scrollView.minimumX;
      position = (scrollPosition / minimumPosition) * (scrollViewSize.width - margin - size);

      if (scrollPosition > 0) {
        size = Math.round(Math.max(size - scrollPosition, thickness));
        position = 1;
      } else if (scrollPosition < minimumPosition) {
        size = Math.round(Math.max(size - minimumPosition + scrollPosition, thickness));
        position = scrollViewSize.width - size - margin;
      }

      translate3d = 'translate3d(' + position + 'px, 0, 0)';
      translate = 'translate(' + position + 'px, 0)';
    } else {
      margin = (canScrollHorizontal ? thickness * 2 : thickness) + 1;
      scrollPosition = scrollView.y;
      size = (!recalculateSize && minimumPosition < scrollPosition && scrollPosition < 0) ?
        this._size : Math.max(minimumSize, Math.round(
          (scrollViewSize.height / contentSize.height) * (scrollViewSize.height - margin)
        ));

      minimumPosition = scrollView.minimumY;
      position = (scrollPosition / minimumPosition) * (scrollViewSize.height - margin - size);

      if (scrollPosition > 0) {
        size = Math.round(Math.max(size - scrollPosition, thickness));
        position = 1;
      } else if (scrollPosition < minimumPosition) {
        size = Math.round(Math.max(size - minimumPosition + scrollPosition, thickness));
        position = scrollViewSize.height - size - margin;
      }

      translate3d = 'translate3d(0, ' + position + 'px, 0)';
      translate = 'translate(0, ' + position + 'px)';
    }

    if (this._size !== size) this.setSize(size);

    this.$element.css({
      '-webkit-transform': translate3d,
      '-moz-transform': translate,
      '-ms-transform': translate,
      '-o-transform': translate,
      'transform': translate
    });
  },
  show: function() {
    this.$element.addClass('active');
  },
  hide: function() {
    this.$element.removeClass('active');
  }
};

$(function() {
  $('.sk-scroll-view').each(function(index, element) { new SKScrollView(element); });
});
<commit_msg>Added support for multi-touch scrolling multiple scroll views independently at the same time.<commit_after>'use strict';

// Polyfill for requestAnimationFrame() / cancelAnimationFrame()
(function() {
  var lastTime = 0;
  var vendors = ['webkit', 'moz', 'ms', 'o'];

  for (var i = 0; i < vendors.length && !window.requestAnimationFrame; i++) {
    window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] ||
      window[vendors[i] + 'RequestCancelAnimationFrame'];
  }

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      var currTime = Date.now();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() {
        callback(currTime + timeToCall);
      }, timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  }

  if (!window.cancelAnimationFrame) {
    window.cancelAnimationFrame = function(id) {
      window.clearTimeout(id);
    };
  }
})();

var SKScrollEventType = {
  ScrollStart: 'SKScrollStart',
  ScrollEnd: 'SKScrollEnd'
};

var SKScrollBarType = {
  Horizontal: 0,
  Vertical: 1
};

var SKScrollView = function(element) {
  var kBounceTransitionDuration = 0.35;
  var kAccelerationTimeout = 250;
  var kAcceleration = 15;
  var kElasticDeceleration = 0.03;
  var kElasticAcceleration = 0.08;
  var kMinimumDecelerationVelocity = 1;
  var kDecelerationFactor = 0.95;
  var kMinimumVelocity = 0.01;
  var kScrollBarHideTimeout = 100;

  var _isDragging = false;
  var _isDecelerating = false;
  var _isScrolling = false;
  var _startAccelerateX = 0;
  var _startAccelerateY = 0;
  var _lastMouseX = -1;
  var _lastMouseY = -1;
  var _lastTouchIdentifier = 0;
  var _lastTimeStamp = Date.now();
  var _decelerationAnimationInterval = null;

  var $window = $(window['addEventListener'] ? window : document.body);
  var $element = this.$element = $(element);
  element = this.element = $(element).get(0);

  var content = this.content = new SKScrollContent(this);
  var horizontalScrollBar = this.horizontalScrollBar = new SKScrollBar(this, SKScrollBarType.Horizontal);
  var verticalScrollBar = this.verticalScrollBar = new SKScrollBar(this, SKScrollBarType.Vertical);
  var self = this;

  var startDeceleration = function(startTime) {
    var acceleration = (startTime - _lastTimeStamp) / kAcceleration;
    var accelerateDeltaX = self.x - _startAccelerateX;
    var accelerateDeltaY = self.y - _startAccelerateY;
    var velocityX = accelerateDeltaX / acceleration;
    var velocityY = accelerateDeltaY / acceleration;
    var minimumX = self.minimumX;
    var minimumY = self.minimumY;
    var elasticDeceleration = kElasticDeceleration;
    var elasticAcceleration = kElasticAcceleration;
    var lastFrameTime = 0;

    var stepAnimation = function (currentFrameTime) {
      if (!_isDecelerating) return;

      var deltaTime = currentFrameTime - lastFrameTime;
      var x = self.x = self.x + (!self.canScrollHorizontal() ? 0 : velocityX);
      var y = self.y = self.y + (!self.canScrollVertical() ? 0 : velocityY);

      velocityX *= kDecelerationFactor;
      velocityY *= kDecelerationFactor;

      if (Math.abs(velocityX) <= kMinimumVelocity &&
          Math.abs(velocityY) <= kMinimumVelocity) {
        _isDecelerating = false;
        scrollEnd();
        return;
      }

      content.translate(x, y);
      _decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);

      var elasticX = (x < minimumX) ? minimumX - x : (x > 0) ? -x : 0;
      var elasticY = (y < minimumY) ? minimumY - y : (y > 0) ? -y : 0;

      if (elasticX) velocityX = (elasticX * velocityX <= 0) ?
        velocityX + (elasticX * elasticDeceleration) : elasticX * elasticAcceleration;

      if (elasticY) velocityY = (elasticY * velocityY <= 0) ?
        velocityY + (elasticY * elasticDeceleration) : elasticY * elasticAcceleration;

      lastFrameTime = currentFrameTime;
    };

    if (Math.abs(velocityX) > kMinimumDecelerationVelocity ||
        Math.abs(velocityY) > kMinimumDecelerationVelocity) {
      _isDecelerating = true;
      _decelerationAnimationInterval = window.requestAnimationFrame(stepAnimation);
      lastFrameTime = Date.now();
    } else {
      scrollEnd();
    }
  };

  var stopDeceleration = function() {
    _isDecelerating = false;
    window.cancelAnimationFrame(_decelerationAnimationInterval);
  };

  var scrollStart = function() {
    if (_isScrolling) return;

    _isScrolling = true;

    if (self.canScrollHorizontal()) horizontalScrollBar.show();
    if (self.canScrollVertical()) verticalScrollBar.show();

    $element.trigger(SKScrollEventType.ScrollStart);
  };

  var scrollEnd = function() {
    if (!_isScrolling) return;

    _isScrolling = false;

    content.translate(self.x = Math.round(self.x), self.y = Math.round(self.y));

    if (self.canScrollHorizontal()) horizontalScrollBar.hide();
    if (self.canScrollVertical()) verticalScrollBar.hide();

    $element.trigger(SKScrollEventType.ScrollEnd);
  };

  var bounceTransitionEndHandler = function(evt) {
    $element.unbind(evt);
    scrollEnd();
  };

  $element.bind('mousedown touchstart', function(evt) {
    var scrollViewSize = self.getSize();
    var contentSize = content.getSize();

    self.minimumX = scrollViewSize.width - contentSize.width;
    self.minimumY = scrollViewSize.height - contentSize.height;

    _isDragging = true;
    _startAccelerateX = self.x;
    _startAccelerateY = self.y;
    _lastTimeStamp = evt.timeStamp;

    if (evt.type === 'touchstart') {
      _lastMouseX = evt.originalEvent.targetTouches[0].pageX;
      _lastMouseY = evt.originalEvent.targetTouches[0].pageY;
      _lastTouchIdentifier = evt.originalEvent.targetTouches[0].identifier;
    } else {
      _lastMouseX = evt.pageX;
      _lastMouseY = evt.pageY;
    }

    stopDeceleration();

    if (self.canScrollHorizontal()) horizontalScrollBar.update(true);
    if (self.canScrollVertical()) verticalScrollBar.update(true);

    if (evt.type === 'mousedown') evt.preventDefault();
  });

  $window.bind('mousemove touchmove', function(evt) {
    if (!_isDragging) return;

    var mouseX, mouseY;

    if (evt.type === 'touchmove') {
      var touches = evt.originalEvent.touches;
      var touch = touches[0];

      for (var i = 0, length = touches.length; i < length; i++) {
        if (touches[i].identifier === _lastTouchIdentifier) {
          touch = touches[i];
          break;
        }
      }

      mouseX = touch.pageX;
      mouseY = touch.pageY;
    } else {
      mouseX = evt.pageX;
      mouseY = evt.pageY;
    }

    var deltaX = mouseX - _lastMouseX;
    var deltaY = mouseY - _lastMouseY;
    var x = self.x + deltaX;
    var y = self.y + deltaY;

    x -= ((x < self.minimumX) ? deltaX : (x > 0) ? deltaX : 0) / 2;
    y -= ((y < self.minimumY) ? deltaY : (y > 0) ? deltaY : 0) / 2;
    x = self.x = !self.canScrollHorizontal() ? 0 : x;
    y = self.y = !self.canScrollVertical() ? 0 : y;

    content.translate(x, y);

    var accelerationTime = evt.timeStamp - _lastTimeStamp;

    if (accelerationTime > kAccelerationTimeout) {
      _startAccelerateX = x;
      _startAccelerateY = y;
      _lastTimeStamp = evt.timeStamp;
    }

    if (self.canScrollHorizontal()) horizontalScrollBar.update();
    if (self.canScrollVertical()) verticalScrollBar.update();
    if (!_isScrolling) scrollStart();

    _lastMouseX = mouseX;
    _lastMouseY = mouseY;

    evt.preventDefault();
  });

  $window.bind('mouseup touchend', function(evt) {
    if (!_isDragging) return;

    var timeStamp = evt.timeStamp;
    var accelerationTime = timeStamp - _lastTimeStamp;
    var x = Math.min(Math.max(self.minimumX, self.x), 0);
    var y = Math.min(Math.max(self.minimumY, self.y), 0);

    var bounce = function() {
      $element.bind('webkitTransitionEnd transitionend MSTransitionEnd oTransitionEnd transitionEnd', bounceTransitionEndHandler);
      content.translate(x, y, kBounceTransitionDuration);

      if (self.canScrollHorizontal()) horizontalScrollBar.hide();
      if (self.canScrollVertical()) verticalScrollBar.hide();

      self.x = _startAccelerateX = !self.canScrollHorizontal() ? 0 : x;
      self.y = _startAccelerateY = !self.canScrollVertical() ? 0 : y;
    };

    if (accelerationTime < kAccelerationTimeout) {
      if (x !== self.x || y !== self.y) {
        bounce();
      } else {
        startDeceleration(timeStamp);
      }
    } else if (x !== self.x || y !== self.y) {
      bounce();
    } else {
      scrollEnd();
    }

    _isDragging = false;
    _lastMouseX = -1;
    _lastMouseY = -1;
    _lastTimeStamp = timeStamp;

    evt.preventDefault();
  });

  $element.data('scrollView', this);
};

SKScrollView.prototype = {
  minimumX: 0,
  minimumY: 0,
  element: null,
  $element: null,
  content: null,
  horizontalScrollBar: null,
  verticalScrollBar: null,
  x: 0,
  y: 0,
  canScrollHorizontal: function() { return (this.minimumX < 0); },
  canScrollVertical: function() { return (this.minimumY < 0); },
  getSize: function() {
    var $element = this.$element;
    return { width: $element.width(), height: $element.height() };
  }
};

var SKScrollContent = function(scrollView) {
  this.scrollView = scrollView;
  scrollView.$element.wrapInner('
');

  var $element = this.$element = scrollView.$element.children('.sk-scroll-content');
  var element = this.element = $element.get(0);
};

SKScrollContent.prototype = {
  element: null,
  $element: null,
  scrollView: null,
  getSize: function() {
    var $element = this.$element;
    return { width: $element.width(), height: $element.height() };
  },
  translate: function(x, y, duration) {
    var translate3d = 'translate3d(' + x + 'px, ' + y + 'px, 0)';
    var translate = 'translate(' + x + 'px, ' + y + 'px)';

    duration = (duration) ? duration + 's' : '0s';

    this.$element.css({
      '-webkit-transition-duration': duration,
      '-moz-transition-duration': duration,
      '-ms-transition-duration': duration,
      '-o-transition-duration': duration,
      'transition-duration': duration,
      '-webkit-transform': translate3d,
      '-moz-transform': translate,
      '-ms-transform': translate,
      '-o-transform': translate,
      'transform': translate
    });

    var scrollView = this.scrollView;

    if (scrollView.canScrollHorizontal()) scrollView.horizontalScrollBar.update();
    if (scrollView.canScrollVertical()) scrollView.verticalScrollBar.update();
  }
};

var SKScrollBar = function(scrollView, type) {
  this.scrollView = scrollView;
  this.type = type;

  var $element = this.$element = $('
');
  var element = this.element = $element.get(0);

  scrollView.$element.append($element);

  if (this.type === SKScrollBarType.Horizontal) {
    this.thickness = parseInt($element.css('height'), 10);
    $element.css({ 'bottom': '0', 'left': '0' });
  } else {
    this.thickness = parseInt($element.css('width'), 10);
    $element.css({ 'top': '0', 'right': '0' });
  }
};

SKScrollBar.prototype = {
  _size: 0,
  _scrollViewSize: null,
  _contentSize: null,
  element: null,
  $element: null,
  scrollView: null,
  type: SKScrollBarType.Horizontal,
  minimumSize: 34,
  thickness: 5,
  setSize: function(value) {
    this._size = value;
    this.$element.css((this.type === SKScrollBarType.Horizontal) ? 'width' : 'height', value + 'px');
  },
  update: function(recalculateSize) {
    var scrollView = this.scrollView;
    var minimumSize = this.minimumSize;
    var thickness = this.thickness;
    var type = this.type;
    var content = scrollView.content;
    var scrollViewSize, contentSize

    if (recalculateSize) {
      scrollViewSize = this._scrollViewSize = scrollView.getSize();
      contentSize = this._contentSize = content.getSize();
    } else {
      scrollViewSize = this._scrollViewSize;
      contentSize = this._contentSize;
    }

    var canScrollHorizontal = scrollView.canScrollHorizontal();
    var canScrollVertical = scrollView.canScrollVertical();
    var margin, size, scrollPosition, minimumPosition, position, translate3d, translate;

    if (type === SKScrollBarType.Horizontal) {
      margin = (canScrollVertical ? thickness * 2 : thickness) + 1;
      scrollPosition = scrollView.x;
      size = (!recalculateSize && minimumPosition < scrollPosition && scrollPosition < 0) ?
        this._size : Math.max(minimumSize, Math.round(
          (scrollViewSize.width / contentSize.width) * (scrollViewSize.width - margin)
        ));

      minimumPosition = scrollView.minimumX;
      position = (scrollPosition / minimumPosition) * (scrollViewSize.width - margin - size);

      if (scrollPosition > 0) {
        size = Math.round(Math.max(size - scrollPosition, thickness));
        position = 1;
      } else if (scrollPosition < minimumPosition) {
        size = Math.round(Math.max(size - minimumPosition + scrollPosition, thickness));
        position = scrollViewSize.width - size - margin;
      }

      translate3d = 'translate3d(' + position + 'px, 0, 0)';
      translate = 'translate(' + position + 'px, 0)';
    } else {
      margin = (canScrollHorizontal ? thickness * 2 : thickness) + 1;
      scrollPosition = scrollView.y;
      size = (!recalculateSize && minimumPosition < scrollPosition && scrollPosition < 0) ?
        this._size : Math.max(minimumSize, Math.round(
          (scrollViewSize.height / contentSize.height) * (scrollViewSize.height - margin)
        ));

      minimumPosition = scrollView.minimumY;
      position = (scrollPosition / minimumPosition) * (scrollViewSize.height - margin - size);

      if (scrollPosition > 0) {
        size = Math.round(Math.max(size - scrollPosition, thickness));
        position = 1;
      } else if (scrollPosition < minimumPosition) {
        size = Math.round(Math.max(size - minimumPosition + scrollPosition, thickness));
        position = scrollViewSize.height - size - margin;
      }

      translate3d = 'translate3d(0, ' + position + 'px, 0)';
      translate = 'translate(0, ' + position + 'px)';
    }

    if (this._size !== size) this.setSize(size);

    this.$element.css({
      '-webkit-transform': translate3d,
      '-moz-transform': translate,
      '-ms-transform': translate,
      '-o-transform': translate,
      'transform': translate
    });
  },
  show: function() {
    this.$element.addClass('active');
  },
  hide: function() {
    this.$element.removeClass('active');
  }
};

$(function() {
  $('.sk-scroll-view').each(function(index, element) { new SKScrollView(element); });
});
<|endoftext|>


<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets, window */

/** Adds "Delete to line start" and "Delete to line end" menu items */
define(function (require, exports, module) {
    "use strict";

    var CommandManager  = brackets.getModule("command/CommandManager"),
    EditorManager   = brackets.getModule("editor/EditorManager"),
    DocumentManager = brackets.getModule("document/DocumentManager"),
    Menus           = brackets.getModule("command/Menus"),
    DELETE_TO_START_COMMAND_ID      = "probertson.deleteToLineStart",
    DELETE_TO_END_COMMAND_ID      = "probertson.deleteToLineEnd";

    CommandManager.register("Delete To Line Start",
                            DELETE_TO_START_COMMAND_ID,
                            deleteToLineStart);
    CommandManager.register("Delete To Line End",
                            DELETE_TO_END_COMMAND_ID,
                            deleteToLineEnd);

    function deleteToLineStart() {
        var cm = EditorManager.getFocusedEditor()._codeMirror;
        var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
        if (sel) {
            cm.replaceRange("", from, to, "+delete");
        }
        else if (from.ch == 0) {
            cm.replaceRange("", from, Pos(from.line - 1, cm.getLine(from.line - 1).length), "+delete");
        }
        else {
            // "start smart" position algorithm adapted from CodeMirror's goLineStartSmart() function
            var start = Pos(from.line, 0);//lineStart(cm, from.line);
            var line = cm.getLineHandle(start.line);
            var firstNonWS = Math.max(0, line.text.search(/\S/));
            var inWS = from.line == start.line && from.ch <= firstNonWS && from.ch;
            cm.replaceRange("", from, Pos(from.line, inWS ? 0 : firstNonWS), "+delete");
       }
    }

    function deleteToLineEnd() {
        var cm = EditorManager.getFocusedEditor()._codeMirror;
        CodeMirror.commands.killLine(cm);
    }

    function posEq(a, b) {
        return a.line == b.line && a.ch == b.ch;
    }

    function Pos(line, ch) {
        return new CodeMirror.Pos(line, ch);
    }

    var menu = Menus.getMenu(Menus.AppMenuBar.EDIT_MENU);
    menu.addMenuItem(DELETE_TO_START_COMMAND_ID,
                     [{key: "Alt-Backspace", platform: "win"},
                      {key: "Cmd-Backspace", platform: "mac"}]);
    menu.addMenuItem(DELETE_TO_END_COMMAND_ID,
                     [{key: "Alt-Delete", platform: "win"},
                      {key: "Cmd-Delete", platform: "mac"}]);

});
<commit_msg>Change command Id to use recommended format<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets, window */

/** Adds "Delete to line start" and "Delete to line end" menu items */
define(function (require, exports, module) {
    "use strict";

    var CommandManager  = brackets.getModule("command/CommandManager"),
    EditorManager   = brackets.getModule("editor/EditorManager"),
    DocumentManager = brackets.getModule("document/DocumentManager"),
    Menus           = brackets.getModule("command/Menus"),
    DELETE_TO_START_COMMAND_ID      = "probertson.delete_to_line_start_end.deleteToLineStart",
    DELETE_TO_END_COMMAND_ID      = "probertson.delete_to_line_start_end.deleteToLineEnd";

    CommandManager.register("Delete To Line Start",
                            DELETE_TO_START_COMMAND_ID,
                            deleteToLineStart);
    CommandManager.register("Delete To Line End",
                            DELETE_TO_END_COMMAND_ID,
                            deleteToLineEnd);

    function deleteToLineStart() {
        var cm = EditorManager.getFocusedEditor()._codeMirror;
        var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
        if (sel) {
            cm.replaceRange("", from, to, "+delete");
        }
        else if (from.ch == 0) {
            cm.replaceRange("", from, Pos(from.line - 1, cm.getLine(from.line - 1).length), "+delete");
        }
        else {
            // "start smart" position algorithm adapted from CodeMirror's goLineStartSmart() function
            var start = Pos(from.line, 0);//lineStart(cm, from.line);
            var line = cm.getLineHandle(start.line);
            var firstNonWS = Math.max(0, line.text.search(/\S/));
            var inWS = from.line == start.line && from.ch <= firstNonWS && from.ch;
            cm.replaceRange("", from, Pos(from.line, inWS ? 0 : firstNonWS), "+delete");
       }
    }

    function deleteToLineEnd() {
        var cm = EditorManager.getFocusedEditor()._codeMirror;
        CodeMirror.commands.killLine(cm);
    }

    function posEq(a, b) {
        return a.line == b.line && a.ch == b.ch;
    }

    function Pos(line, ch) {
        return new CodeMirror.Pos(line, ch);
    }

    var menu = Menus.getMenu(Menus.AppMenuBar.EDIT_MENU);
    menu.addMenuItem(DELETE_TO_START_COMMAND_ID,
                     [{key: "Alt-Backspace", platform: "win"},
                      {key: "Cmd-Backspace", platform: "mac"}]);
    menu.addMenuItem(DELETE_TO_END_COMMAND_ID,
                     [{key: "Alt-Delete", platform: "win"},
                      {key: "Cmd-Delete", platform: "mac"}]);

});
<|endoftext|>