<commit_before>/// <autosync enabled="true" />
/// <reference path="modernizr-2.8.3.js" />
/// <reference path="jquery-2.1.1.js" />
/// <reference path="bootstrap.js" />
/// <reference path="respond.js" />
/// <reference path="respond.matchmedia.addlistener.js" />
<commit_msg>references.js updated automatically<commit_after>/// <autosync enabled="true" />
/// <reference path="bootstrap.js" />
/// <reference path="jquery-2.1.1.js" />
/// <reference path="modernizr-2.8.3.js" />
/// <reference path="respond.js" />
/// <reference path="respond.matchmedia.addlistener.js" />
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('GVA.Common')
        .factory('TokenService', TokenService);

    TokenService.$inject = ['$location', '$http', '$localStorage', '$routeParams', '$q', '$timeout'];

    function TokenService($location, $http, $localStorage, $routeParams, $q, $timeout) {

        var service = {
            getToken: getTokenForPoll,
            setToken: setTokenForPoll,
            getManageId: getManageIdForPoll,
            setManageId: setManageIdForPoll
        };

        return service;

        function setTokenForPoll(pollId, token) {
            var deferred = $q.defer();

            if (!$localStorage[pollId]) {
                $localStorage[pollId] = {};
            }

            $localStorage[pollId].token = token;
            // Ensure that we've actually saved the values before continuing. (see https://github.com/gsklee/ngStorage/issues/39)
            $timeout(function () { deferred.resolve(); }, 110);

            return deferred.promise;
        }

        function setManageIdForPoll(pollId, manageId) {
            var deferred = $q.defer();

            if (!$localStorage[pollId]) {
                $localStorage[pollId] = {};
            }

            $localStorage[pollId].manageId = manageId;
            // Ensure that we've actually saved the values before continuing. (see https://github.com/gsklee/ngStorage/issues/39)
            $timeout(function () { deferred.resolve(); }, 110);

            return deferred.promise;
        }

        function getManageIdForPoll(pollId) {
            var deferred = $q.defer();

            if (!pollId) {
                deferred.reject();
                return deferred.promise;
            }

            if ($localStorage[pollId]) {
                deferred.resolve($localStorage[pollId].manageId);
                return deferred.promise;
            }

            return deferred.promise;
        }

        function getTokenForPoll(pollId) {

            var deferred = $q.defer();

            if (!pollId) {
                deferred.reject();
                return deferred.promise;
            }

            if ($routeParams['tokenId']) {
                deferred.resolve($routeParams['tokenId']);
                return deferred.promise;
            }

            if ($localStorage[pollId]) {

                // Fallback for old system
                if (typeof ($localStorage[pollId]) === 'string') {
                    deferred.resolve($localStorage[pollId]);
                } else if ($localStorage[pollId].token) {
                    deferred.resolve($localStorage[pollId].token);
                }
            }

            $http({
                method: 'GET',
                url: '/api/poll/' + pollId + '/token'
            })
            .success(function (data) {
                var token = data.replace(/\"/g, '');
                setTokenForPoll(pollId, token);

                deferred.resolve(token);
            });

            return deferred.promise;
        }
    }
})();<commit_msg>Small fix<commit_after>(function () {
    'use strict';

    angular
        .module('GVA.Common')
        .factory('TokenService', TokenService);

    TokenService.$inject = ['$location', '$http', '$localStorage', '$routeParams', '$q', '$timeout'];

    function TokenService($location, $http, $localStorage, $routeParams, $q, $timeout) {

        var service = {
            getToken: getTokenForPoll,
            setToken: setTokenForPoll,
            getManageId: getManageIdForPoll,
            setManageId: setManageIdForPoll
        };

        return service;

        function setTokenForPoll(pollId, token) {
            var deferred = $q.defer();

            if (!$localStorage[pollId]) {
                $localStorage[pollId] = {};
            }

            $localStorage[pollId].token = token;
            // Ensure that we've actually saved the values before continuing. (see https://github.com/gsklee/ngStorage/issues/39)
            $timeout(function () { deferred.resolve(); }, 110);

            return deferred.promise;
        }

        function setManageIdForPoll(pollId, manageId) {
            var deferred = $q.defer();

            if (!$localStorage[pollId]) {
                $localStorage[pollId] = {};
            }

            $localStorage[pollId].manageId = manageId;
            // Ensure that we've actually saved the values before continuing. (see https://github.com/gsklee/ngStorage/issues/39)
            $timeout(function () { deferred.resolve(); }, 110);

            return deferred.promise;
        }

        function getManageIdForPoll(pollId) {
            var deferred = $q.defer();

            if (!pollId) {
                deferred.reject();
                return deferred.promise;
            }

            if ($localStorage[pollId]) {
                deferred.resolve($localStorage[pollId].manageId);
                return deferred.promise;
            }

            return deferred.promise;
        }

        function getTokenForPoll(pollId) {

            var deferred = $q.defer();

            if (!pollId) {
                deferred.reject();
                return deferred.promise;
            }

            if ($routeParams['tokenId']) {
                deferred.resolve($routeParams['tokenId']);
                return deferred.promise;
            }

            if ($localStorage[pollId]) {

                // Fallback for old system
                if (typeof ($localStorage[pollId]) === 'string') {
                    deferred.resolve($localStorage[pollId]);
                    return deferred.promise;
                } else if ($localStorage[pollId].token) {
                    deferred.resolve($localStorage[pollId].token);
                    return deferred.promise;
                }
            }

            $http({
                method: 'GET',
                url: '/api/poll/' + pollId + '/token'
            })
            .success(function (data) {
                var token = data.replace(/\"/g, '');
                setTokenForPoll(pollId, token);

                deferred.resolve(token);
            });

            return deferred.promise;
        }
    }
})();<|endoftext|>


<commit_before>//
// Implementations of primitive methods
// This is loaded at the very end, everything is already available
// If this gets too long, split it in multiple files
//

ProtoObject._addClassMethods({
	basicNew: function() { return this._newInstance(); },
	_new: function() { return this.basicNew().initialize(); },
	name: function() { return this._classname; }
});
ProtoObject._addInstanceMethods({
	_equals_equals: function(anObject) { if (this === anObject) {return _true; } else { return _false; } }
});

_Object._addInstanceMethods({
	_class: function() { return this.__class; }
});

Error._addInstanceMethods({
	signal: function(){ throw this }
});

String._addInstanceMethods({
	// This is not actually a primitive function, but behaves in the same way the #, method does
	_comma: function(anotherString) { return string(this.string$ + anotherString.string$)}
});

_Number._addInstanceMethods({
	printString: function() { return string(this.num$.toString()); }
});

Float._addInstanceMethods({
	_plus: function(other) { return number(this.num$ + other.num$); },
	_minus: function(other) { return number(this.num$ - other.num$); },
	_times: function(other) { return number(this.num$ * other.num$); },
	_slash: function(other) { return number(this.num$ / other.num$); },
	_slash_slash: function(other) { return number(this.num$ / other.num$); },
	_less: function(other) {
		return bool(this.num$ < other.num$);
	},
	_greater: function(other) {
		return bool(this.num$ > other.num$);
	},
	_less_equals: function(other) {
		return bool(this.num$ <= other.num$);
	},
	_greater_equals: function(other) {
		return bool(this.num$ >= other.num$);
	},
	_equals: function(other) {
		return bool(this.num$ == other.num$);
	},
	timesRepeat_: function(aBlock){
		for (var i = 0; i < this.num$; i++) {
			aBlock.value();
		}
		return this;
	}
});

Point._addInstanceMethods({
	_times: function(aNumber){
		return (this.x()._times(aNumber))._at(this.y()._times(aNumber));
	}
});

var _blockValueFunction_ = function(){ return this.func$.apply(this, arguments); };
BlockClosure._addInstanceMethods({
	value: _blockValueFunction_,
	value_: _blockValueFunction_,
	value_value_: _blockValueFunction_,
	value_value_value_: _blockValueFunction_,
	value_value_value_value_: _blockValueFunction_,

	whileTrue_: function(anotherBlock) {
		// TODO implement whileTrue: for real
		while (this.value() === _true) {
			anotherBlock.value();
		}
	},

	onServer: function() {

	}
});

_Array._addInstanceMethods({
	size: function(){
		return number(this.arr$.length);
	},
	at_put_: function(idx, val){
		this.arr$[idx.num$ - 1] = val;
		return val;
	},
	at_: function(idx){
		return this.arr$[idx.num$ - 1];
	}
});
_Array._addClassMethods({
	new_: function(size){
		return array([]);
	}
});

// Defined in bootstrap.js. Must be called after primitives-initialization.
JsGlobal.AddJsFunctionToAllObjects();
<commit_msg>add isEmpty for strings<commit_after>//
// Implementations of primitive methods
// This is loaded at the very end, everything is already available
// If this gets too long, split it in multiple files
//

ProtoObject._addClassMethods({
	basicNew: function() { return this._newInstance(); },
	_new: function() { return this.basicNew().initialize(); },
	name: function() { return this._classname; }
});
ProtoObject._addInstanceMethods({
	_equals_equals: function(anObject) { if (this === anObject) {return _true; } else { return _false; } }
});

_Object._addInstanceMethods({
	_class: function() { return this.__class; }
});

Error._addInstanceMethods({
	signal: function(){ throw this }
});

String._addInstanceMethods({
	// This is not actually a primitive function, but behaves in the same way the #, method does
	_comma: function(anotherString) { return string(this.string$ + anotherString.string$) },
	_equals: function(anotherString) { return bool(this.string$ == anotherString.string$) },
	isEmpty: function() { return bool(this.string$.length == 0) }
});

_Number._addInstanceMethods({
	printString: function() { return string(this.num$.toString()); }
});

Float._addInstanceMethods({
	_plus: function(other) { return number(this.num$ + other.num$); },
	_minus: function(other) { return number(this.num$ - other.num$); },
	_times: function(other) { return number(this.num$ * other.num$); },
	_slash: function(other) { return number(this.num$ / other.num$); },
	_slash_slash: function(other) { return number(this.num$ / other.num$); },
	_less: function(other) {
		return bool(this.num$ < other.num$);
	},
	_greater: function(other) {
		return bool(this.num$ > other.num$);
	},
	_less_equals: function(other) {
		return bool(this.num$ <= other.num$);
	},
	_greater_equals: function(other) {
		return bool(this.num$ >= other.num$);
	},
	_equals: function(other) {
		return bool(this.num$ == other.num$);
	},
	timesRepeat_: function(aBlock){
		for (var i = 0; i < this.num$; i++) {
			aBlock.value();
		}
		return this;
	}
});

Point._addInstanceMethods({
	_times: function(aNumber){
		return (this.x()._times(aNumber))._at(this.y()._times(aNumber));
	}
});

var _blockValueFunction_ = function(){ return this.func$.apply(this, arguments); };
BlockClosure._addInstanceMethods({
	value: _blockValueFunction_,
	value_: _blockValueFunction_,
	value_value_: _blockValueFunction_,
	value_value_value_: _blockValueFunction_,
	value_value_value_value_: _blockValueFunction_,

	whileTrue_: function(anotherBlock) {
		// TODO implement whileTrue: for real
		while (this.value() === _true) {
			anotherBlock.value();
		}
	},

	onServer: function() {

	}
});

_Array._addInstanceMethods({
	size: function(){
		return number(this.arr$.length);
	},
	at_put_: function(idx, val){
		this.arr$[idx.num$ - 1] = val;
		return val;
	},
	at_: function(idx){
		return this.arr$[idx.num$ - 1];
	},
	isEmpty: function(){
    return (this.arr$.length == 0);
	}
});
_Array._addClassMethods({
	new_: function(size){
		return array([]);
	}
});

// Defined in bootstrap.js. Must be called after primitives-initialization.
JsGlobal.AddJsFunctionToAllObjects();
<|endoftext|>


<commit_before>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe('object'); //A mistake? - http://javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(FILL_ME_IN);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(FILL_ME_IN);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
        refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<commit_msg>it should understand array length<commit_after>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe('object'); //A mistake? - http://javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(4);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(6);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(10);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(5);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
        refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<|endoftext|>


<commit_before>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe("object"); //A mistake? - http://javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(FILL_ME_IN);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(FILL_ME_IN);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
        refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<commit_msg>answered 3rd array<commit_after>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe("object"); //A mistake? - http://javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(4);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(6);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(10);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(5);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
        refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<|endoftext|>


<commit_before>'use strict';

const Api = require('sat-api-lib');
const util = require('lambda-proxy-utils');
const es = require('../../lib/es');
let esClient;

function search(action, req, cb) {
  const s = new Api(req, esClient);

  s[action](function (err, resp) {
    if (err) {
      console.log(err);
      const res = new util.Response({ cors: true, statusCode: 400 });
      return cb(null, res.send({ details: err.message }));
    }
    const res = new util.Response({ cors: true, statusCode: 400 });
    return cb(null, res.send(resp));
  });
}

function getAction(resource) {
  const path = resource.replace('/main', '');

  if (path) {
    return path.replace('/', '');
  }
  return 'simple';
}

/**
 * @api {get} / GET
 * @apiName /
 * @apiGroup search
 * @apiDescription Primary search functionality. Parameters listed are shared across satellites (Landsat-8 and Sentinel-2).
 * Satellite specific parameters can be searched on the in the same fashion (exact match).
 *
 * @apiParam {Number} limit=1 Limit of results to return.
 * @apiParam {Number} skip=0 Results to skip in return.
 * @apiParam {Number} page=1 Results page to view.
 * @apiParam {String} fields Comma separated list of fields to include in the query results. Ex: `?fields=scene_id,date,cloud_coverage`.
 * @apiParam {String} contains Comma separated lists of form `longitude,latitude`. Returns results if the point  is within the bounding box of an image. Ex `?contains=40.23,70.76`.
 * @apiParam {String} intersects Valid GeoJSON, returns results that touch any point of the geometry.
 * @apiParam {String} scene_id Performs exact search on sceneID field.
 * @apiParam {Number} cloud_from The lower limit for cloud_coverage field.
 * @apiParam {Number} cloud_to The upper limit for cloud_coverage field.
 *
 * @apiSuccess {Object} meta Metadata about the search endpoint.
 * @apiSuccess {Number} meta.found Total number of results returned from this query.
 * @apiSuccess {String} meta.name API name.
 * @apiSuccess {String} meta.license API license.
 * @apiSuccess {String} meta.website API endpoint.
 * @apiSuccess {Number} meta.page Results page being viewed.
 * @apiSuccess {Number} meta.limit Limit of results to return.
 * @apiSuccess {Object[]} results Query results.
 * @apiSuccess {String} results.scene_id Scene ID.
 * @apiSuccess {String} results.satellite_name Satellite name.
 * @apiSuccess {Number} results.cloud_coverage Cloud coverage.
 * @apiSuccess {String} results.date Date when image was taken.
 * @apiSuccess {String} results.thumbnail Thumbnail for the scene.
 * @apiSuccess {Object} results.data_geometry GeoJSON representing the scene outline.
 * @apiSuccessExample {json} Minimal Success Response:
 * HTTP/1.1 200 OK
 * {
 *   "meta": {
 *     "found": 2257062,
 *     "name": "sat-api",
 *     "license": "CC0-1.0",
 *     "website": "https://api.developmentseed.org/satellites/",
 *     "page": 1,
 *     "limit": 1
 *   },
 *   "results": [
 *     {
 *       "scene_id": "LC81000202017030LGN00",
 *       "satellite_name": "landsat-8",
 *       "cloud_coverage": 19.53,
 *       "date": "2017-01-30",
 *       "thumbnail": "https://ad-thumbnails.s3.amazonaws.com/LC81000202017030LGN00.jpg",
 *       "data_geometry": {
 *         "crs": {
 *           "type": "name",
 *           "properties": {
 *             "name": "urn:ogc:def:crs:EPSG:8.9:4326"
 *           }
 *         },
 *         "type": "Polygon",
 *         "coordinates": [
 *           [
 *             [
 *               161.38522,
 *               57.878
 *             ],
 *             [
 *               158.27701,
 *               58.39804
 *             ],
 *             [
 *               157.37548,
 *               56.70892
 *             ],
 *             [
 *               160.35236,
 *               56.20273
 *             ],
 *             [
 *               161.38522,
 *               57.878
 *             ]
 *           ]
 *         ]
 *       }
 *     }
 *   ]
 * }
 * @apiSuccessExample {json} Full Success Response:
 * HTTP/1.1 200 OK
 * {
 *   "meta": {
 *     "found": 2257062,
 *     "name": "sat-api",
 *     "license": "CC0-1.0",
 *     "website": "https://api.developmentseed.org/satellites/",
 *     "page": 1,
 *     "limit": 1
 *   },
 *   "results": [
 *     {
 *       "scene_id": "LC81000202017030LGN00",
 *       "satellite_name": "landsat-8",
 *       "cloud_coverage": 19.53,
 *       "date": "2017-01-30",
 *       "thumbnail": "https://ad-thumbnails.s3.amazonaws.com/LC81000202017030LGN00.jpg",
 *       "data_geometry": {
 *         "crs": {
 *           "type": "name",
 *           "properties": {
 *             "name": "urn:ogc:def:crs:EPSG:8.9:4326"
 *           }
 *         },
 *         "type": "Polygon",
 *         "coordinates": [
 *           [
 *             [
 *               161.38522,
 *               57.878
 *             ],
 *             [
 *               158.27701,
 *               58.39804
 *             ],
 *             [
 *               157.37548,
 *               56.70892
 *             ],
 *             [
 *               160.35236,
 *               56.20273
 *             ],
 *             [
 *               161.38522,
 *               57.878
 *             ]
 *           ]
 *         ]
 *       },
 *       "browseAvailable": "Y",
 *       "browseURL": "http://earthexplorer.usgs.gov/browse/landsat_8/2017/100/020/LC81000202017030LGN00.jpg",
 *       "sceneID": "LC81000202017030LGN00",
 *       "sensor": "OLI_TIRS",
 *       "acquisitionDate": "2017-01-30",
 *       "dateUpdated": "2017-01-29",
 *       "path": 100,
 *       "row": 20,
 *       "upperLeftCornerLatitude": 58.39804,
 *       "upperLeftCornerLongitude": 158.27701,
 *       "upperRightCornerLatitude": 57.878,
 *       "upperRightCornerLongitude": 161.38522,
 *       "lowerLeftCornerLatitude": 56.70892,
 *       "lowerLeftCornerLongitude": 157.37548,
 *       "lowerRightCornerLatitude": 56.20273,
 *       "lowerRightCornerLongitude": 160.35236,
 *       "sceneCenterLatitude": 57.30952,
 *       "sceneCenterLongitude": 159.3503,
 *       "cloudCover": 1,
 *       "cloudCoverFull": 19.53,
 *       "dayOrNight": "DAY",
 *       "sunElevation": 13.6553746,
 *       "sunAzimuth": 163.05483232,
 *       "receivingStation": "LGN",
 *       "sceneStartTime": "2017:030:00:26:23.6556890",
 *       "sceneStopTime": "2017:030:00:26:55.4256860",
 *       "imageQuality1": 9,
 *       "DATA_TYPE_L1": "L1T",
 *       "cartURL": "http://earthexplorer.usgs.gov/order/process?dataset_name=LANDSAT_8&ordered=LC81000202017030LGN00",
 *       "ROLL_ANGLE": -0.001,
 *       "GEOMETRIC_RMSE_MODEL_X": 10.185,
 *       "GEOMETRIC_RMSE_MODEL_Y": 11.822,
 *       "FULL_PARTIAL_SCENE": "FULL",
 *       "NADIR_OFFNADIR": "NADIR",
 *       "PROCESSING_SOFTWARE_VERSION": "LPGS_2.6.2",
 *       "CPF_NAME": "L8CPF20170101_20170331.02",
 *       "RLUT_FILE_NAME": "L8RLUT20150303_20431231v11.h5",
 *       "BPF_NAME_OLI": "LO8BPF20170130002250_20170130010416.01",
 *       "BPF_NAME_TIRS": "LT8BPF20170126095930_20170126100746.01",
 *       "GROUND_CONTROL_POINTS_MODEL": 178,
 *       "GROUND_CONTROL_POINTS_VERSION": 4,
 *       "DATE_L1_GENERATED": "2017-01-29 22:17:21",
 *       "TIRS_SSM_MODEL": "PRELIMINARY"
 *     }
 *   ]
 * }
 */
module.exports.handler = function (event, context, cb) {
  const method = event.httpMethod;
  const payload = { query: {} };
  const action = getAction(event.resource);

  if (method === 'POST' && event.body) {
    payload.query = JSON.parse(event.body);
  }
  else if (method === 'GET' && event.queryStringParameters) {
    payload.query = event.queryStringParameters;
  }

  if (!esClient) {
    es.connect().then((client) => {
      esClient = client;
      search(action, payload, cb);
    });
  }
  else {
    search(action, payload, cb);
  }
};
<commit_msg>fix response type<commit_after>'use strict';

const Api = require('sat-api-lib');
const util = require('lambda-proxy-utils');
const es = require('../../lib/es');
let esClient;

function search(action, req, cb) {
  const s = new Api(req, esClient);

  s[action](function (err, resp) {
    if (err) {
      console.log(err);
      const res = new util.Response({ cors: true, statusCode: 400 });
      return cb(null, res.send({ details: err.message }));
    }
    const res = new util.Response({ cors: true, statusCode: 200 });
    return cb(null, res.send(resp));
  });
}

function getAction(resource) {
  const path = resource.replace('/main', '');

  if (path) {
    return path.replace('/', '');
  }
  return 'simple';
}

/**
 * @api {get} / GET
 * @apiName /
 * @apiGroup search
 * @apiDescription Primary search functionality. Parameters listed are shared across satellites (Landsat-8 and Sentinel-2).
 * Satellite specific parameters can be searched on the in the same fashion (exact match).
 *
 * @apiParam {Number} limit=1 Limit of results to return.
 * @apiParam {Number} skip=0 Results to skip in return.
 * @apiParam {Number} page=1 Results page to view.
 * @apiParam {String} fields Comma separated list of fields to include in the query results. Ex: `?fields=scene_id,date,cloud_coverage`.
 * @apiParam {String} contains Comma separated lists of form `longitude,latitude`. Returns results if the point  is within the bounding box of an image. Ex `?contains=40.23,70.76`.
 * @apiParam {String} intersects Valid GeoJSON, returns results that touch any point of the geometry.
 * @apiParam {String} scene_id Performs exact search on sceneID field.
 * @apiParam {Number} cloud_from The lower limit for cloud_coverage field.
 * @apiParam {Number} cloud_to The upper limit for cloud_coverage field.
 *
 * @apiSuccess {Object} meta Metadata about the search endpoint.
 * @apiSuccess {Number} meta.found Total number of results returned from this query.
 * @apiSuccess {String} meta.name API name.
 * @apiSuccess {String} meta.license API license.
 * @apiSuccess {String} meta.website API endpoint.
 * @apiSuccess {Number} meta.page Results page being viewed.
 * @apiSuccess {Number} meta.limit Limit of results to return.
 * @apiSuccess {Object[]} results Query results.
 * @apiSuccess {String} results.scene_id Scene ID.
 * @apiSuccess {String} results.satellite_name Satellite name.
 * @apiSuccess {Number} results.cloud_coverage Cloud coverage.
 * @apiSuccess {String} results.date Date when image was taken.
 * @apiSuccess {String} results.thumbnail Thumbnail for the scene.
 * @apiSuccess {Object} results.data_geometry GeoJSON representing the scene outline.
 * @apiSuccessExample {json} Minimal Success Response:
 * HTTP/1.1 200 OK
 * {
 *   "meta": {
 *     "found": 2257062,
 *     "name": "sat-api",
 *     "license": "CC0-1.0",
 *     "website": "https://api.developmentseed.org/satellites/",
 *     "page": 1,
 *     "limit": 1
 *   },
 *   "results": [
 *     {
 *       "scene_id": "LC81000202017030LGN00",
 *       "satellite_name": "landsat-8",
 *       "cloud_coverage": 19.53,
 *       "date": "2017-01-30",
 *       "thumbnail": "https://ad-thumbnails.s3.amazonaws.com/LC81000202017030LGN00.jpg",
 *       "data_geometry": {
 *         "crs": {
 *           "type": "name",
 *           "properties": {
 *             "name": "urn:ogc:def:crs:EPSG:8.9:4326"
 *           }
 *         },
 *         "type": "Polygon",
 *         "coordinates": [
 *           [
 *             [
 *               161.38522,
 *               57.878
 *             ],
 *             [
 *               158.27701,
 *               58.39804
 *             ],
 *             [
 *               157.37548,
 *               56.70892
 *             ],
 *             [
 *               160.35236,
 *               56.20273
 *             ],
 *             [
 *               161.38522,
 *               57.878
 *             ]
 *           ]
 *         ]
 *       }
 *     }
 *   ]
 * }
 * @apiSuccessExample {json} Full Success Response:
 * HTTP/1.1 200 OK
 * {
 *   "meta": {
 *     "found": 2257062,
 *     "name": "sat-api",
 *     "license": "CC0-1.0",
 *     "website": "https://api.developmentseed.org/satellites/",
 *     "page": 1,
 *     "limit": 1
 *   },
 *   "results": [
 *     {
 *       "scene_id": "LC81000202017030LGN00",
 *       "satellite_name": "landsat-8",
 *       "cloud_coverage": 19.53,
 *       "date": "2017-01-30",
 *       "thumbnail": "https://ad-thumbnails.s3.amazonaws.com/LC81000202017030LGN00.jpg",
 *       "data_geometry": {
 *         "crs": {
 *           "type": "name",
 *           "properties": {
 *             "name": "urn:ogc:def:crs:EPSG:8.9:4326"
 *           }
 *         },
 *         "type": "Polygon",
 *         "coordinates": [
 *           [
 *             [
 *               161.38522,
 *               57.878
 *             ],
 *             [
 *               158.27701,
 *               58.39804
 *             ],
 *             [
 *               157.37548,
 *               56.70892
 *             ],
 *             [
 *               160.35236,
 *               56.20273
 *             ],
 *             [
 *               161.38522,
 *               57.878
 *             ]
 *           ]
 *         ]
 *       },
 *       "browseAvailable": "Y",
 *       "browseURL": "http://earthexplorer.usgs.gov/browse/landsat_8/2017/100/020/LC81000202017030LGN00.jpg",
 *       "sceneID": "LC81000202017030LGN00",
 *       "sensor": "OLI_TIRS",
 *       "acquisitionDate": "2017-01-30",
 *       "dateUpdated": "2017-01-29",
 *       "path": 100,
 *       "row": 20,
 *       "upperLeftCornerLatitude": 58.39804,
 *       "upperLeftCornerLongitude": 158.27701,
 *       "upperRightCornerLatitude": 57.878,
 *       "upperRightCornerLongitude": 161.38522,
 *       "lowerLeftCornerLatitude": 56.70892,
 *       "lowerLeftCornerLongitude": 157.37548,
 *       "lowerRightCornerLatitude": 56.20273,
 *       "lowerRightCornerLongitude": 160.35236,
 *       "sceneCenterLatitude": 57.30952,
 *       "sceneCenterLongitude": 159.3503,
 *       "cloudCover": 1,
 *       "cloudCoverFull": 19.53,
 *       "dayOrNight": "DAY",
 *       "sunElevation": 13.6553746,
 *       "sunAzimuth": 163.05483232,
 *       "receivingStation": "LGN",
 *       "sceneStartTime": "2017:030:00:26:23.6556890",
 *       "sceneStopTime": "2017:030:00:26:55.4256860",
 *       "imageQuality1": 9,
 *       "DATA_TYPE_L1": "L1T",
 *       "cartURL": "http://earthexplorer.usgs.gov/order/process?dataset_name=LANDSAT_8&ordered=LC81000202017030LGN00",
 *       "ROLL_ANGLE": -0.001,
 *       "GEOMETRIC_RMSE_MODEL_X": 10.185,
 *       "GEOMETRIC_RMSE_MODEL_Y": 11.822,
 *       "FULL_PARTIAL_SCENE": "FULL",
 *       "NADIR_OFFNADIR": "NADIR",
 *       "PROCESSING_SOFTWARE_VERSION": "LPGS_2.6.2",
 *       "CPF_NAME": "L8CPF20170101_20170331.02",
 *       "RLUT_FILE_NAME": "L8RLUT20150303_20431231v11.h5",
 *       "BPF_NAME_OLI": "LO8BPF20170130002250_20170130010416.01",
 *       "BPF_NAME_TIRS": "LT8BPF20170126095930_20170126100746.01",
 *       "GROUND_CONTROL_POINTS_MODEL": 178,
 *       "GROUND_CONTROL_POINTS_VERSION": 4,
 *       "DATE_L1_GENERATED": "2017-01-29 22:17:21",
 *       "TIRS_SSM_MODEL": "PRELIMINARY"
 *     }
 *   ]
 * }
 */
module.exports.handler = function (event, context, cb) {
  const method = event.httpMethod;
  const payload = { query: {} };
  const action = getAction(event.resource);

  if (method === 'POST' && event.body) {
    payload.query = JSON.parse(event.body);
  }
  else if (method === 'GET' && event.queryStringParameters) {
    payload.query = event.queryStringParameters;
  }

  if (!esClient) {
    es.connect().then((client) => {
      esClient = client;
      search(action, payload, cb);
    });
  }
  else {
    search(action, payload, cb);
  }
};
<|endoftext|>


<commit_before>/*
 * File   : $Source: /alkacon/cvs/opencms/modules/org.opencms.editors/resources/system/workplace/editors/xmlcontent/help.js,v $
 * Date   : $Date: 2005/05/24 11:05:56 $
 * Version: $Revision: 1.2 $
 *
 * This library is part of OpenCms -
 * the Open Source Content Mananagement System
 *
 * Copyright (C) 2002 - 2005 Alkacon Software (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

var selectBoxes;

function Browser() {
	this.isIE = false;  // Internet Explorer
	if (navigator.userAgent.indexOf("MSIE") != -1) {
		this.isIE = true;
	}
}

var browser = new Browser();

function findPosX(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curleft += obj.offsetLeft - obj.scrollLeft;
            obj = obj.offsetParent;
        }
    } else if (obj.x) {
        curleft += obj.x;
    }
    return curleft;
}

function findPosY(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop - obj.scrollTop;
            obj = obj.offsetParent;
        }
    } else if (obj.y) {
        curtop += obj.y;
    }
    return curtop;
}

function showHelp(id) {

    var text = document.getElementById("help" + id);

    // get all select boxes for Internet Explorer
    if (browser.isIE && selectBoxes == null) {
    	selectBoxes = document.getElementsByTagName("select");
    }

    if (text.style.visibility == "visible") {
        return;
    }

    // get the help icon element
    var icon = document.getElementById("img" + id);
    var xOffset = 8;
    if (icon == null) {
    	// no icon found, this is a combo help text
    	icon = document.getElementById(id);
    	xOffset = 50;
    }

    x = findPosX(icon) + xOffset;
    y = findPosY(icon) + 8;
    var textHeight = text.scrollHeight;
    var textWidth = text.scrollWidth;
    var scrollSize = 20;
    var scrollTop = 0;
    var scrollLeft = 0;
    var clientHeight = 0;
    var clientWidth = 0;
    if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.clientHeight)) {
        scrollTop = document.documentElement.scrollTop;
        scrollLeft = document.documentElement.scrollLeft;
        clientHeight = document.documentElement.clientHeight;
        clientWidth = document.documentElement.clientWidth;
    } else if (document.body) {
        scrollTop = document.body.scrollTop;
        scrollLeft = document.body.scrollLeft;
        clientHeight = document.body.clientHeight;
        clientWidth = document.body.clientWidth;
    }
    if ((y + textHeight) > (clientHeight + scrollTop)) {
        y = y - textHeight;
    }
    if (y < scrollTop) {
        y = (clientHeight + scrollTop) - (textHeight + scrollSize);
    }
    if (y < scrollTop) {
        y = scrollTop;
    }
    if ((x + textWidth) > (clientWidth + scrollLeft)) {
        x = x - textWidth;
    }
    if (x < scrollLeft) {
        x = (clientWidth + scrollLeft) - (textWidth + scrollSize);
    }
    if (x < scrollLeft) {
        x = scrollLeft;
    }
    text.style.left = x + "px";
    text.style.top =  y + "px";
    text.style.visibility = "visible";

    if (browser.isIE) {
    	// hide select boxes which are in help bubble area to avoid display issues
    	for (var i=0; i<selectBoxes.length; i++) {
    		var topPos = findPosY(selectBoxes[i]);
    		if (topPos + selectBoxes[i].offsetHeight >= y && topPos <= y + textHeight) {
    			// hide this select box
    			selectBoxes[i].style.display = "none";
    		}
    	}
    }
}

function hideHelp(id) {
    var text = document.getElementById("help" + id);
    text.style.visibility = "hidden";
    text.style.left = "0px";
    text.style.top =  "0px";
    if (browser.isIE) {
    	// show select boxes which were hidden
    	for (var i=0; i<selectBoxes.length; i++) {
    		if (selectBoxes[i].style.display == "none") {
    			selectBoxes[i].style.display = "";
    		}
    	}
    }
}<commit_msg>changed type from binary to text<commit_after>/*
 * File   : $Source: /alkacon/cvs/opencms/modules/org.opencms.editors/resources/system/workplace/editors/xmlcontent/help.js,v $
 * Date   : $Date: 2005/06/20 12:54:56 $
 * Version: $Revision: 1.3 $
 *
 * This library is part of OpenCms -
 * the Open Source Content Mananagement System
 *
 * Copyright (C) 2002 - 2005 Alkacon Software (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

var selectBoxes;

function Browser() {
	this.isIE = false;  // Internet Explorer
	if (navigator.userAgent.indexOf("MSIE") != -1) {
		this.isIE = true;
	}
}

var browser = new Browser();

function findPosX(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curleft += obj.offsetLeft - obj.scrollLeft;
            obj = obj.offsetParent;
        }
    } else if (obj.x) {
        curleft += obj.x;
    }
    return curleft;
}

function findPosY(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop - obj.scrollTop;
            obj = obj.offsetParent;
        }
    } else if (obj.y) {
        curtop += obj.y;
    }
    return curtop;
}

function showHelp(id) {

    showHelp(id, id);
}

function hideHelp(id) {
    var text = document.getElementById("help" + id);
    text.style.visibility = "hidden";
    text.style.left = "0px";
    text.style.top =  "0px";
    if (browser.isIE) {
    	// show select boxes which were hidden
    	for (var i=0; i<selectBoxes.length; i++) {
    		if (selectBoxes[i].style.display == "none") {
    			selectBoxes[i].style.display = "";
    		}
    	}
    }
}

function showHelpX(id, helpId) {

    var text = document.getElementById("help" + helpId);

    // get all select boxes for Internet Explorer
    if (browser.isIE && selectBoxes == null) {
    	selectBoxes = document.getElementsByTagName("select");
    }

    if (text.style.visibility == "visible") {
        return;
    }

    // get the help icon element
    var icon = document.getElementById("img" + id);
    var xOffset = 8;
    if (icon == null) {
    	// no icon found, this is a combo help text
    	icon = document.getElementById(id);
    	xOffset = 50;
    }

    x = findPosX(icon) + xOffset;
    y = findPosY(icon) + 8;
    var textHeight = text.scrollHeight;
    var textWidth = text.scrollWidth;
    var scrollSize = 20;
    var scrollTop = 0;
    var scrollLeft = 0;
    var clientHeight = 0;
    var clientWidth = 0;
    if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.clientHeight)) {
        scrollTop = document.documentElement.scrollTop;
        scrollLeft = document.documentElement.scrollLeft;
        clientHeight = document.documentElement.clientHeight;
        clientWidth = document.documentElement.clientWidth;
    } else if (document.body) {
        scrollTop = document.body.scrollTop;
        scrollLeft = document.body.scrollLeft;
        clientHeight = document.body.clientHeight;
        clientWidth = document.body.clientWidth;
    }
    if ((y + textHeight) > (clientHeight + scrollTop)) {
        y = y - textHeight;
    }
    if (y < scrollTop) {
        y = (clientHeight + scrollTop) - (textHeight + scrollSize);
    }
    if (y < scrollTop) {
        y = scrollTop;
    }
    if ((x + textWidth) > (clientWidth + scrollLeft)) {
        x = x - textWidth;
    }
    if (x < scrollLeft) {
        x = (clientWidth + scrollLeft) - (textWidth + scrollSize);
    }
    if (x < scrollLeft) {
        x = scrollLeft;
    }
    text.style.left = x + "px";
    text.style.top =  y + "px";
    text.style.visibility = "visible";

    if (browser.isIE) {
    	// hide select boxes which are in help bubble area to avoid display issues
    	for (var i=0; i<selectBoxes.length; i++) {
    		var topPos = findPosY(selectBoxes[i]);
    		if (topPos + selectBoxes[i].offsetHeight >= y && topPos <= y + textHeight) {
    			// hide this select box
    			selectBoxes[i].style.display = "none";
    		}
    	}
    }
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { Tooltip } from '@buffetjs/styles';
import get from 'lodash/get';

const mapToLocaleName = (locales, localeCode) =>
  get(
    locales.find(({ code }) => code === localeCode),
    'name',
    localeCode
  );

const LocaleListCell = ({ locales, localizations, locale: currentLocaleCode, id }) => {
  const allLocalizations = [{ locale: currentLocaleCode }, ...localizations];
  const localizationNames = allLocalizations.map(locale => locale.locale);
  const defaultLocale = locales.find(locale => locale.isDefault);
  const hasDefaultLocale = localizationNames.includes(defaultLocale.code);

  let localesNames;

  if (hasDefaultLocale) {
    const ctLocalesWithoutDefault = localizationNames.filter(
      locale => locale !== defaultLocale.code
    );
    const ctLocalesNamesWithoutDefault = ctLocalesWithoutDefault.map(locale =>
      mapToLocaleName(locales, locale)
    );

    ctLocalesNamesWithoutDefault.sort();

    const ctLocalesNamesWithDefault = [
      `${defaultLocale.name} (default)`,
      ...ctLocalesNamesWithoutDefault,
    ];

    localesNames = ctLocalesNamesWithDefault.join(', ');
  } else {
    const ctLocales = localizationNames.map(locale => mapToLocaleName(locales, locale));
    ctLocales.sort();

    localesNames = ctLocales.join(', ');
  }

  const elId = `entry-${id}__locale`;

  return (

        {localesNames}

      <Tooltip id={elId} place="top" delay={0} />

  );
};

LocaleListCell.propTypes = {
  id: PropTypes.number.isRequired,
  localizations: PropTypes.arrayOf(
    PropTypes.shape({
      locale: PropTypes.string.isRequired,
    })
  ).isRequired,
  locales: PropTypes.arrayOf(
    PropTypes.shape({
      name: PropTypes.string.isRequired,
      code: PropTypes.string.isRequired,
      isDefault: PropTypes.bool,
    })
  ).isRequired,
  locale: PropTypes.string.isRequired,
};

export default LocaleListCell;
<commit_msg>Fix tooltip i18n<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Padded, Text } from '@buffetjs/core';
import { Tooltip } from '@buffetjs/styles';
import get from 'lodash/get';

const mapToLocaleName = (locales, localeCode) =>
  get(
    locales.find(({ code }) => code === localeCode),
    'name',
    localeCode
  );

const LocaleListCell = ({ locales, localizations, locale: currentLocaleCode, id }) => {
  const allLocalizations = [{ locale: currentLocaleCode }, ...localizations];
  const localizationNames = allLocalizations.map(locale => locale.locale);
  const defaultLocale = locales.find(locale => locale.isDefault);
  const hasDefaultLocale = localizationNames.includes(defaultLocale.code);

  let localesArray = [];

  if (hasDefaultLocale) {
    const ctLocalesWithoutDefault = localizationNames.filter(
      locale => locale !== defaultLocale.code
    );
    const ctLocalesNamesWithoutDefault = ctLocalesWithoutDefault.map(locale =>
      mapToLocaleName(locales, locale)
    );

    ctLocalesNamesWithoutDefault.sort();

    const ctLocalesNamesWithDefault = [
      `${defaultLocale.name} (default)`,
      ...ctLocalesNamesWithoutDefault,
    ];

    localesArray = ctLocalesNamesWithDefault;
  } else {
    const ctLocales = localizationNames.map(locale => mapToLocaleName(locales, locale));
    ctLocales.sort();

    localesArray = ctLocales;
  }

  const elId = `entry-${id}__locale`;
  const localesNames = localesArray.join(', ');

  return (

        {localesNames}

      <Tooltip id={elId} place="bottom" delay={0}>
        {localesArray.map(name => (
          <Padded key={name} top bottom size="xs">
            <Text ellipsis color="white">
              {name}
            </Text>
          </Padded>
        ))}
      </Tooltip>

  );
};

LocaleListCell.propTypes = {
  id: PropTypes.number.isRequired,
  localizations: PropTypes.arrayOf(
    PropTypes.shape({
      locale: PropTypes.string.isRequired,
    })
  ).isRequired,
  locales: PropTypes.arrayOf(
    PropTypes.shape({
      name: PropTypes.string.isRequired,
      code: PropTypes.string.isRequired,
      isDefault: PropTypes.bool,
    })
  ).isRequired,
  locale: PropTypes.string.isRequired,
};

export default LocaleListCell;
<|endoftext|>


<commit_before>'use strict'

function HomeWorld() {
    this.__init__()
}

HomeWorld.prototype = {
    scene: null,
    player: null,

    hello_message: null,

    got_camera: null,

    current_world: null,

    //

    __init__: function() {

        this.current_world = false

        this.got_camera = false

        this.scene = new THREE.Scene()

        // Going to try to create a plane here.
        var plane_geometry = new THREE.PlaneGeometry(2000, 2000, 10, 10)
        plane_geometry.applyMatrix(new THREE.Matrix4().makeRotationX(- Math.PI / 2))
        //var plane_material = new THREE.MeshBasicMaterial({color: 0x0000ff})
        var plane_material = new THREE.MeshLambertMaterial({color: 0xccffcc, side: THREE.FrontSide, wireframe: true})
        var plane_mesh     = new THREE.Mesh(plane_geometry, plane_material)
        this.add_to_scene(plane_mesh)

        var light3 = new THREE.PointLight(0xccffcc, .8, 0)
        light3.position.set(5, 100, 5)
        this.add_to_scene(light3)

        var color1 = '#b9ffd2'
        var color2 = '#090920'
        var light2 = new THREE.HemisphereLight(color1, color2, .5)
        this.add_to_scene(light2)

        var light = new THREE.AmbientLight(0x404040, .2) // soft white light
        this.add_to_scene(light)

        this.ajax_status = new Floating2DText(400, 30, '', TYPE_TITLE, this.scene)
        this.ajax_status.update_position_and_look_at(new THREE.Vector3(150, 100, 45), new THREE.Vector3(150, 100, 55))

        // Create the 2 week views here.
        // Temporary design testing.

        var number_of_segments = 14
        var angle_delta = Math.PI / number_of_segments
        var radius = 300

        this.day_titles = []

        var origin = new THREE.Vector3(0, 0, 0)

        for (var i = 0; i < number_of_segments; i++) {
            var day_string = ''
            switch(i % 7) {
            case 0:
                day_string = 'Monday'
                break
            case 1:
                day_string = 'Tuesday'
                break
            case 2:
                day_string = 'Wednesday'
                break
            case 3:
                day_string = 'Thursday'
                break
            case 4:
                day_string = 'Friday'
                break
            case 5:
                day_string = 'Saturday'
                break
            case 6:
                day_string = 'Sunday'
                break
            }
            var day_floating_text = new Floating2DText(100, 25, day_string, TYPE_TITLE, this.scene)

            var x_position = Math.cos(angle_delta * i) * radius
            var z_position = Math.sin(angle_delta * i) * radius

            console.log( x_position + '\t' + z_position)

            day_floating_text.update_position_and_look_at(new THREE.Vector3(x_position, 0, z_position), new THREE.Vector3(origin))
            this.day_titles.push(day_floating_text)
        }
    },

    update: function() {

    },

    add_to_scene: function(object) {
        this.scene.add(object)
    },

    enter_world: function() {
        this.current_world = true
        if (this.got_camera === false) {
            this.add_to_scene(this.player.fps_controls.get_object())
        }
        if (this.hello_message === null) {
            this.ajax_status.update_text('Welcome back ' + this.player.username)
        }
        this.player.set_position(new THREE.Vector3(130, 90, 300))
    },

    exit_world: function() {
        this.current_world = false
    }
}

<commit_msg>general updating 05<commit_after>'use strict'

function HomeWorld() {
    this.__init__()
}

HomeWorld.prototype = {
    scene: null,
    player: null,

    hello_message: null,

    got_camera: null,

    current_world: null,

    //

    __init__: function() {

        this.current_world = false

        this.got_camera = false

        this.scene = new THREE.Scene()

        // Going to try to create a plane here.
        var plane_geometry = new THREE.PlaneGeometry(2000, 2000, 10, 10)
        plane_geometry.applyMatrix(new THREE.Matrix4().makeRotationX(- Math.PI / 2))
        //var plane_material = new THREE.MeshBasicMaterial({color: 0x0000ff})
        var plane_material = new THREE.MeshLambertMaterial({color: 0xccffcc, side: THREE.FrontSide, wireframe: true})
        var plane_mesh     = new THREE.Mesh(plane_geometry, plane_material)
        this.add_to_scene(plane_mesh)

        var light3 = new THREE.PointLight(0xccffcc, .8, 0)
        light3.position.set(5, 100, 5)
        this.add_to_scene(light3)

        var color1 = '#b9ffd2'
        var color2 = '#090920'
        var light2 = new THREE.HemisphereLight(color1, color2, .5)
        this.add_to_scene(light2)

        var light = new THREE.AmbientLight(0x404040, .2) // soft white light
        this.add_to_scene(light)

        this.ajax_status = new Floating2DText(400, 30, '', TYPE_TITLE, this.scene)
        this.ajax_status.update_position_and_look_at(new THREE.Vector3(150, 100, 45), new THREE.Vector3(150, 100, 55))

        // Create the 2 week views here.
        // Temporary design testing.

        var number_of_segments = 14
        var angle_delta = Math.PI / number_of_segments
        var radius = 300

        this.day_titles = []

        var origin = new THREE.Vector3(0, 0, 0)

        for (var i = 0; i < number_of_segments; i++) {
            var day_string = ''
            switch(i % 7) {
            case 0:
                day_string = 'Monday'
                break
            case 1:
                day_string = 'Tuesday'
                break
            case 2:
                day_string = 'Wednesday'
                break
            case 3:
                day_string = 'Thursday'
                break
            case 4:
                day_string = 'Friday'
                break
            case 5:
                day_string = 'Saturday'
                break
            case 6:
                day_string = 'Sunday'
                break
            }
            console.log('Day string : ' + day_string)
            var day_floating_text = new Floating2DText(100, 25, day_string, TYPE_TITLE, this.scene)

            var x_position = Math.cos(angle_delta * i) * radius
            var z_position = Math.sin(angle_delta * i) * radius

            console.log( x_position + '\t' + z_position)

            day_floating_text.update_position_and_look_at(new THREE.Vector3(x_position, 0, z_position), new THREE.Vector3(origin))
            this.day_titles.push(day_floating_text)
        }
    },

    update: function() {

    },

    add_to_scene: function(object) {
        this.scene.add(object)
    },

    enter_world: function() {
        this.current_world = true
        if (this.got_camera === false) {
            this.add_to_scene(this.player.fps_controls.get_object())
        }
        if (this.hello_message === null) {
            this.ajax_status.update_text('Welcome back ' + this.player.username)
        }
        this.player.set_position(new THREE.Vector3(130, 90, 300))
    },

    exit_world: function() {
        this.current_world = false
    }
}

<|endoftext|>


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

/**
 * Internal dependencies
 */
import {
	render,
	fireEvent,
	createTestRegistry,
	provideModules,
} from '../../../../../../../tests/js/test-utils';
import { enabledFeatures } from '../../../../../features';
import { getWidgetComponentProps } from '../../../../../googlesitekit/widgets/util/';
import * as fixtures from '../../../datastore/__fixtures__';
import DashboardIdeasWidget from './index';

describe( 'Idea Hub', () => {
	let registry;
	const widgetComponentProps = getWidgetComponentProps( 'ideaHubIdeas' );

	beforeEach( () => {
		global.location.hash = '';

		enabledFeatures.add( 'ideaHubModule' );

		registry = createTestRegistry();

		provideModules( registry, [
			{
				slug: 'idea-hub',
				active: true,
				connected: true,
			},
		] );

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/draft-post-ideas/,
			{ body: fixtures.draftPostIdeas, status: 200 }
		);

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/saved-ideas/,
			{ body: fixtures.savedIdeas, status: 200 }
		);

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/new-ideas/,
			{ body: fixtures.newIdeas, status: 200 }
		);
	} );

	it.each( [
		[ 'New', '#new-ideas' ],
		[ 'Saved', '#saved-ideas' ],
		[ 'Drafts', '#draft-ideas' ],
	] )(
		'should change location hash & DOM correctly when the %s tab is clicked',
		async ( args, expected ) => {
			const { getByRole, findByRole } = render(
				<DashboardIdeasWidget { ...widgetComponentProps } />,
				{ registry }
			);

			fireEvent.click( getByRole( 'tab', { name: args } ) );
			expect( global.location.hash ).toEqual( expected );

			const tabItem = await findByRole( 'tab', { selected: true } );
			expect( tabItem ).toHaveTextContent( args );
		}
	);
} );
<commit_msg>Fix broken tests.<commit_after>/**
 * DashboardIdeasWidget component tests.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils';

/**
 * Internal dependencies
 */
import {
	render,
	fireEvent,
	createTestRegistry,
	provideModules,
} from '../../../../../../../tests/js/test-utils';
import { enabledFeatures } from '../../../../../features';
import { getWidgetComponentProps } from '../../../../../googlesitekit/widgets/util/';
import * as fixtures from '../../../datastore/__fixtures__';
import DashboardIdeasWidget from './index';

describe( 'Idea Hub', () => {
	let registry;
	const widgetComponentProps = getWidgetComponentProps( 'ideaHubIdeas' );

	beforeEach( () => {
		global.location.hash = '';

		enabledFeatures.add( 'ideaHubModule' );

		registry = createTestRegistry();

		provideModules( registry, [
			{
				slug: 'idea-hub',
				active: true,
				connected: true,
			},
		] );

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/draft-post-ideas/,
			{ body: fixtures.draftPostIdeas }
		);

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/saved-ideas/,
			{ body: fixtures.savedIdeas }
		);

		fetchMock.get(
			/^\/google-site-kit\/v1\/modules\/idea-hub\/data\/new-ideas/,
			{ body: fixtures.newIdeas }
		);

		mockAllIsIntersecting( false );
	} );

	it.each( [
		[ 'New', '#new-ideas' ],
		[ 'Saved', '#saved-ideas' ],
		[ 'Drafts', '#draft-ideas' ],
	] )(
		'should change location hash & DOM correctly when the %s tab is clicked',
		async ( args, expected ) => {
			const { getByRole, findByRole } = render(
				<DashboardIdeasWidget { ...widgetComponentProps } />,
				{ registry }
			);

			fireEvent.click( getByRole( 'tab', { name: args } ) );
			expect( global.location.hash ).toEqual( expected );

			const tabItem = await findByRole( 'tab', { selected: true } );
			expect( tabItem ).toHaveTextContent( args );
		}
	);
} );
<|endoftext|>


<commit_before>import isEmpty from 'lodash/isEmpty';
import find from 'lodash/find';
import { samePageCheckGenerator } from 'kolibri.coreVue.vuex.actions';
import { RemoteChannelResource, ChannelResource } from 'kolibri.resources';
import router from 'kolibri.coreVue.router';
import { ContentWizardPages as PageNames, TransferTypes } from '../../constants';
import {
  availableChannelsPageLink,
  selectContentPageLink,
} from '../../views/manage-content-page/manageContentLinks';
import { loadChannelMetaData, updateTreeViewTopic } from './selectContentActions';
import { refreshDriveList } from './taskActions';
import { refreshChannelList } from './manageContentActions';
import { getAllRemoteChannels } from './availableChannelsActions';

export const LOCAL_DRIVE = 'local';
export const KOLIBRI_STUDIO = 'network';

export function setWizardPageName(store, pageName) {
  store.dispatch('SET_WIZARD_PAGENAME', pageName);
}

export function setTransferType(store, transferType) {
  store.dispatch('SET_TRANSFER_TYPE', transferType);
}

export function setTransferredChannel(store, channel) {
  store.dispatch('SET_TRANSFERRED_CHANNEL', channel);
}

export function startImportWorkflow(store, channel) {
  channel && setTransferredChannel(store, channel);
  setWizardPageName(store, PageNames.SELECT_IMPORT_SOURCE);
}

export function startExportWorkflow(store) {
  setTransferType(store, TransferTypes.LOCALEXPORT);
  setWizardPageName(store, PageNames.SELECT_DRIVE);
}

// Cancels wizard and resets wizardState
export function cancelContentTransferWizard(store) {
  store.dispatch('SET_TRANSFERRED_CHANNEL', {});
  setTransferType(store, '');
  return setWizardPageName(store, '');
}

// Forward from SELECT_IMPORT -> SELECT_DRIVE or AVAILABLE_CHANNELS
export function goForwardFromSelectImportSourceModal(store, source) {
  const { transferredChannel } = store.state.pageState.wizardState;

  if (source === LOCAL_DRIVE) {
    setTransferType(store, TransferTypes.LOCALIMPORT);
    setWizardPageName(store, PageNames.SELECT_DRIVE);
  }

  if (source === KOLIBRI_STUDIO) {
    setTransferType(store, TransferTypes.REMOTEIMPORT);
    // From top-level import workflow
    if (isEmpty(transferredChannel)) {
      return router.push(availableChannelsPageLink());
    }
    // From import-more-from-channel workflow
    return router.push(selectContentPageLink({ channelId: transferredChannel.id }));
  }
}

// Forward from SELECT_DRIVE -> AVAILABLE_CHANNELS or SELECT_CONTENT
export function goForwardFromSelectDriveModal(store, { driveId, forExport }) {
  const { transferredChannel } = store.state.pageState.wizardState;
  // From top-level import/export workflow
  if (isEmpty(transferredChannel)) {
    setWizardPageName(store, PageNames.AVAILABLE_CHANNELS);
    return router.push(availableChannelsPageLink({ driveId, forExport }));
  }
  // From import-more-from-channel workflow
  setWizardPageName(store, PageNames.SELECT_CONTENT);
  return router.push(
    selectContentPageLink({ channelId: transferredChannel.id, driveId, forExport })
  );
}

// Utilities for the show*Page actions
function getSelectedDrive(store, driveId) {
  const { transferType } = store.state.pageState.wizardState;
  return new Promise((resolve, reject) => {
    refreshDriveList(store).then(driveList => {
      const drive = find(driveList, { id: driveId });
      if (drive) {
        if (transferType === TransferTypes.LOCALEXPORT && !drive.writable) {
          reject({ error: 'drive_is_not_writeable' });
        } else {
          resolve({ ...drive });
        }
      } else {
        reject({ error: 'drive_not_found' });
      }
    });
  });
}

function getInstalledChannelsPromise(store) {
  const { channelList } = store.state.pageState;
  // Only refresh channel list if it hasn't been fetched yet (i.e. user went straight to URL)
  if (channelList.length === 0) {
    return refreshChannelList(store);
  } else {
    return Promise.resolve([...channelList]);
  }
}

function getTransferType(params) {
  const { for_export, drive_id } = params;
  // invalid combination
  if (for_export && !drive_id) {
    return null;
  }
  if (drive_id) {
    return for_export ? TransferTypes.LOCALEXPORT : TransferTypes.LOCALIMPORT;
  } else {
    return TransferTypes.REMOTEIMPORT;
  }
}

// Handler for when user goes directly to the Available Channels URL
// params { drive_id?: string, for_export?: boolean }
// are normalized at the router handler function
export function showAvailableChannelsPage(store, params) {
  let selectedDrivePromise = Promise.resolve({});
  let availableChannelsPromise;
  const transferType = getTransferType(params);

  store.dispatch('CORE_SET_PAGE_LOADING', true);

  if (transferType === null) {
    return Promise.reject({ error: 'invalid_parameters' });
  }

  if (transferType === TransferTypes.LOCALEXPORT) {
    selectedDrivePromise = getSelectedDrive(store, params.drive_id);
    availableChannelsPromise = getInstalledChannelsPromise(store);
  }

  if (transferType === TransferTypes.LOCALIMPORT) {
    selectedDrivePromise = getSelectedDrive(store, params.drive_id);
    availableChannelsPromise = selectedDrivePromise.then(drive => {
      return [...drive.metadata.channels];
    });
  }

  if (transferType === TransferTypes.REMOTEIMPORT) {
    availableChannelsPromise = new Promise((resolve, reject) => {
      getInstalledChannelsPromise(store).then(() => {
        return RemoteChannelResource.getCollection()
          .fetch()
          ._promise.then(channels => {
            return getAllRemoteChannels(store, channels).then(allChannels => resolve(allChannels));
          })
          .catch(() => reject({ error: 'kolibri_studio_unavailable' }));
      });
    });
  }

  const isSamePage = samePageCheckGenerator(store);

  return Promise.all([availableChannelsPromise, selectedDrivePromise]).then(
    ([availableChannels, selectedDrive]) => {
      // Hydrate wizardState as if user went through UI workflow
      if (isSamePage()) {
        store.dispatch('SET_AVAILABLE_CHANNELS', availableChannels);
        store.dispatch('SET_SELECTED_DRIVE', selectedDrive.id);
        store.dispatch('SET_TRANSFER_TYPE', transferType);
        store.dispatch('SET_PAGE_NAME', PageNames.AVAILABLE_CHANNELS);
        store.dispatch('CORE_SET_PAGE_LOADING', false);
      }
    }
  );
}

/**
 * Handler for going to Select Content Page URL directly
 * params are { channel_id: string, drive_id?: string, for_export?: boolean },
 * which are normalized at router handler function
 */
export function showSelectContentPage(store, params) {
  let selectedDrivePromise = Promise.resolve({});
  let transferredChannelPromise;
  const { drive_id, channel_id } = params;
  const transferType = getTransferType(params);
  // HACK if going directly to URL, make sure channel list has this channel at the minimum.
  // We only get the one channel, since GETing channel-list with file sizes is slow.
  const installedChannelPromise = ChannelResource.getModel(params.channel_id)
    .fetch({ file_sizes: true }, true)
    .then(channel => {
      if (store.state.pageState.channelList.length === 0) {
        store.dispatch('SET_CHANNEL_LIST', [channel]);
      }
    })
    .catch(() => {});

  if (transferType === null) {
    return Promise.reject({ error: 'invalid_parameters' });
  }

  if (transferType === TransferTypes.LOCALEXPORT) {
    selectedDrivePromise = getSelectedDrive(store, drive_id);
    transferredChannelPromise = new Promise((resolve, reject) => {
      getInstalledChannelsPromise(store).then(channels => {
        const match = find(channels, { id: channel_id });
        if (match) {
          resolve({ ...match });
        } else {
          reject({ error: 'channel_not_found_on_server' });
        }
      });
    });
  }

  if (transferType === TransferTypes.LOCALIMPORT) {
    selectedDrivePromise = getSelectedDrive(store, drive_id);
    transferredChannelPromise = new Promise((resolve, reject) => {
      selectedDrivePromise.then(drive => {
        const match = find(drive.metadata.channels, { id: channel_id });
        if (match) {
          resolve({ ...match });
        } else {
          reject({ error: 'channel_not_found_on_drive' });
        }
      });
    });
  }

  if (transferType === TransferTypes.REMOTEIMPORT) {
    transferredChannelPromise = new Promise((resolve, reject) => {
      RemoteChannelResource.getModel(channel_id)
        // Force fetching because using cached version switches
        // between returning an array and returning an object
        .fetch({}, true)
        .then(
          channels => {
            resolve({ ...channels[0] });
          },
          () => reject({ error: 'channel_not_found_on_studio' })
        );
    });
  }

  let isSamePage = samePageCheckGenerator(store);

  return Promise.all([
    selectedDrivePromise,
    transferredChannelPromise,
    installedChannelPromise,
  ]).then(promises => {
    const [selectedDrive, transferredChannel] = promises;

    if (isSamePage()) {
      store.dispatch('SET_SELECTED_DRIVE', selectedDrive.id);
      store.dispatch('SET_TRANSFERRED_CHANNEL', { ...transferredChannel });
      store.dispatch('SET_TRANSFER_TYPE', transferType);
      store.dispatch('SET_PAGE_NAME', PageNames.SELECT_CONTENT);
      store.dispatch('CORE_SET_PAGE_LOADING', false);
      isSamePage = samePageCheckGenerator(store);
      return loadChannelMetaData(store).then(() => {
        if (isSamePage()) {
          return updateTreeViewTopic(store, {
            pk: store.state.pageState.wizardState.transferredChannel.root,
            title: transferredChannel.name,
          });
        }
      });
    }
  });
}
<commit_msg>Handle intermediate stage before available channels page<commit_after>import isEmpty from 'lodash/isEmpty';
import find from 'lodash/find';
import { samePageCheckGenerator } from 'kolibri.coreVue.vuex.actions';
import { RemoteChannelResource, ChannelResource } from 'kolibri.resources';
import router from 'kolibri.coreVue.router';
import { createTranslator } from 'kolibri.utils.i18n';
import { ContentWizardPages as PageNames, TransferTypes } from '../../constants';
import {
  availableChannelsPageLink,
  selectContentPageLink,
} from '../../views/manage-content-page/manageContentLinks';
import { loadChannelMetaData, updateTreeViewTopic } from './selectContentActions';
import { refreshDriveList } from './taskActions';
import { refreshChannelList } from './manageContentActions';
import { getAllRemoteChannels } from './availableChannelsActions';

const translator = createTranslator('contentWizardTexts', {
  loadingChannelsToolbar: 'Loading channels…',
});

export const LOCAL_DRIVE = 'local';
export const KOLIBRI_STUDIO = 'network';

export function setWizardPageName(store, pageName) {
  store.dispatch('SET_WIZARD_PAGENAME', pageName);
}

export function setTransferType(store, transferType) {
  store.dispatch('SET_TRANSFER_TYPE', transferType);
}

export function setTransferredChannel(store, channel) {
  store.dispatch('SET_TRANSFERRED_CHANNEL', channel);
}

export function startImportWorkflow(store, channel) {
  channel && setTransferredChannel(store, channel);
  setWizardPageName(store, PageNames.SELECT_IMPORT_SOURCE);
}

export function startExportWorkflow(store) {
  setTransferType(store, TransferTypes.LOCALEXPORT);
  setWizardPageName(store, PageNames.SELECT_DRIVE);
}

// Cancels wizard and resets wizardState
export function cancelContentTransferWizard(store) {
  store.dispatch('SET_TRANSFERRED_CHANNEL', {});
  setTransferType(store, '');
  return setWizardPageName(store, '');
}

// Provide a intermediate state before Available Channels is fully-loaded
function prepareForAvailableChannelsPage(store) {
  store.dispatch('SET_TOOLBAR_TITLE', translator.$tr('loadingChannelsToolbar'));
  store.dispatch('SET_PAGE_NAME', PageNames.AVAILABLE_CHANNELS);
}

// Forward from SELECT_IMPORT -> SELECT_DRIVE or AVAILABLE_CHANNELS
export function goForwardFromSelectImportSourceModal(store, source) {
  const { transferredChannel } = store.state.pageState.wizardState;

  if (source === LOCAL_DRIVE) {
    setTransferType(store, TransferTypes.LOCALIMPORT);
    setWizardPageName(store, PageNames.SELECT_DRIVE);
  }

  if (source === KOLIBRI_STUDIO) {
    setTransferType(store, TransferTypes.REMOTEIMPORT);
    // From top-level import workflow
    if (isEmpty(transferredChannel)) {
      prepareForAvailableChannelsPage(store);
      return router.push(availableChannelsPageLink());
    }
    // From import-more-from-channel workflow
    return router.push(selectContentPageLink({ channelId: transferredChannel.id }));
  }
}

// Forward from SELECT_DRIVE -> AVAILABLE_CHANNELS or SELECT_CONTENT
export function goForwardFromSelectDriveModal(store, { driveId, forExport }) {
  const { transferredChannel } = store.state.pageState.wizardState;
  // From top-level import/export workflow
  if (isEmpty(transferredChannel)) {
    prepareForAvailableChannelsPage(store);
    return router.push(availableChannelsPageLink({ driveId, forExport }));
  }
  // From import-more-from-channel workflow
  setWizardPageName(store, PageNames.SELECT_CONTENT);
  return router.push(
    selectContentPageLink({ channelId: transferredChannel.id, driveId, forExport })
  );
}

// Utilities for the show*Page actions
function getSelectedDrive(store, driveId) {
  const { transferType } = store.state.pageState.wizardState;
  return new Promise((resolve, reject) => {
    refreshDriveList(store).then(driveList => {
      const drive = find(driveList, { id: driveId });
      if (drive) {
        if (transferType === TransferTypes.LOCALEXPORT && !drive.writable) {
          reject({ error: 'drive_is_not_writeable' });
        } else {
          resolve({ ...drive });
        }
      } else {
        reject({ error: 'drive_not_found' });
      }
    });
  });
}

function getInstalledChannelsPromise(store) {
  const { channelList } = store.state.pageState;
  // Only refresh channel list if it hasn't been fetched yet (i.e. user went straight to URL)
  if (channelList.length === 0) {
    return refreshChannelList(store);
  } else {
    return Promise.resolve([...channelList]);
  }
}

function getTransferType(params) {
  const { for_export, drive_id } = params;
  // invalid combination
  if (for_export && !drive_id) {
    return null;
  }
  if (drive_id) {
    return for_export ? TransferTypes.LOCALEXPORT : TransferTypes.LOCALIMPORT;
  } else {
    return TransferTypes.REMOTEIMPORT;
  }
}

// Handler for when user goes directly to the Available Channels URL
// params { drive_id?: string, for_export?: boolean }
// are normalized at the router handler function
export function showAvailableChannelsPage(store, params) {
  let selectedDrivePromise = Promise.resolve({});
  let availableChannelsPromise;
  const transferType = getTransferType(params);

  store.dispatch('CORE_SET_PAGE_LOADING', true);

  if (transferType === null) {
    return Promise.reject({ error: 'invalid_parameters' });
  }

  if (transferType === TransferTypes.LOCALEXPORT) {
    selectedDrivePromise = getSelectedDrive(store, params.drive_id);
    availableChannelsPromise = getInstalledChannelsPromise(store);
  }

  if (transferType === TransferTypes.LOCALIMPORT) {
    selectedDrivePromise = getSelectedDrive(store, params.drive_id);
    availableChannelsPromise = selectedDrivePromise.then(drive => {
      return [...drive.metadata.channels];
    });
  }

  if (transferType === TransferTypes.REMOTEIMPORT) {
    availableChannelsPromise = new Promise((resolve, reject) => {
      getInstalledChannelsPromise(store).then(() => {
        return RemoteChannelResource.getCollection()
          .fetch()
          ._promise.then(channels => {
            return getAllRemoteChannels(store, channels).then(allChannels => resolve(allChannels));
          })
          .catch(() => reject({ error: 'kolibri_studio_unavailable' }));
      });
    });
  }

  const isSamePage = samePageCheckGenerator(store);

  return Promise.all([availableChannelsPromise, selectedDrivePromise]).then(
    ([availableChannels, selectedDrive]) => {
      // Hydrate wizardState as if user went through UI workflow
      if (isSamePage()) {
        store.dispatch('SET_AVAILABLE_CHANNELS', availableChannels);
        store.dispatch('SET_SELECTED_DRIVE', selectedDrive.id);
        store.dispatch('SET_TRANSFER_TYPE', transferType);
        store.dispatch('SET_PAGE_NAME', PageNames.AVAILABLE_CHANNELS);
        store.dispatch('CORE_SET_PAGE_LOADING', false);
      }
    }
  );
}

/**
 * Handler for going to Select Content Page URL directly
 * params are { channel_id: string, drive_id?: string, for_export?: boolean },
 * which are normalized at router handler function
 */
export function showSelectContentPage(store, params) {
  let selectedDrivePromise = Promise.resolve({});
  let transferredChannelPromise;
  const { drive_id, channel_id } = params;
  const transferType = getTransferType(params);
  // HACK if going directly to URL, make sure channel list has this channel at the minimum.
  // We only get the one channel, since GETing channel-list with file sizes is slow.
  const installedChannelPromise = ChannelResource.getModel(params.channel_id)
    .fetch({ file_sizes: true }, true)
    .then(channel => {
      if (store.state.pageState.channelList.length === 0) {
        store.dispatch('SET_CHANNEL_LIST', [channel]);
      }
    })
    .catch(() => {});

  if (transferType === null) {
    return Promise.reject({ error: 'invalid_parameters' });
  }

  if (transferType === TransferTypes.LOCALEXPORT) {
    selectedDrivePromise = getSelectedDrive(store, drive_id);
    transferredChannelPromise = new Promise((resolve, reject) => {
      getInstalledChannelsPromise(store).then(channels => {
        const match = find(channels, { id: channel_id });
        if (match) {
          resolve({ ...match });
        } else {
          reject({ error: 'channel_not_found_on_server' });
        }
      });
    });
  }

  if (transferType === TransferTypes.LOCALIMPORT) {
    selectedDrivePromise = getSelectedDrive(store, drive_id);
    transferredChannelPromise = new Promise((resolve, reject) => {
      selectedDrivePromise.then(drive => {
        const match = find(drive.metadata.channels, { id: channel_id });
        if (match) {
          resolve({ ...match });
        } else {
          reject({ error: 'channel_not_found_on_drive' });
        }
      });
    });
  }

  if (transferType === TransferTypes.REMOTEIMPORT) {
    transferredChannelPromise = new Promise((resolve, reject) => {
      RemoteChannelResource.getModel(channel_id)
        // Force fetching because using cached version switches
        // between returning an array and returning an object
        .fetch({}, true)
        .then(
          channels => {
            resolve({ ...channels[0] });
          },
          () => reject({ error: 'channel_not_found_on_studio' })
        );
    });
  }

  let isSamePage = samePageCheckGenerator(store);

  return Promise.all([
    selectedDrivePromise,
    transferredChannelPromise,
    installedChannelPromise,
  ]).then(promises => {
    const [selectedDrive, transferredChannel] = promises;

    if (isSamePage()) {
      store.dispatch('SET_SELECTED_DRIVE', selectedDrive.id);
      store.dispatch('SET_TRANSFERRED_CHANNEL', { ...transferredChannel });
      store.dispatch('SET_TRANSFER_TYPE', transferType);
      store.dispatch('SET_PAGE_NAME', PageNames.SELECT_CONTENT);
      store.dispatch('CORE_SET_PAGE_LOADING', false);
      isSamePage = samePageCheckGenerator(store);
      return loadChannelMetaData(store).then(() => {
        if (isSamePage()) {
          return updateTreeViewTopic(store, {
            pk: store.state.pageState.wizardState.transferredChannel.root,
            title: transferredChannel.name,
          });
        }
      });
    }
  });
}
<|endoftext|>


<commit_before>function localStorage(dbname){
	this._partition = dbname;
	this._keys  = [];

	for (var i = 0; i < window.localStorage.length; i++){
    	if(window.localStorage.key(i).indexOf(dbname) == 0)
    		this._keys.push(window.localStorage.key(i))
    }
    this._keys.sort();
}

//key: Returns the name of the key at the position specified.
localStorage.prototype.key = function (keyindex){
		var retVal = this._keys[keyindex];
		if(typeof retVal !== 'undefined'){
            // this needs to be a last and first;
			return this._keys[keyindex].replace(this._partition + '!', "").replace("!bin");
		}else{
			return retVal;
		}
}

//setItem: Saves and item at the key provided.
localStorage.prototype.setItem = function (key, value){
    	key = this._partition + "!" + key;

        if(value instanceof ArrayBuffer || value instanceof Uint8Array) {
            value = String.fromCharCode.apply(null, value)
        }

    	for (var i = 0; i < this._keys.length; i++) {
	        if (this._keys[i] === key) {
	            window.localStorage.setItem(key, value);
	            return;
	        }
	    }

    	this._keys.push(key)
		this._keys.sort()
		window.localStorage.setItem(key, value);

}

//getItem: Returns the item identified by it's key.
localStorage.prototype.getItem = function (key){
	    key = this._partition + "!" + key
		var retval = window.localStorage.getItem(key)
    	if(retval == null){
            key += "!bin";
            retval = window.localStorage.getItem(key);
            if(retval == null){
                retval = undefined;
                }/*else {
                    charList = retval.split(''),
                    uintArray = [];
                    for (var i = 0; i < charList.length; i++) {
                        uintArray.push(charList[i].charCodeAt(0));
                    }
                return new Uint8Array(uintArray);
            }*/

    	}
    	return retval;
}

//removeItem: Removes the item identified by it's key.
localStorage.prototype.removeItem = function (key){
	key = this._partition + "!" + key

	for(var i = this._keys.length; i >= 0; i--) {
    	if(this._keys[i] === key) {
	       this._keys.splice(i, 1);
		   window.localStorage.removeItem(key);
    	}
	}
}

    //clear: Removes all of the key value pairs.
localStorage.prototype.clear = function (){
	window.localStorage.clear()
}

localStorage.prototype.length = function(){

	return this._keys.length
}

exports.localStorage = localStorage;
<commit_msg>small change<commit_after>function localStorage(dbname){
	this._partition = dbname;
	this._keys  = [];

	for (var i = 0; i < window.localStorage.length; i++){
    	if(window.localStorage.key(i).indexOf(dbname) == 0)
    		this._keys.push(window.localStorage.key(i))
    }
    this._keys.sort();
}

//key: Returns the name of the key at the position specified.
localStorage.prototype.key = function (keyindex){
		var retVal = this._keys[keyindex];
		if(typeof retVal !== 'undefined'){
            // this needs to be a last and first;
			return this._keys[keyindex].replace(this._partition + '!', "").replace("!bin");
		}else{
			return retVal;
		}
}

//setItem: Saves and item at the key provided.
localStorage.prototype.setItem = function (key, value){
    	key = this._partition + "!" + key;

        if(value instanceof ArrayBuffer || value instanceof Uint8Array) {
            value = String.fromCharCode.apply(null, value)
        }

    	for (var i = 0; i < this._keys.length; i++) {
	        if (this._keys[i] === key) {
	            window.localStorage.setItem(key, value);
	            return;
	        }
	    }

    	this._keys.push(key)
		this._keys.sort()
		window.localStorage.setItem(key, value);

}

//getItem: Returns the item identified by it's key.
localStorage.prototype.getItem = function (key){
   key = this._partition + "!" + key
   var retval = window.localStorage.getItem(key)
      if(retval == null){
         key += "!bin";
         retval = window.localStorage.getItem(key);
            if(retval == null){
               retval = undefined;
            }/*else {
                    charList = retval.split(''),
                    uintArray = [];
                    for (var i = 0; i < charList.length; i++) {
                        uintArray.push(charList[i].charCodeAt(0));
                    }
                return new Uint8Array(uintArray);
            }*/

    	}
    	return retval;
}

//removeItem: Removes the item identified by it's key.
localStorage.prototype.removeItem = function (key){
	key = this._partition + "!" + key

	for(var i = this._keys.length; i >= 0; i--) {
    	if(this._keys[i] === key) {
	       this._keys.splice(i, 1);
		   window.localStorage.removeItem(key);
    	}
	}
}

    //clear: Removes all of the key value pairs.
localStorage.prototype.clear = function (){
	window.localStorage.clear()
}

localStorage.prototype.length = function(){

	return this._keys.length
}

exports.localStorage = localStorage;
<|endoftext|>