<commit_before>beforeEach(() => {
    const TEXT_TOLERANCE = 25;
    const ERROR_LIMIT = 20;

    const match = (expected, actual) => {
        if (typeof expected === 'number') {
            return expected === actual;
        } else if (expected instanceof Array) {
            return expected[0] <= actual && actual <= expected[1];
        } else {
            return true;
        }
    };

    /**
     * @return
     *   - (space) match
     *
     * r - red mismatch
     * g - green mismatch
     * b - blue mismatch
     * a - alpha mismatch
     *
     * c - at least two of r, g, or b
     * x - at least one of r, g, or b and a
     */
    const matchPixel = (expected, r, g, b, a) => {
        let errors = match(expected.a, a) ? '' : 'a';
        errors += match(expected.r, r) ? '' : 'r';
        errors += match(expected.g, g) ? '' : 'g';
        errors += match(expected.g, g) ? '' : 'b';
        if (errors === '') {
            return ' ';
        } else if (errors.length === 1) {
            return errors;
        } else {
            return errors.includes('a') ? 'x' : 'c';
        }
    };

    const tolerate = (value, tolerance) => {
        if (typeof value === 'number') {
            return [ value - tolerance, value + tolerance ];
        } else if (value instanceof Array) {
            return [ value[0] - tolerance, value[1] + tolerance ];
        }
    };

    const tolerateColor = (color, tolerance) => {
        return Object.keys(color).reduce((toleratedColor, channel) => {
            toleratedColor[channel] = tolerate(color[channel], tolerance);
            return toleratedColor;
        }, {});
    };

    const segment = (data, width, height, bodyColor) => {
        const segments = new Array(height).fill(0).map(() => new Array(width));
        const regions = [];
        let index = 0;
        for (let x = 0; x < width; x++) {
            for (let y = 0; y < height; y++) {
                const pixelIndex = width * y * 4 + x * 4;
                const current = matchPixel(bodyColor,
                    data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                if (current === ' ') {
                    segments[y][x] = 0;
                } else {
                    const neighbours = [];
                    if (0 < y) {
                        if (segments[y - 1][x]) { // check top
                            neighbours.push(segments[y - 1][x]);
                        }
                    }
                    if (0 < x) {
                        if (segments[y][x - 1]) { // check left
                            neighbours.push(segments[y][x - 1]);
                        }
                    }

                    if (neighbours.length) {
                        neighbours.sort();
                        segments[y][x] = neighbours[0];
                        if (1 < neighbours.length) {
                            neighbours.forEach(neighbour => { // connect regions
                                if (neighbour !== neighbours[0]) {
                                    const foundReference = regions.find(region => region.includes(neighbours[0]));
                                    const foundCurrent = regions.find(region => region.includes(neighbour));
                                    if (foundCurrent === foundReference) {
                                        // Nothing to do
                                    } else if (foundReference && foundCurrent) {
                                        regions.push(foundReference.concat(foundCurrent));
                                        foundReference.length = 0;
                                        foundCurrent.length = 0;
                                    } else {
                                        foundReference.push(neighbour);
                                    }
                                }
                            });
                        }
                    } else {
                        index++;
                        segments[y][x] = index;
                        regions.push([index]);
                    }
                }
            }
        }

        return regions.filter(region => region.length).length;
    };

    jasmine.addMatchers({
        toResembleColor: () => ({
            compare: (actual, expected) => {
                const { data, width, height } = actual;
                const area = width * height;

                let count = 0;
                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        const currentPassing = ' ' === matchPixel(expected,
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        if (currentPassing) {
                            count++;
                        }
                    }
                }

                const passing = area / 2 < count;

                return {
                    pass: passing,
                    message: `Matched ${count} out of ${area}`
                };
            }
        }),
        toResembleText: () => ({
            compare: (actual, expected, textColor, bodyColor) => {
                const { data, width, height } = actual;

                const segments = segment(data, width, height, bodyColor);

                const words = expected.replace(/\s/g, '').length;

                let passing = segments === words;

                const toleratedColor = tolerateColor(textColor, TEXT_TOLERANCE);

                const colors = {
                    body: 0,
                    text: 0,
                    misc: 0
                };
                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        if (' ' === matchPixel(bodyColor,
                                data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3])) {
                            colors.body++;
                        } else if (' ' === matchPixel(toleratedColor,
                                data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3])) {
                            colors.text++;
                        } else {
                            colors.misc++
                        }
                    }
                }

                passing = passing && colors.misc <= colors.text && colors.text <= colors.body;

                return {
                    pass: passing,
                    message: `Expected: ${words} characters (${expected}), Actual: ${segments} characters. Colors: ${colors.misc}, ${colors.text}, ${colors.body}`
                }
            }
        }),
        toResembleShape: () => ({
            compare: (actual, expected, rotateCW) => {
                const { data, width, height } = actual;
                let passing = true;
                let matrix = `|${'-'.repeat(width)}|\n|`;

                for (let y = 0; y < height; y++) {
                    for (let x = 0; x < width; x++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        let mappedX;
                        let mappedY;
                        switch (rotateCW) {
                            case 90:
                                mappedX = y;
                                mappedY = width - x - 1;
                                break;
                            case 180:
                                mappedX = width - x - 1;
                                mappedY = height - y - 1;
                                break;
                            case 270:
                                mappedX = height - y - 1;
                                mappedY = x;
                                break;
                            default:
                                mappedX = x;
                                mappedY = y;
                                break;
                        }

                        const current = matchPixel(expected[mappedY][mappedX],
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        matrix += current;
                        passing = passing && current === ' ';
                    }
                    matrix += '|\n|';
                }
                matrix += `${'-'.repeat(width)}|`;

                return {
                    pass: passing,
                    message: `Problems at ${rotateCW}deg:\n${matrix}`
                };
            }
        }),
        toResembleOblongShape: () => ({
            compare: (actual, expected, rotateCW) => {
                const { data, width, height } = actual;
                let passing = true;
                let errors = '';
                let errorCount = 0;

                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        let mapped;
                        if (rotateCW === 90 || rotateCW === 270) {
                            mapped = rotateCW === 90 ? width - x - 1 : x;
                        } else {
                            mapped = rotateCW === 180 ? height - y - 1 : y;
                        }

                        const current = matchPixel(expected[mapped],
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        passing = passing && (current === ' ');

                        if (current !== ' ') {
                            if (errorCount < ERROR_LIMIT) {
                                errors += `(${x}, ${y}): ${data[pixelIndex]}, ${data[pixelIndex + 1]}, ${data[pixelIndex + 2]}, ${data[pixelIndex + 3]})}\n`;
                            }
                            errorCount++;
                        }
                    }
                }

                return {
                    pass: passing,
                    message: `Problems at ${rotateCW}deg (first ${ERROR_LIMIT}):\n${errors}\n${errorCount - ERROR_LIMIT} more errors.`
                };
            }
        })
    });
});
<commit_msg>Add toResembleCircularShape, Fix pixel-matching bug, Improve error reporting<commit_after>beforeEach(() => {
    const TEXT_TOLERANCE = 25;
    const ERROR_LIMIT = 20;

    const match = (expected, actual) => {
        if (typeof expected === 'number') {
            return expected === actual;
        } else if (expected instanceof Array) {
            return expected[0] <= actual && actual <= expected[1];
        } else {
            return true;
        }
    };

    /**
     * @return
     *   - (space) match
     *
     * r - red mismatch
     * g - green mismatch
     * b - blue mismatch
     * a - alpha mismatch
     *
     * c - at least two of r, g, or b
     * x - at least one of r, g, or b and a
     */
    const matchPixel = (expected, r, g, b, a) => {
        let errors = match(expected.a, a) ? '' : 'a';
        errors += match(expected.r, r) ? '' : 'r';
        errors += match(expected.g, g) ? '' : 'g';
        errors += match(expected.b, b) ? '' : 'b';
        if (errors === '') {
            return ' ';
        } else if (errors.length === 1) {
            return errors;
        } else {
            return errors.includes('a') ? 'x' : 'c';
        }
    };

    const tolerate = (value, tolerance) => {
        if (typeof value === 'number') {
            return [ value - tolerance, value + tolerance ];
        } else if (value instanceof Array) {
            return [ value[0] - tolerance, value[1] + tolerance ];
        }
    };

    const tolerateColor = (color, tolerance) => {
        return Object.keys(color).reduce((toleratedColor, channel) => {
            toleratedColor[channel] = tolerate(color[channel], tolerance);
            return toleratedColor;
        }, {});
    };

    const segment = (data, width, height, bodyColor) => {
        const segments = new Array(height).fill(0).map(() => new Array(width));
        const regions = [];
        let index = 0;
        for (let x = 0; x < width; x++) {
            for (let y = 0; y < height; y++) {
                const pixelIndex = width * y * 4 + x * 4;
                const current = matchPixel(bodyColor,
                    data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                if (current === ' ') {
                    segments[y][x] = 0;
                } else {
                    const neighbours = [];
                    if (0 < y) {
                        if (segments[y - 1][x]) { // check top
                            neighbours.push(segments[y - 1][x]);
                        }
                    }
                    if (0 < x) {
                        if (segments[y][x - 1]) { // check left
                            neighbours.push(segments[y][x - 1]);
                        }
                    }

                    if (neighbours.length) {
                        neighbours.sort();
                        segments[y][x] = neighbours[0];
                        if (1 < neighbours.length) {
                            neighbours.forEach(neighbour => { // connect regions
                                if (neighbour !== neighbours[0]) {
                                    const foundReference = regions.find(region => region.includes(neighbours[0]));
                                    const foundCurrent = regions.find(region => region.includes(neighbour));
                                    if (foundCurrent === foundReference) {
                                        // Nothing to do
                                    } else if (foundReference && foundCurrent) {
                                        regions.push(foundReference.concat(foundCurrent));
                                        foundReference.length = 0;
                                        foundCurrent.length = 0;
                                    } else {
                                        foundReference.push(neighbour);
                                    }
                                }
                            });
                        }
                    } else {
                        index++;
                        segments[y][x] = index;
                        regions.push([index]);
                    }
                }
            }
        }

        return regions.filter(region => region.length).length;
    };

    jasmine.addMatchers({
        toResembleColor: () => ({
            compare: (actual, expected) => {
                const { data, width, height } = actual;
                const area = width * height;

                let count = 0;
                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        const currentPassing = ' ' === matchPixel(expected,
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        if (currentPassing) {
                            count++;
                        }
                    }
                }

                const passing = area / 2 < count;

                return {
                    pass: passing,
                    message: `Matched ${count} out of ${area}`
                };
            }
        }),
        toResembleText: () => ({
            compare: (actual, expected, textColor, bodyColor) => {
                const { data, width, height } = actual;

                const segments = segment(data, width, height, bodyColor);

                const words = expected.replace(/\s/g, '').length;

                let passing = segments === words;

                const toleratedColor = tolerateColor(textColor, TEXT_TOLERANCE);

                const colors = {
                    body: 0,
                    text: 0,
                    misc: 0
                };
                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        if (' ' === matchPixel(bodyColor,
                                data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3])) {
                            colors.body++;
                        } else if (' ' === matchPixel(toleratedColor,
                                data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3])) {
                            colors.text++;
                        } else {
                            colors.misc++
                        }
                    }
                }

                passing = passing && colors.misc <= colors.text && colors.text <= colors.body;

                return {
                    pass: passing,
                    message: `Expected: ${words} characters (${expected}), Actual: ${segments} characters. Colors: ${colors.misc}, ${colors.text}, ${colors.body}`
                }
            }
        }),
        toResembleShape: () => ({
            compare: (actual, expected, rotateCW) => {
                const { data, width, height } = actual;
                let passing = true;
                let matrix = `|${'-'.repeat(width)}|\n|`;
                let errors = '';
                let errorCount = 0;

                for (let y = 0; y < height; y++) {
                    for (let x = 0; x < width; x++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        let mappedX;
                        let mappedY;
                        switch (rotateCW) {
                            case 90:
                                mappedX = y;
                                mappedY = width - x - 1;
                                break;
                            case 180:
                                mappedX = width - x - 1;
                                mappedY = height - y - 1;
                                break;
                            case 270:
                                mappedX = height - y - 1;
                                mappedY = x;
                                break;
                            default:
                                mappedX = x;
                                mappedY = y;
                                break;
                        }

                        const current = matchPixel(expected[mappedY][mappedX],
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        matrix += current;
                        passing = passing && current === ' ';

                        if (current !== ' ') {
                            if (errorCount < ERROR_LIMIT) {
                                errors += `(${mappedX}, ${mappedY}): ${data[pixelIndex]}, ${data[pixelIndex + 1]}, ${data[pixelIndex + 2]}, ${data[pixelIndex + 3]})}\n`;
                            }
                            errorCount++;
                        }
                    }
                    matrix += '|\n|';
                }
                matrix += `${'-'.repeat(width)}|`;

                return {
                    pass: passing,
                    message: `Problems at ${rotateCW}deg:\n${matrix}\n${errors}\n${errorCount - ERROR_LIMIT} more errors.`
                };
            }
        }),
        toResembleOblongShape: () => ({
            compare: (actual, expected, rotateCW) => {
                const { data, width, height } = actual;
                let passing = true;
                let errors = '';
                let errorCount = 0;

                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        let mapped;
                        if (rotateCW === 90 || rotateCW === 270) {
                            mapped = rotateCW === 90 ? width - x - 1 : x;
                        } else {
                            mapped = rotateCW === 180 ? height - y - 1 : y;
                        }

                        const current = matchPixel(expected[mapped],
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        passing = passing && (current === ' ');

                        if (current !== ' ') {
                            if (errorCount < ERROR_LIMIT) {
                                errors += `(${x}, ${y}): ${data[pixelIndex]}, ${data[pixelIndex + 1]}, ${data[pixelIndex + 2]}, ${data[pixelIndex + 3]})}\n`;
                            }
                            errorCount++;
                        }
                    }
                }

                return {
                    pass: passing,
                    message: `Problems at ${rotateCW}deg (first ${ERROR_LIMIT}):\n${errors}\n${errorCount - ERROR_LIMIT} more errors.`
                };
            }
        }),
        toResembleCircularShape: () => ({
            compare: (actual, expected) => {
                const { data, width, height } = actual;
                let passing = true;
                let errors = '';
                let errorCount = 0;

                const center = {
                    x: width / 2,
                    y: height / 2
                };

                for (let x = 0; x < width; x++) {
                    for (let y = 0; y < height; y++) {
                        const pixelIndex = width * y * 4 + x * 4;
                        const dx = center.x - x - 0.5;
                        const dy = center.y - y - 0.5;
                        const mapped = Math.round(Math.sqrt(dx * dx + dy * dy));

                        const current = matchPixel(expected[mapped],
                            data[pixelIndex], data[pixelIndex + 1], data[pixelIndex + 2], data[pixelIndex + 3]);
                        passing = passing && (current === ' ');

                        if (current !== ' ') {
                            if (errorCount < ERROR_LIMIT) {
                                errors += `(${x}, ${y}), mapped ${mapped}: ${data[pixelIndex]}, ${data[pixelIndex + 1]}, ${data[pixelIndex + 2]}, ${data[pixelIndex + 3]})}\n`;
                            }
                            errorCount++;
                        }
                    }
                }

                return {
                    pass: passing,
                    message: `Problems (first ${ERROR_LIMIT}):\n${errors}\n${errorCount - ERROR_LIMIT} more errors.`
                };
            }
        })
    });
});
<|endoftext|>


<commit_before>angular.module('eventsInfo', [])
  .constant('moment', moment)
  .controller('eventsController', function($scope, $state, Eventstored, moment, $interval, $window) {
    $scope.eve = {};
    $scope.eve.eventDate = '';
    $scope.eve.eventDescription = '';
    $scope.eve.eventAlert = '';
    $scope.eve.eventTime = '';
    $scope.eve.roomName = '';
    $scope.eve.houseName = 'Hacker House';

    $scope.ifValue = true;
    $scope.showIf = function() {
      return $scope.ifValue;
    };
    $scope.hideIf = function() {
      return !$scope.ifValue;
    };

    $scope.refreshEvents = function() {
      Eventstored.getData().then(function(events) {

        var allEvents = events.data;
        //console.log(allEvents);
        var today = moment().dayOfYear();

        for (var i = 0; i < allEvents.length; i++) {
          var eachDib = moment(allEvents[i].eventDate).dayOfYear();
          var diff = eachDib - today;
          allEvents[i].diff = diff;
          //console.log('This is the flag', diff);
        }
        var formattedEvents = Eventstored.formatData(events);
        $scope.bookedEvents = formattedEvents;
      });
    };

    $scope.renderSideDashboard = function() {
      $state.go('dashboardPage.events');
      Eventstored.getData().then(function(events) {
        var allEvents = events.data;
        //console.log(allEvents);
        var today = moment().dayOfYear();

        for (var i = 0; i < allEvents.length; i++) {
          var eachDib = moment(allEvents[i].eventDate).dayOfYear();
          var diff = eachDib - today;
          allEvents[i].diff = diff;
          //console.log('This is the flag', diff);
        }
        var formattedEvents = Eventstored.formatData(events);
        $scope.bookedEvents = formattedEvents;
      });

      // removing past daily dibs every 30s
      //$scope.refreshEvents();
    };

    $scope.renderSideDashboardChart = function() {
      $state.go('dashboardPage.eventsChart');
    };

    $scope.highlightEvents = function(event) {
      //console.log('test', event.diff);

      if (event.diff <= 1) {
        //console.log(true);
        return true;
      } else {
        //console.log(false);
        return false;
      }
    };

    $scope.eventSubmit = function() {
      var $events = $scope.eve;
      Eventstored.eventData($events)
        .then(function(message) {
          if (!message.data.result) {
            alert('Someone else called Dibs!');
          }
        });
      // Eventstored.getData();
      $scope.refreshEvents();
      $scope.renderSideDashboard();
    };

    $scope.signout = function() {
      //remove jwt here
      console.log("I'm signing out");
      $window.localStorage.clear();
      $state.go('signupPage');
    };

    //TIME ADDON
    $scope.eve.eventDate = new Date();
    $scope.hstep = 1;
    $scope.mstep = 1;
    $scope.options = {
      hstep: [1, 2, 3],
      mstep: [1, 5, 10, 15, 25, 30]
    };

    $scope.ismeridian = true;
    $scope.toggleMode = function() {
      $scope.ismeridian = !$scope.ismeridian;
    };

    $scope.update = function() {
      var d = $scope.eve.eventDate;
      d.setHours(15);
      d.setMinutes(0);
      // $scope.eve.eventDate = d;
    };

    // used to help render the date
    $scope.dt = +new Date();

    $scope.today = function() {
      $scope.eve.eventDate = new Date();
    };

    $scope.today();

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

    $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.eve.eventDate = new Date(year, month, day);
    };

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

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

    $scope.status = {
      opened: false
    };

    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 '';
    };
  });<commit_msg>[feat] add redirect to signin page if server resource is not available (due to user not being authenticated<commit_after>angular.module('eventsInfo', [])
  .constant('moment', moment)
  .controller('eventsController', function($scope, $state, Eventstored, moment, $interval, $window) {
    $scope.eve = {};
    $scope.eve.eventDate = '';
    $scope.eve.eventDescription = '';
    $scope.eve.eventAlert = '';
    $scope.eve.eventTime = '';
    $scope.eve.roomName = '';
    $scope.eve.houseName = 'Hacker House';

    $scope.ifValue = true;
    $scope.showIf = function() {
      return $scope.ifValue;
    };
    $scope.hideIf = function() {
      return !$scope.ifValue;
    };

    $scope.refreshEvents = function() {
      Eventstored.getData().then(function(events) {

        var allEvents = events.data;
        //console.log(allEvents);
        var today = moment().dayOfYear();

        for (var i = 0; i < allEvents.length; i++) {
          var eachDib = moment(allEvents[i].eventDate).dayOfYear();
          var diff = eachDib - today;
          allEvents[i].diff = diff;
          //console.log('This is the flag', diff);
        }
        var formattedEvents = Eventstored.formatData(events);
        $scope.bookedEvents = formattedEvents;
      });
    };

    $scope.renderSideDashboard = function() {
      $state.go('dashboardPage.events');
      Eventstored.getData().then(function successCallback(events) {
        var allEvents = events.data;
        //console.log(allEvents);
        var today = moment().dayOfYear();

        for (var i = 0; i < allEvents.length; i++) {
          var eachDib = moment(allEvents[i].eventDate).dayOfYear();
          var diff = eachDib - today;
          allEvents[i].diff = diff;
          //console.log('This is the flag', diff);
        }
        var formattedEvents = Eventstored.formatData(events);
        $scope.bookedEvents = formattedEvents;
      },function errorCallback(response) {

        //do not have access to events resource
        //user must not be logged in
        //redirect to signup

        $state.go('signupPage');

        console.log("RESPONSE",response);

      });

      // removing past daily dibs every 30s
      //$scope.refreshEvents();
    };

    $scope.renderSideDashboardChart = function() {
      $state.go('dashboardPage.eventsChart');
    };

    $scope.highlightEvents = function(event) {
      //console.log('test', event.diff);

      if (event.diff <= 1) {
        //console.log(true);
        return true;
      } else {
        //console.log(false);
        return false;
      }
    };

    $scope.eventSubmit = function() {
      var $events = $scope.eve;
      Eventstored.eventData($events)
        .then(function(message) {
          if (!message.data.result) {
            alert('Someone else called Dibs!');
          }
        });
      // Eventstored.getData();
      $scope.refreshEvents();
      $scope.renderSideDashboard();
    };

    $scope.signout = function() {
      //remove jwt here
      console.log("I'm signing out");
      $window.localStorage.clear();
      $state.go('signupPage');
    };

    //TIME ADDON
    $scope.eve.eventDate = new Date();
    $scope.hstep = 1;
    $scope.mstep = 1;
    $scope.options = {
      hstep: [1, 2, 3],
      mstep: [1, 5, 10, 15, 25, 30]
    };

    $scope.ismeridian = true;
    $scope.toggleMode = function() {
      $scope.ismeridian = !$scope.ismeridian;
    };

    $scope.update = function() {
      var d = $scope.eve.eventDate;
      d.setHours(15);
      d.setMinutes(0);
      // $scope.eve.eventDate = d;
    };

    // used to help render the date
    $scope.dt = +new Date();

    $scope.today = function() {
      $scope.eve.eventDate = new Date();
    };

    $scope.today();

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

    $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.eve.eventDate = new Date(year, month, day);
    };

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

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

    $scope.status = {
      opened: false
    };

    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 '';
    };
  });<|endoftext|>


<commit_before>import { getRandomArbitrary } from "utils";
import {
  Wall,
  SpritePlayer,
  SpriteEnemy,
  SpriteEnemy2,
  SpriteEnemy3,
  SpriteBullet,
  BoomerangSprite,
  DeathSound,
  Background,
  LightSprite
} from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight,
  Border,
  CharacterWitdh,
  CharacterHeight,
  BoomerangWidth,
  BoomerangHeight
  } from "Constants";

import Player from "objects/Character";
import Boomerang from "objects/Boomerang";
import Room from "objects/Room";
import BackgroundLayer from "objects/BackgroundLayer";
import EnemyGroup from "objects/EnemyGroup";
import ChandelierLayer from "objects/ChandelierLayer";

const needCamera = false;

const MinDivision = 1;
const MaxDivision = 5;

const Division = getRandomArbitrary(MinDivision, MaxDivision);

const MaxBorder = 60;
const MinBorder = 30;

const SizeMaze = getRandomArbitrary(MinBorder, MaxBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class Game extends Phaser.State {

  create() {
    this.game.stage.backgroundColor = 0x000000;
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.room = new Room(this.game);
    this.room.createRandomSquare(Border,Border,SizeMaze, Division);

    this.hero = new Player(this.game, 100, 100);
    this.game.add.existing(this.hero);
    this.getInitialPosition(this.hero, CharacterWitdh, CharacterHeight);

    //this.bgLayer = new BackgroundLayer(this.game, this.hero.x, this.hero.y, this.room.getRoomBordered());

    this.boomerang = new Boomerang(this.game, 0, 0);
    this.getInitialPosition(this.boomerang, BoomerangWidth, BoomerangHeight);
    this.game.add.existing(this.boomerang);

    this.enemies = new EnemyGroup(this.game);
    this.chandelierLayer = new ChandelierLayer(this.game);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }
    this.camera.follow(this.hero);
    this.launchBoomerangKey = this.game.input.keyboard.addKey(Phaser.Keyboard.B);

    //sounds
    this.deathFx = this.game.add.audio(DeathSound);

  }

  getInitialPosition(sprite, spriteWidth, spriteHeight) {
    let maxAttempt = 0;
    let hasBlock = false;
    do {
      const x = getRandomArbitrary(2 * Border, this.game.world.bounds.width - spriteWidth - 2 * Border);
      const y = getRandomArbitrary(2 * Border, this.game.world.bounds.height - spriteHeight - 2 * Border);
      sprite.position.setTo(x,y);
      maxAttempt = maxAttempt + 1;
      hasBlock = this.game.physics.arcade.collide(sprite, this.room);
    } while(maxAttempt < 10 && hasBlock);
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemies, this.damage, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemies, this.kill, null, this);
    this.game.physics.arcade.overlap(this.enemies, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.enemies);
    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.enemies, this.boomerang, this.killByBoomerang, null, this);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.game.physics.arcade.collide(this.boomerang, this.room, this.killBoomerang, null, this);
    this.game.physics.arcade.overlap(this.hero, this.boomerang, this.launchBoomerang, null, this);
    this.enemies.follow(this.hero.body.position);

    if(this.hero.isDeath()) {
      this.lost();
    }

     if(this.hero.isOutSideTheLevel(this.game) || !this.enemies.hasEnemies()) {
        this.won();
     }
  }

  kill(bullet, enemy) {
    this.enemies.remove(enemy);
    bullet.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  killByBoomerang(boomerang, enemy) {
    if(boomerang.isMoving()) {
      this.enemies.remove(enemy);
    }
  }

  killBoomerang(boomerang) {
    boomerang.kill();
    this.camera.follow(this.hero, Phaser.Camera.FOLLOW_LOCKON, 0.1, 0.1);
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  launchBoomerang() {
    if(this.launchBoomerangKey.isDown) {
      this.camera.follow(this.boomerang);
      // after the tween get back to the player
      const onCompleteCallback = (boomerang, tween) => {
         boomerang.kill();
         tween.stop()
         this.camera.follow(this.hero, Phaser.Camera.FOLLOW_LOCKON, 0.1, 0.1);
      };
      // the first param is the direction
      this.boomerang.launch(this.hero.directionChoosed(), onCompleteCallback);
    }
  }

  lost() {
    this.hero.kill();
    this.deathFx.play();
     setTimeout(() => {
       this.room.clear();
       this.chandelierLayer.clear();
       this.boomerang.kill();
       this.game.goToLose();
     }, 500);
  }

  won() {
    this.game.goToWin();
  }

  preload() {
    this.game.load.image(Wall, "res/block.png");
    this.game.load.spritesheet(SpritePlayer, "res/hero-sprite.png", CharacterWitdh, CharacterHeight);
    this.game.load.spritesheet(SpriteEnemy, "res/zombie.png", EnemyWidth, EnemyHeight);
    this.game.load.spritesheet(SpriteEnemy2, "res/zombie2.png", EnemyWidth, EnemyHeight);
    this.game.load.spritesheet(SpriteEnemy3, "res/zombie1.png", EnemyWidth, EnemyHeight);
    this.game.load.image(SpriteBullet, "res/bullet.png");
    this.game.load.image(BoomerangSprite, "res/ufoRed.png");
    this.game.load.image(Background, "res/boomerang.png");
    this.game.load.image(LightSprite, "res/light.png");
    this.game.load.audio(DeathSound, 'res/painSoundBible.com.mp3');
  }

  render() {
    //this.enemies.render(this.game);
    //this.game.debug.spriteInfo(this.hero, 32, 32);
    //this.game.debug.text(Bounds, 2, 14, "#ff0000");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default Game;
<commit_msg>does not follow boomerang anymore<commit_after>import { getRandomArbitrary } from "utils";
import {
  Wall,
  SpritePlayer,
  SpriteEnemy,
  SpriteEnemy2,
  SpriteEnemy3,
  SpriteBullet,
  BoomerangSprite,
  DeathSound,
  Background,
  LightSprite
} from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight,
  Border,
  CharacterWitdh,
  CharacterHeight,
  BoomerangWidth,
  BoomerangHeight
  } from "Constants";

import Player from "objects/Character";
import Boomerang from "objects/Boomerang";
import Room from "objects/Room";
import BackgroundLayer from "objects/BackgroundLayer";
import EnemyGroup from "objects/EnemyGroup";
import ChandelierLayer from "objects/ChandelierLayer";

const needCamera = false;

const MinDivision = 1;
const MaxDivision = 5;

const Division = getRandomArbitrary(MinDivision, MaxDivision);

const MaxBorder = 60;
const MinBorder = 30;

const SizeMaze = getRandomArbitrary(MinBorder, MaxBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class Game extends Phaser.State {

  create() {
    this.game.stage.backgroundColor = 0x000000;
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.room = new Room(this.game);
    this.room.createRandomSquare(Border,Border,SizeMaze, Division);

    this.hero = new Player(this.game, 100, 100);
    this.game.add.existing(this.hero);
    this.getInitialPosition(this.hero, CharacterWitdh, CharacterHeight);

    //this.bgLayer = new BackgroundLayer(this.game, this.hero.x, this.hero.y, this.room.getRoomBordered());

    this.boomerang = new Boomerang(this.game, 0, 0);
    this.getInitialPosition(this.boomerang, BoomerangWidth, BoomerangHeight);
    this.game.add.existing(this.boomerang);

    this.enemies = new EnemyGroup(this.game);
    this.chandelierLayer = new ChandelierLayer(this.game);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }
    this.camera.follow(this.hero);
    this.launchBoomerangKey = this.game.input.keyboard.addKey(Phaser.Keyboard.B);

    //sounds
    this.deathFx = this.game.add.audio(DeathSound);

  }

  getInitialPosition(sprite, spriteWidth, spriteHeight) {
    let maxAttempt = 0;
    let hasBlock = false;
    do {
      const x = getRandomArbitrary(2 * Border, this.game.world.bounds.width - spriteWidth - 2 * Border);
      const y = getRandomArbitrary(2 * Border, this.game.world.bounds.height - spriteHeight - 2 * Border);
      sprite.position.setTo(x,y);
      maxAttempt = maxAttempt + 1;
      hasBlock = this.game.physics.arcade.collide(sprite, this.room);
    } while(maxAttempt < 10 && hasBlock);
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemies, this.damage, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemies, this.kill, null, this);
    this.game.physics.arcade.overlap(this.enemies, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.enemies);
    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.enemies, this.boomerang, this.killByBoomerang, null, this);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.game.physics.arcade.collide(this.boomerang, this.room, this.killBoomerang, null, this);
    this.game.physics.arcade.overlap(this.hero, this.boomerang, this.launchBoomerang, null, this);
    this.enemies.follow(this.hero.body.position);

    if(this.hero.isDeath()) {
      this.lost();
    }

     if(this.hero.isOutSideTheLevel(this.game) || !this.enemies.hasEnemies()) {
        this.won();
     }
  }

  kill(bullet, enemy) {
    this.enemies.remove(enemy);
    bullet.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  killByBoomerang(boomerang, enemy) {
    if(boomerang.isMoving()) {
      this.enemies.remove(enemy);
    }
  }

  killBoomerang(boomerang) {
    boomerang.kill();
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  launchBoomerang() {
    if(this.launchBoomerangKey.isDown) {
      // after the tween get back to the player
      const onCompleteCallback = (boomerang, tween) => {
         boomerang.kill();
         tween.stop()
      };
      // the first param is the direction
      this.boomerang.launch(this.hero.directionChoosed(), onCompleteCallback);
    }
  }

  lost() {
    this.hero.kill();
    this.deathFx.play();
     setTimeout(() => {
       this.room.clear();
       this.chandelierLayer.clear();
       this.boomerang.kill();
       this.game.goToLose();
     }, 500);
  }

  won() {
    this.game.goToWin();
  }

  preload() {
    this.game.load.image(Wall, "res/block.png");
    this.game.load.spritesheet(SpritePlayer, "res/hero-sprite.png", CharacterWitdh, CharacterHeight);
    this.game.load.spritesheet(SpriteEnemy, "res/zombie.png", EnemyWidth, EnemyHeight);
    this.game.load.spritesheet(SpriteEnemy2, "res/zombie2.png", EnemyWidth, EnemyHeight);
    this.game.load.spritesheet(SpriteEnemy3, "res/zombie1.png", EnemyWidth, EnemyHeight);
    this.game.load.image(SpriteBullet, "res/bullet.png");
    this.game.load.image(BoomerangSprite, "res/ufoRed.png");
    this.game.load.image(Background, "res/boomerang.png");
    this.game.load.image(LightSprite, "res/light.png");
    this.game.load.audio(DeathSound, 'res/painSoundBible.com.mp3');
  }

  render() {
    //this.enemies.render(this.game);
    //this.game.debug.spriteInfo(this.hero, 32, 32);
    //this.game.debug.text(Bounds, 2, 14, "#ff0000");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default Game;
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "underscore", "sakai/sakai.api.core"], function($, _, sakai){

    /**
     * @name sakai_global.versions
     *
     * @class versions
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.versions = function(tuid, showSettings){

        ///////////////
        // VARIABLES //
        ///////////////

        var $rootel = $("#" + tuid);

        // Vars
        var contentPath = "";
        var currentPageShown = "";
        var versions = [];
        var itemsBeforeScroll = 0;

        // Containers
        var versionsContainer = "#versions_container";

        // Templates
        var versionsTemplate = "versions_template";

        // Elements
        var versionsVersionItem = ".versions_version_item";
        var versionsRestoreVersion = ".versions_restore_version";

        var carouselBinding = function(carousel){
            $("#versions_newer", $rootel).live("click",function(){
                carousel.prev();
            });

            $("#versions_older", $rootel).live("click",function(){
                if (carousel.last !== carousel.size()){
                    carousel.next();
                }
            });

            $("#versions_oldest", $rootel).live("click",function(){
                carousel.scroll(carousel.size() || 0);
            });

            $("#versions_newest", $rootel).live("click",function(){
                carousel.scroll(0);
            });
        };

        ///////////////
        // RENDERING //
        ///////////////

        var renderVersions = function(){
            $(versionsContainer, $rootel).html(sakai.api.Util.TemplateRenderer(versionsTemplate, {
                'itemsBeforeScroll': itemsBeforeScroll,
                "data": versions,
                "sakai": sakai,
                "currentPage": currentPageShown
            }));
            $("#versions_carousel_container", $rootel).jcarousel({
                animation: "slow",
                easing: "swing",
                scroll: 4,
                start: 0,
                initCallback: carouselBinding,
                itemFallbackDimension: 123
            });
        };

        var setUsername = function(u, users) {
            $(versions).each(function(index, val){
               var userId = val["_lastModifiedBy"] || val["sakai:pool-content-created-for"];
               if (userId === u){
                    val["username"] = sakai.api.Util.applyThreeDots(sakai.api.User.getDisplayName(users[u]), 80, null, "s3d-regular-links versions_updater");
               }
            });
        };

        var parseVersions = function(success, data){
            var userIds = [];
            $.each(data.versions, function(index, version){
                version.versionId = index;
                versions.push(version);
                userIds.push(version["_lastModifiedBy"] || version["sakai:pool-content-created-for"]);
            });
            if (userIds.length) {
                sakai.api.User.getMultipleUsers(userIds, function(users){
                    for (var u in users) {
                        if (users.hasOwnProperty(u)) {
                            setUsername(u, users);
                        }
                    }
                    renderVersions();
                });
            } else {
                renderVersions();
            }
        };

        //////////
        // UTIL //
        //////////

        var getVersions = function(){
            sakai.api.Server.loadJSON(currentPageShown.pageSavePath + "/" + currentPageShown.saveRef + ".versions.json", parseVersions);
        };

        var getContext = function(){
            contentPath = $.bbq.getState("content_path");
        };

        var getVersionContent = function(versionId, callback) {
            var version = versions[versionId];
            if (!version.version) {
                var vurl = currentPageShown.pageSavePath + '/' + currentPageShown.saveRef + '.version.,' + version.versionId + ',.json';
                sakai.api.Server.loadJSON(vurl, function(success, data) {
                    if (success) {
                        if (!data.version) {
                            version.version = {
                                'rows': [{
                                    'id': sakai.api.Util.generateWidgetId(),
                                    'columns': [{
                                        'width': 1,
                                        'elements': []
                                    }]
                                }]
                            };
                        } else if (_.isString(data.version)) {
                            version.version = $.parseJSON(data.version);
                        }
                        callback(version);
                    }
                });
            } else {
                callback(version);
            }
        };

        var previewVersion = function(event){
            event.stopPropagation();
            if (!sakai_global.content_profile || sakai_global.content_profile.content_data.data.mimeType == "x-sakai/document") {
                $(".versions_selected", $rootel).removeClass("versions_selected");
                $("#" + currentPageShown.ref).remove();
                $(this).addClass("versions_selected");
                getVersionContent($(this).attr('data-versionId'), showPageVersion);
            } else{
                window.open(currentPageShown.pageSavePath + ".version.," + $(this).attr("data-version") + ",/" + $(this).attr("data-pooleditemname"), "_blank");
            }
        };

        var showPageVersion = function(version) {
            var newPageShown = $.extend(true, {}, currentPageShown);
            newPageShown.content = version.version;
            newPageShown.isVersionHistory = true;
            newPageShown.ref = currentPageShown.ref + '_previewversion';
            $(window).trigger('showpage.contentauthoring.sakai', newPageShown);
        };

        var restoreVersion = function(e) {
            getVersionContent($(this).parent().attr('data-versionId'), saveRestoredVersion);
        };

        var saveRestoredVersion = function(version) {
            var toStore = version.version;
            currentPageShown.content = toStore;
            toStore.version = $.toJSON(version.version);
            sakai.api.Server.saveJSON(currentPageShown.pageSavePath + "/" + currentPageShown.saveRef, toStore, function(success) {
                $.ajax({
                    url: currentPageShown.pageSavePath + "/" + currentPageShown.saveRef + ".save.json",
                    type: "POST",
                    success: function(){
                        $(window).trigger("update.versions.sakai", currentPageShown);
                    }
                });
            });
        };

        /////////////
        // BINDING //
        /////////////

        var addBinding = function(){
            if (!sakai_global.content_profile || sakai_global.content_profile.content_data.data.mimeType == "x-sakai/document") {
                $(versionsVersionItem, $rootel).die("click", previewVersion);
                $(versionsVersionItem, $rootel).live("click", previewVersion);
            }

            $(versionsRestoreVersion, $rootel).die("click", restoreVersion);
            $(versionsRestoreVersion, $rootel).live("click", restoreVersion);
        };

        ////////////////////
        // INITIALIZATION //
        ////////////////////

        var doInit = function(){
            versions = [];
            addBinding();
            getContext();
            getVersions();
        };

        $(window).bind("init.versions.sakai", function(ev, cps){
            if ($('.s3d-page-column-left').is(':visible')) {
                // There is a left hand navigation visible, versions widget will be smaller
                $(versionsContainer, $rootel).removeClass("versions_without_left_hand_nav");
                itemsBeforeScroll = 6;
            } else {
                // No left hand navigation visible, versions widget will be wider
                $(versionsContainer, $rootel).addClass("versions_without_left_hand_nav");
                itemsBeforeScroll = 7;
            }
            currentPageShown = cps;
            $('.versions_widget', $rootel).show();
            doInit();
        });
        $(window).bind("close.versions.sakai", function(ev, cps) {
            $('.versions_widget', $rootel).hide();
            $(window).trigger('showpage.contentauthoring.sakai', currentPageShown);
        });

        $(window).bind("update.versions.sakai", function(ev, cps) {
            if ($('.versions_widget', $rootel).is(":visible")) {
                currentPageShown = cps;
                doInit();
            }
        });

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("versions");
});
<commit_msg>SAKIII-5367 - Fix error when no versions https://jira.sakaiproject.org/browse/SAKIII-5367<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "underscore", "sakai/sakai.api.core"], function($, _, sakai){

    /**
     * @name sakai_global.versions
     *
     * @class versions
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.versions = function(tuid, showSettings){

        ///////////////
        // VARIABLES //
        ///////////////

        var $rootel = $("#" + tuid);

        // Vars
        var contentPath = "";
        var currentPageShown = "";
        var versions = [];
        var itemsBeforeScroll = 0;

        // Containers
        var versionsContainer = "#versions_container";

        // Templates
        var versionsTemplate = "versions_template";

        // Elements
        var versionsVersionItem = ".versions_version_item";
        var versionsRestoreVersion = ".versions_restore_version";

        var carouselBinding = function(carousel){
            $("#versions_newer", $rootel).live("click",function(){
                carousel.prev();
            });

            $("#versions_older", $rootel).live("click",function(){
                if (carousel.last !== carousel.size()){
                    carousel.next();
                }
            });

            $("#versions_oldest", $rootel).live("click",function(){
                carousel.scroll(carousel.size() || 0);
            });

            $("#versions_newest", $rootel).live("click",function(){
                carousel.scroll(0);
            });
        };

        ///////////////
        // RENDERING //
        ///////////////

        var renderVersions = function(){
            $(versionsContainer, $rootel).html(sakai.api.Util.TemplateRenderer(versionsTemplate, {
                'itemsBeforeScroll': itemsBeforeScroll,
                "data": versions,
                "sakai": sakai,
                "currentPage": currentPageShown
            }));
            if (versions.length){
                $("#versions_carousel_container", $rootel).jcarousel({
                    animation: "slow",
                    easing: "swing",
                    scroll: 4,
                    start: 0,
                    initCallback: carouselBinding,
                    itemFallbackDimension: 123
                });
            }
        };

        var setUsername = function(u, users) {
            $(versions).each(function(index, val){
               var userId = val["_lastModifiedBy"] || val["sakai:pool-content-created-for"];
               if (userId === u){
                    val["username"] = sakai.api.Util.applyThreeDots(sakai.api.User.getDisplayName(users[u]), 80, null, "s3d-regular-links versions_updater");
               }
            });
        };

        var parseVersions = function(success, data){
            var userIds = [];
            $.each(data.versions, function(index, version){
                version.versionId = index;
                versions.push(version);
                userIds.push(version["_lastModifiedBy"] || version["sakai:pool-content-created-for"]);
            });
            if (userIds.length) {
                sakai.api.User.getMultipleUsers(userIds, function(users){
                    for (var u in users) {
                        if (users.hasOwnProperty(u)) {
                            setUsername(u, users);
                        }
                    }
                    renderVersions();
                });
            } else {
                renderVersions();
            }
        };

        //////////
        // UTIL //
        //////////

        var getVersions = function(){
            sakai.api.Server.loadJSON(currentPageShown.pageSavePath + "/" + currentPageShown.saveRef + ".versions.json", parseVersions);
        };

        var getContext = function(){
            contentPath = $.bbq.getState("content_path");
        };

        var getVersionContent = function(versionId, callback) {
            var version = versions[versionId];
            if (!version.version) {
                var vurl = currentPageShown.pageSavePath + '/' + currentPageShown.saveRef + '.version.,' + version.versionId + ',.json';
                sakai.api.Server.loadJSON(vurl, function(success, data) {
                    if (success) {
                        if (!data.version) {
                            version.version = {
                                'rows': [{
                                    'id': sakai.api.Util.generateWidgetId(),
                                    'columns': [{
                                        'width': 1,
                                        'elements': []
                                    }]
                                }]
                            };
                        } else if (_.isString(data.version)) {
                            version.version = $.parseJSON(data.version);
                        }
                        callback(version);
                    }
                });
            } else {
                callback(version);
            }
        };

        var previewVersion = function(event){
            event.stopPropagation();
            if (!sakai_global.content_profile || sakai_global.content_profile.content_data.data.mimeType == "x-sakai/document") {
                $(".versions_selected", $rootel).removeClass("versions_selected");
                $("#" + currentPageShown.ref).remove();
                $(this).addClass("versions_selected");
                getVersionContent($(this).attr('data-versionId'), showPageVersion);
            } else{
                window.open(currentPageShown.pageSavePath + ".version.," + $(this).attr("data-version") + ",/" + $(this).attr("data-pooleditemname"), "_blank");
            }
        };

        var showPageVersion = function(version) {
            var newPageShown = $.extend(true, {}, currentPageShown);
            newPageShown.content = version.version;
            newPageShown.isVersionHistory = true;
            newPageShown.ref = currentPageShown.ref + '_previewversion';
            $(window).trigger('showpage.contentauthoring.sakai', newPageShown);
        };

        var restoreVersion = function(e) {
            getVersionContent($(this).parent().attr('data-versionId'), saveRestoredVersion);
        };

        var saveRestoredVersion = function(version) {
            var toStore = version.version;
            currentPageShown.content = toStore;
            toStore.version = $.toJSON(version.version);
            sakai.api.Server.saveJSON(currentPageShown.pageSavePath + "/" + currentPageShown.saveRef, toStore, function(success) {
                $.ajax({
                    url: currentPageShown.pageSavePath + "/" + currentPageShown.saveRef + ".save.json",
                    type: "POST",
                    success: function(){
                        $(window).trigger("update.versions.sakai", currentPageShown);
                    }
                });
            });
        };

        /////////////
        // BINDING //
        /////////////

        var addBinding = function(){
            if (!sakai_global.content_profile || sakai_global.content_profile.content_data.data.mimeType == "x-sakai/document") {
                $(versionsVersionItem, $rootel).die("click", previewVersion);
                $(versionsVersionItem, $rootel).live("click", previewVersion);
            }

            $(versionsRestoreVersion, $rootel).die("click", restoreVersion);
            $(versionsRestoreVersion, $rootel).live("click", restoreVersion);
        };

        ////////////////////
        // INITIALIZATION //
        ////////////////////

        var doInit = function(){
            versions = [];
            addBinding();
            getContext();
            getVersions();
        };

        $(window).bind("init.versions.sakai", function(ev, cps){
            if ($('.s3d-page-column-left').is(':visible')) {
                // There is a left hand navigation visible, versions widget will be smaller
                $(versionsContainer, $rootel).removeClass("versions_without_left_hand_nav");
                itemsBeforeScroll = 6;
            } else {
                // No left hand navigation visible, versions widget will be wider
                $(versionsContainer, $rootel).addClass("versions_without_left_hand_nav");
                itemsBeforeScroll = 7;
            }
            currentPageShown = cps;
            $('.versions_widget', $rootel).show();
            doInit();
        });
        $(window).bind("close.versions.sakai", function(ev, cps) {
            $('.versions_widget', $rootel).hide();
            $(window).trigger('showpage.contentauthoring.sakai', currentPageShown);
        });

        $(window).bind("update.versions.sakai", function(ev, cps) {
            if ($('.versions_widget', $rootel).is(":visible")) {
                currentPageShown = cps;
                doInit();
            }
        });

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("versions");
});
<|endoftext|>


<commit_before>/**
 * Created by Hsiang on 2017/1/13.
 * 工具函数
 */

const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
let cached;

// watch DOM change
const _MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false;

module.exports = {
  getScrollBarSize: _getScrollBarSize,
  scrollTop: _scrollTop,
  deepCopy: _deepCopy,
  typeOf: _typeOf,
  warnProp: _warnProp,
  firstUpperCase: _firstUpperCase,
  getStyle: _getStyle,
  camelCase: _camelCase,
  oneOf: _oneOf,
  camelcaseToHyphen: _camelcaseToHyphen,
  MutationObserver: _MutationObserver,
};

// ------------- function -------------

/**
 * 滚动到头部
 * */
function _scrollTop (el, from = 0, to, duration = 500) {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = (
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60);
      }
    );
  }
  const difference = Math.abs(from - to);
  const step = Math.ceil(difference / duration * 50);

  function scroll (start, end, step) {
    if (start === end) return;

    let d = (start + step > end) ? end : start + step;
    if (start > end) {
      d = (start - step < end) ? end : start - step;
    }

    if (el === window) {
      window.scrollTo(d, d);
    } else {
      el.scrollTop = d;
    }
    window.requestAnimationFrame(() => scroll(d, end, step));
  }

  scroll(from, to, step);
}

// deepCopy
function _deepCopy (data) {
  const t = typeOf(data);
  let o;

  if (t === 'array') {
    o = [];
  } else if (t === 'object') {
    o = {};
  } else {
    return data;
  }

  if (t === 'array') {
    for (let i = 0; i < data.length; i++) {
      o.push(deepCopy(data[i]));
    }
  } else if (t === 'object') {
    for (let i in data) {
      o[i] = deepCopy(data[i]);
    }
  }
  return o;
}

function _typeOf (obj) {
  const toString = Object.prototype.toString;
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  return map[toString.call(obj)];
}

// Warn
function _warnProp (component, prop, correctType, wrongType) {
  correctType = firstUpperCase(correctType);
  wrongType = firstUpperCase(wrongType);
  console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`);    // eslint-disable-line
}

// firstUpperCase
function _firstUpperCase (str) {
  return str.toString()[0].toUpperCase() + str.toString().slice(1);
}

// getStyle
function _getStyle (element, styleName) {
  if (!element || !styleName) return null;
  styleName = _camelCase(styleName);
  if (styleName === 'float') {
    styleName = 'cssFloat';
  }
  try {
    const computed = document.defaultView.getComputedStyle(element, '');
    return element.style[styleName] || computed ? computed[styleName] : null;
  } catch (e) {
    return element.style[styleName];
  }
}

function _camelCase (name) {
  return name.replace(SPECIAL_CHARS_REGEXP, function (_, separator, letter, offset) {
    return offset ? letter.toUpperCase() : letter;
  }).replace(MOZ_HACK_REGEXP, 'Moz$1');
}

// 判断参数是否是其中之一
function _oneOf (value, validList) {
  for (let i = 0; i < validList.length; i++) {
    if (value === validList[i]) {
      return true;
    }
  }
  return false;
}

function _camelcaseToHyphen (str) {
  return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}

// For Modal scrollBar hidden
function _getScrollBarSize (fresh) {
  if (fresh || cached === undefined) {
    const inner = document.createElement('div');
    inner.style.width = '100%';
    inner.style.height = '200px';

    const outer = document.createElement('div');
    const outerStyle = outer.style;

    outerStyle.position = 'absolute';
    outerStyle.top = 0;
    outerStyle.left = 0;
    outerStyle.pointerEvents = 'none';
    outerStyle.visibility = 'hidden';
    outerStyle.width = '200px';
    outerStyle.height = '150px';
    outerStyle.overflow = 'hidden';

    outer.appendChild(inner);

    document.body.appendChild(outer);

    const widthContained = inner.offsetWidth;
    outer.style.overflow = 'scroll';
    let widthScroll = inner.offsetWidth;

    if (widthContained === widthScroll) {
      widthScroll = outer.clientWidth;
    }

    document.body.removeChild(outer);

    cached = widthContained - widthScroll;
  }
  return cached;
}
<commit_msg>获取string的数字<commit_after>/**
 * Created by Hsiang on 2017/1/13.
 * 工具函数
 */

const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
let cached;

// watch DOM change
const _MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false;

module.exports = {
  getScrollBarSize: _getScrollBarSize,
  scrollTop: _scrollTop,
  deepCopy: _deepCopy,
  typeOf: _typeOf,
  warnProp: _warnProp,
  firstUpperCase: _firstUpperCase,
  getStyle: _getStyle,
  camelCase: _camelCase,
  oneOf: _oneOf,
  camelcaseToHyphen: _camelcaseToHyphen,
  MutationObserver: _MutationObserver,
  getNum: _getNum,
};

// ------------- function -------------

/**
 * 滚动到头部
 * */
function _scrollTop (el, from = 0, to, duration = 500) {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = (
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60);
      }
    );
  }
  const difference = Math.abs(from - to);
  const step = Math.ceil(difference / duration * 50);

  function scroll (start, end, step) {
    if (start === end) return;

    let d = (start + step > end) ? end : start + step;
    if (start > end) {
      d = (start - step < end) ? end : start - step;
    }

    if (el === window) {
      window.scrollTo(d, d);
    } else {
      el.scrollTop = d;
    }
    window.requestAnimationFrame(() => scroll(d, end, step));
  }

  scroll(from, to, step);
}

// deepCopy
function _deepCopy (data) {
  const t = typeOf(data);
  let o;

  if (t === 'array') {
    o = [];
  } else if (t === 'object') {
    o = {};
  } else {
    return data;
  }

  if (t === 'array') {
    for (let i = 0; i < data.length; i++) {
      o.push(deepCopy(data[i]));
    }
  } else if (t === 'object') {
    for (let i in data) {
      o[i] = deepCopy(data[i]);
    }
  }
  return o;
}

function _typeOf (obj) {
  const toString = Object.prototype.toString;
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  return map[toString.call(obj)];
}

// Warn
function _warnProp (component, prop, correctType, wrongType) {
  correctType = firstUpperCase(correctType);
  wrongType = firstUpperCase(wrongType);
  console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`);    // eslint-disable-line
}

// firstUpperCase
function _firstUpperCase (str) {
  return str.toString()[0].toUpperCase() + str.toString().slice(1);
}

// getStyle
function _getStyle (element, styleName) {
  if (!element || !styleName) return null;
  styleName = _camelCase(styleName);
  if (styleName === 'float') {
    styleName = 'cssFloat';
  }
  try {
    const computed = document.defaultView.getComputedStyle(element, '');
    return element.style[styleName] || computed ? computed[styleName] : null;
  } catch (e) {
    return element.style[styleName];
  }
}

function _camelCase (name) {
  return name.replace(SPECIAL_CHARS_REGEXP, function (_, separator, letter, offset) {
    return offset ? letter.toUpperCase() : letter;
  }).replace(MOZ_HACK_REGEXP, 'Moz$1');
}

// 判断参数是否是其中之一
function _oneOf (value, validList) {
  for (let i = 0; i < validList.length; i++) {
    if (value === validList[i]) {
      return true;
    }
  }
  return false;
}

function _camelcaseToHyphen (str) {
  return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}

// For Modal scrollBar hidden
function _getScrollBarSize (fresh) {
  if (fresh || cached === undefined) {
    const inner = document.createElement('div');
    inner.style.width = '100%';
    inner.style.height = '200px';

    const outer = document.createElement('div');
    const outerStyle = outer.style;

    outerStyle.position = 'absolute';
    outerStyle.top = 0;
    outerStyle.left = 0;
    outerStyle.pointerEvents = 'none';
    outerStyle.visibility = 'hidden';
    outerStyle.width = '200px';
    outerStyle.height = '150px';
    outerStyle.overflow = 'hidden';

    outer.appendChild(inner);

    document.body.appendChild(outer);

    const widthContained = inner.offsetWidth;
    outer.style.overflow = 'scroll';
    let widthScroll = inner.offsetWidth;

    if (widthContained === widthScroll) {
      widthScroll = outer.clientWidth;
    }

    document.body.removeChild(outer);

    cached = widthContained - widthScroll;
  }
  return cached;
}

/**
 * @desc 从字符串中提取数字
 * @param {string} str
 * @return {number}
 * @example 44px => 44
 * @example auto => 0
 * */
function _getNum (str) {
  let _num = str.replace(/[^0-9]/ig, "");
  if (_num === '' || _num === undefined || _num === null) {
    _num = 0;
  }
  return _num * 1
}
<|endoftext|>


<commit_before>/* globals __DEV__ */
import Phaser from 'phaser'
import Ship from '../sprites/Ship'

export default class extends Phaser.State {
  init () {
    this.score = 0
    this.money = 0
  }
  preload () {
    let level = localStorage.getItem('currentLevel')
    if(!level  || level > this.cache.getJSON('commonLevelConfig').levelsCount){
      level = 1
      localStorage.setItem('currentLevel', 1)
    }
    this.load.json('levelConfig', 'http://labirint.dev/assets/levels/'+level+'/config.json')
    this.load.tilemap('tilemap', 'assets/levels/'+level+'/map.json', null, Phaser.Tilemap.TILED_JSON)
  }

  create () {
    this.game.physics.startSystem(Phaser.Physics.ARCADE)
    this.stage.backgroundColor = '#0f93ff'

    this.loadLevelConfig()

    /***** Загружаем слои карты *****/
    this.map = this.add.tilemap('tilemap');
    if(this.levelConfig.tiles){
      this.map.addTilesetImage('tiles', this.levelConfig.tiles);
    }else{
      this.map.addTilesetImage('tiles', 'tiles');
    }

    this.map.setCollisionBetween(0, 900); // все тайлы устанавливаем как непроходимые
    this.layer = this.map.createLayer('Layer 1');
    this.layer2 = this.map.createLayer('Layer 2');

    /***** Загружаем объекты с карты *****/
    this.points = game.add.group();
    this.points.enableBody = true;
    this.coins = game.add.group();
    this.coins.enableBody = true;
    this.chests = game.add.group();
    this.chests.enableBody = true;

    if (this.map.objects['Objects 1']) {
      const mapObjects = this.map.objects['Objects 1']
      mapObjects.forEach(obj => {
        let curY = obj.y - this.map.tileHeight
        if(obj.type == 'chests'){
          this.chests.create(obj.x, curY, 'chest');
        }else if(obj.type == 'coins'){
          this.coins.create(obj.x, curY, 'coin');
        }else if(obj.type == 'points'){
          this.points.create(obj.x, curY, 'flag');
        }
      });
    }

    /***** Игрок *****/
    this.ship = new Ship({
      game: this,
      x: this.levelConfig.startPosition.x,
      y: this.levelConfig.startPosition.y,
      asset: 'ship'
    })
    this.game.add.existing(this.ship)
    this.ship.scale.setTo(0.5, 0.5)
    this.game.physics.arcade.enable(this.ship)
    this.ship.body.collideWorldBounds = true

    /***** АУдио *****/
    this.getCoinAudio = this.game.add.audio('getCoin')
    this.getChestAudio = this.game.add.audio('getChest')
    this.bgAudio = this.game.add.audio('bgAudio')
    this.game.sound.setDecodedCallback([ this.getCoinAudio, this.getChestAudio, this.bgAudio ], this.startAudio, this)

    this.createTexts()

    if(1==1){ // читер!!!
      const key1 = this.game.input.keyboard.addKey(Phaser.Keyboard.ONE)
      key1.onDown.add(
        () => {
          this.score = this.levelConfig.chestsCount
          this.getChestAudio.play()
          console.log('well done')
        },
        this)
      game.input.keyboard.removeKeyCapture(Phaser.Keyboard.ONE);
    }
  }

  update (){
    this.game.physics.arcade.collide(this.ship, this.layer) // проверяем столкновения спрайта персонажа с тайлами карты
    this.game.physics.arcade.overlap(this.ship, this.chests, this.collectChests, null, this)
    this.game.physics.arcade.overlap(this.ship, this.coins, this.collectCoins, null, this)
    this.game.physics.arcade.overlap(this.ship, this.points, this.doFinish, null, this)
  }

  loadLevelConfig(){
    this.levelConfig = this.cache.getJSON('levelConfig')
    console.log('levelConfig', this.levelConfig)
  }

  collectChests (player, chest) {
    // Removes the star from the screen
    chest.kill();
    this.getChestAudio.play()
    //  Add and update the score
    this.score ++
    this.chestsText.text = 'Chests: ' + this.score
  }

  collectCoins(player, coin) {
    // Removes the star from the screen
    coin.kill();
    this.getCoinAudio.play()
    //  Add and update the score
    this.money += 10
    this.coinsText.text = 'Coins: ' + this.money
  }

  doFinish(player, flag){
    if(this.score >= this.levelConfig.chestsCount){
        this.bgAudio.stop()
        this.state.start('MiniGame')
    }
  }

  createTexts(){
    /***** Выводим текст *****/
    this.levelText = this.add.text(800, 30, 'Level: '+this.levelConfig.level)
    this.levelText.font = 'Bangers'
    this.levelText.padding.set(10, 16)
    this.levelText.fontSize = 20
    this.levelText.stroke = '#000000';
    this.levelText.strokeThickness = 5;
    this.levelText.fill = '#77BFA3'
    this.levelText.smoothed = false
    this.levelText.anchor.setTo(0.5)

    this.coinsText = this.add.text(20, 10, 'Coins: 0')
    this.coinsText.font = 'Bangers'
    this.coinsText.padding.set(10, 16)
    this.coinsText.fontSize = 30
    this.coinsText.stroke = '#000000';
    this.coinsText.strokeThickness = 8;
    this.coinsText.fill = '#77BFA3'
    this.coinsText.smoothed = false
    this.coinsText.anchor.setTo(0)

    this.chestsText = this.add.text(20, 50, 'Chests: 0')
    this.chestsText.font = 'Bangers'
    this.chestsText.padding.set(10, 16)
    this.chestsText.fontSize = 30
    this.chestsText.stroke = '#000000';
    this.chestsText.strokeThickness = 8;
    this.chestsText.fill = '#77BFA3'
    this.chestsText.smoothed = false
    this.chestsText.anchor.setTo(0)
  }

  startAudio(){
    this.bgAudio.loopFull()
  }

  render () {
    if (__DEV__) {
      //this.game.debug.spriteInfo(this.mushroom, 32, 32)
    }
  }
}
<commit_msg>Фикс: удален абсолютный путь к конфигурации уровней<commit_after>/* globals __DEV__ */
import Phaser from 'phaser'
import Ship from '../sprites/Ship'

export default class extends Phaser.State {
  init () {
    this.score = 0
    this.money = 0
  }
  preload () {
    let level = localStorage.getItem('currentLevel')
    if(!level  || level > this.cache.getJSON('commonLevelConfig').levelsCount){
      level = 1
      localStorage.setItem('currentLevel', 1)
    }
    this.load.json('levelConfig', 'assets/levels/'+level+'/config.json')
    this.load.tilemap('tilemap', 'assets/levels/'+level+'/map.json', null, Phaser.Tilemap.TILED_JSON)
  }

  create () {
    this.game.physics.startSystem(Phaser.Physics.ARCADE)
    this.stage.backgroundColor = '#0f93ff'

    this.loadLevelConfig()

    /***** Загружаем слои карты *****/
    this.map = this.add.tilemap('tilemap');
    if(this.levelConfig.tiles){
      this.map.addTilesetImage('tiles', this.levelConfig.tiles);
    }else{
      this.map.addTilesetImage('tiles', 'tiles');
    }

    this.map.setCollisionBetween(0, 900); // все тайлы устанавливаем как непроходимые
    this.layer = this.map.createLayer('Layer 1');
    this.layer2 = this.map.createLayer('Layer 2');

    /***** Загружаем объекты с карты *****/
    this.points = game.add.group();
    this.points.enableBody = true;
    this.coins = game.add.group();
    this.coins.enableBody = true;
    this.chests = game.add.group();
    this.chests.enableBody = true;

    if (this.map.objects['Objects 1']) {
      const mapObjects = this.map.objects['Objects 1']
      mapObjects.forEach(obj => {
        let curY = obj.y - this.map.tileHeight
        if(obj.type == 'chests'){
          this.chests.create(obj.x, curY, 'chest');
        }else if(obj.type == 'coins'){
          this.coins.create(obj.x, curY, 'coin');
        }else if(obj.type == 'points'){
          this.points.create(obj.x, curY, 'flag');
        }
      });
    }

    /***** Игрок *****/
    this.ship = new Ship({
      game: this,
      x: this.levelConfig.startPosition.x,
      y: this.levelConfig.startPosition.y,
      asset: 'ship'
    })
    this.game.add.existing(this.ship)
    this.ship.scale.setTo(0.5, 0.5)
    this.game.physics.arcade.enable(this.ship)
    this.ship.body.collideWorldBounds = true

    /***** АУдио *****/
    this.getCoinAudio = this.game.add.audio('getCoin')
    this.getChestAudio = this.game.add.audio('getChest')
    this.bgAudio = this.game.add.audio('bgAudio')
    this.game.sound.setDecodedCallback([ this.getCoinAudio, this.getChestAudio, this.bgAudio ], this.startAudio, this)

    this.createTexts()

    if(1==1){ // читер!!!
      const key1 = this.game.input.keyboard.addKey(Phaser.Keyboard.ONE)
      key1.onDown.add(
        () => {
          this.score = this.levelConfig.chestsCount
          this.getChestAudio.play()
          console.log('well done')
        },
        this)
      game.input.keyboard.removeKeyCapture(Phaser.Keyboard.ONE);
    }
  }

  update (){
    this.game.physics.arcade.collide(this.ship, this.layer) // проверяем столкновения спрайта персонажа с тайлами карты
    this.game.physics.arcade.overlap(this.ship, this.chests, this.collectChests, null, this)
    this.game.physics.arcade.overlap(this.ship, this.coins, this.collectCoins, null, this)
    this.game.physics.arcade.overlap(this.ship, this.points, this.doFinish, null, this)
  }

  loadLevelConfig(){
    this.levelConfig = this.cache.getJSON('levelConfig')
    console.log('levelConfig', this.levelConfig)
  }

  collectChests (player, chest) {
    // Removes the star from the screen
    chest.kill();
    this.getChestAudio.play()
    //  Add and update the score
    this.score ++
    this.chestsText.text = 'Chests: ' + this.score
  }

  collectCoins(player, coin) {
    // Removes the star from the screen
    coin.kill();
    this.getCoinAudio.play()
    //  Add and update the score
    this.money += 10
    this.coinsText.text = 'Coins: ' + this.money
  }

  doFinish(player, flag){
    if(this.score >= this.levelConfig.chestsCount){
        this.bgAudio.stop()
        this.state.start('MiniGame')
    }
  }

  createTexts(){
    /***** Выводим текст *****/
    this.levelText = this.add.text(800, 30, 'Level: '+this.levelConfig.level)
    this.levelText.font = 'Bangers'
    this.levelText.padding.set(10, 16)
    this.levelText.fontSize = 20
    this.levelText.stroke = '#000000';
    this.levelText.strokeThickness = 5;
    this.levelText.fill = '#77BFA3'
    this.levelText.smoothed = false
    this.levelText.anchor.setTo(0.5)

    this.coinsText = this.add.text(20, 10, 'Coins: 0')
    this.coinsText.font = 'Bangers'
    this.coinsText.padding.set(10, 16)
    this.coinsText.fontSize = 30
    this.coinsText.stroke = '#000000';
    this.coinsText.strokeThickness = 8;
    this.coinsText.fill = '#77BFA3'
    this.coinsText.smoothed = false
    this.coinsText.anchor.setTo(0)

    this.chestsText = this.add.text(20, 50, 'Chests: 0')
    this.chestsText.font = 'Bangers'
    this.chestsText.padding.set(10, 16)
    this.chestsText.fontSize = 30
    this.chestsText.stroke = '#000000';
    this.chestsText.strokeThickness = 8;
    this.chestsText.fill = '#77BFA3'
    this.chestsText.smoothed = false
    this.chestsText.anchor.setTo(0)
  }

  startAudio(){
    this.bgAudio.loopFull()
  }

  render () {
    if (__DEV__) {
      //this.game.debug.spriteInfo(this.mushroom, 32, 32)
    }
  }
}
<|endoftext|>


<commit_before>export default {
  title: 'zsx\'s Blog',
  author: 'zsx',
  github: 'https://github.com/zsxsoft',
  themeUrl: 'https://github.com/zsxsoft/blog.zsxsoft.com',
  apiUrl: 'https://blog.zsxsoft.com/api',
  titleOnlyCategoires: ['5', '6', '7'],

  analytics: {
    google: 'UA-128215311-1',
    tencent: '21682966',
    baidu: 'e676290db1a063d7eabcc30211f4000b'
  },

  filing: {
    icp: '闽ICP备15006942号',
    security: {
      text: '闽公网安备 35010302000147 号',
      link: 'http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=35010302000147'
    }
  }
}
<commit_msg>[API] Update API Url<commit_after>export default {
  title: 'zsx\'s Blog',
  author: 'zsx',
  github: 'https://github.com/zsxsoft',
  themeUrl: 'https://github.com/zsxsoft/blog.zsxsoft.com',
  apiUrl: process.browser ? 'https://blog.zsxsoft.com/api' : 'http://blog.zsxsoft.com/api',
  titleOnlyCategoires: ['5', '6', '7'],

  analytics: {
    google: 'UA-128215311-1',
    tencent: '21682966',
    baidu: 'e676290db1a063d7eabcc30211f4000b'
  },

  filing: {
    icp: '闽ICP备15006942号',
    security: {
      text: '闽公网安备 35010302000147 号',
      link: 'http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=35010302000147'
    }
  }
}
<|endoftext|>