<commit_before>/*
	GEIESLISTS - JS lists
	Author: Marco Faustinelli (contacts@faustinelli.net)
	Web: http://faustinelli.net/
	     http://faustinelli.wordpress.com/
	Version: 1.1

	The MIT License - Copyright (c) 2012-2015 Geieslists Project
*/
var L = function() {
    var EMPTY = function(x){return x;};
    var Nil = EMPTY
    var nil = EMPTY
    var NIL = EMPTY

    // cons returns an APPLICATOR OF BINARY FUNCTIONS
    function cons(x, y) {
        if (x === null || typeof x === "undefined") throw "cannot cons without head";
        if (typeof(y) !== "function")   // y must be a function at any cost (but this check is 99% safe)
            throw "cannot cons without a function in the tail";
        var result = function(w) {
            return w(x, y);
        };
        // we  can safely freeze the string representation because cons is immutable
        result.c = consToString(result)
        return result;
    };

    // car returns the APPLICATION of a binary function to an APPLICATOR of binary functions
    function head(cons) {
        return cons(function (x, y) { return x; });
    };

    // cdr returns the APPLICATION of a binary function to an APPLICATOR of binary functions
    function tail(cons) {
        return cons(function (x, y) { return y; });
    };

    // WARNING: contains mutable vars!
    function List() {
        var bigCons = EMPTY;
        for (var i = arguments.length; i--; ) {
            bigCons = cons(arguments[i], bigCons);
        }
        return bigCons
    };

    // WARNING: contains mutable vars!
    function ArrayToList(anArray) {
        var bigCons = EMPTY;
        for (var i = anArray.length; i--; ) {
            // string, number or boolean
            if (isAtom(anArray[i]))
                bigCons = cons(anArray[i], bigCons);
            // else array
            else bigCons = cons(ArrayToList(anArray[i]), bigCons)
        }
        return bigCons
    }

    function isEmpty(list){
        return (list === EMPTY);
    }

    function isAtom(sexpr){
        return (typeof(sexpr) === "string" || typeof(sexpr) === "number" || typeof(sexpr) === "boolean");
    }

    function size(list) {
        if (isEmpty(list))
            return 0
        else
            return 1 + size(tail(list))
    }

    // as alternative you may invoke cons.c
    function consToString(cons) {
        var adder = function (curCons, acc) {
            if (isEmpty(curCons))
                return acc + "]"
            else if (isAtom(head(curCons)))
                return adder(tail(curCons), acc + head(curCons) + (isEmpty(tail(curCons)) ? "" : ","))
            else
                return adder(tail(curCons), acc + consToString(head(curCons)) + (isEmpty(tail(curCons)) ? "" : ","))
        }
        return adder(cons, "[")
    }

    function last(list) {
        if (isEmpty(tail(list)))
            return head(list)
        else
            return last(tail(list))
    }

    // all elements except the last one
    function listInit(list) {
        if (isEmpty(tail(list))) {
            return EMPTY;
        } else {
            return cons(head(list), listInit(tail(list)));
        }
    }

    function concat(list1, list2) {
        if (isEmpty(list1)) return list2
        else if (isEmpty(list2)) return list1
        else if (isEmpty(tail(list1)))
            return cons(head(list1), list2)
        else
            return cons(head(list1), concat(tail(list1), list2))
    }

    function reverse(list) {
        if (isEmpty(tail(list)))
            return list
        else
            return concat(reverse(tail(list)), cons(head(list), EMPTY))
    }

    function insert(elem, orderedList) {
        if (isEmpty(orderedList))
            return cons(elem, EMPTY)
        else if (elem < head(orderedList))
            return cons(elem, orderedList)
        else
            return cons(head(orderedList), insert(elem, tail(orderedList)))
    }

    function sort(list) {
        if (isEmpty(tail(list)))
            return list
        else
            return insert(head(list), sort(tail(list)))
    }

    // take(2,List(a,b,c,d,e)) --> List(a,b)
    function take(elems, list) { // elems = absolute number of list elements
        if (isEmpty(list) || size(list) === elems) return list
        else return take(elems, listInit(list))
    }

    // drop(2,List(a,b,c,d,e)) --> List(c,d,e)
    function drop(elems, list) { // elems = absolute number of list elements
        if (isEmpty(list) || elems === 0) return list
        else return drop(elems - 1, tail(list))
    }

    // index starts from 0
    function elementAt(index, list) {
        if (isEmpty(list)) return list
        else if (index === 0) return head(list)
        else return elementAt(index - 1, tail(list))
    }

    function isMember(atom, list) {
        if (isEmpty(list)) return false;
        else return (head(list) === atom) || (isMember(atom, tail(list)));
    }

    // index starts from 0
    function removeAt(index, list) {
        if (index < 0 || index > size(list)) return list
        return concat(take(index, list), drop(index + 1, list))
    }

    // it means "split after given element"
    function splitAt(elem,list) {
        if (elem<1) {
            return ({v1:List(),v2:list});
        } else if (elem>size(list)) {
            return ({v1:list,v2:List()});
        } else {
        var splitT = function (tuple) {
            var xs = tuple.v1, ys = tuple.v2;
            if (size(xs) === elem) return ({ v1: xs, v2: ys })
            else return splitT({ v1: concat(xs, List(head(ys))), v2: tail(ys) })
        }
            return splitT({v1:List(),v2:list})
        }
    }

    // Marco's
    function equalList(listA,listB) {
        if (size(listA) !== size(listB)) return false;
        var innerEq = function(alist,blist) {
            if (head(alist) !== head(blist)) return false;
            else if (isEmpty(tail(alist)) && isEmpty(tail(blist))) return true;
            else return innerEq(tail(alist),tail(blist));
        }
        return innerEq(listA,listB)
    }

    // Dionyzis's
    function equalList2( listA, listB ) {
        return isEmpty( listA ) && isEmpty( listB )
            ||    !isEmpty( listB )
              && !isEmpty( listB )
              && head( listA ) === head( listB )
              && equalList( tail( listA ), tail( listB ) );
    }

    function msort(list) {
        var n = Math.floor(size(list) / 2)
        if (n === 0)
            return list
        else {
            var mergeT = function (xs, ys) {
                if (isEmpty(xs))
                    return ys
                else if (isEmpty(ys))
                    return xs
                else { // both lists have at least one element
                    if (head(xs) <= head(ys))
                        return cons(head(xs), mergeT(tail(xs), ys))
                    else
                        return cons(head(ys), mergeT(xs, tail(ys)))
                }
            }
            var tuple = splitAt(n, list)
            return mergeT(msort(tuple.v1), msort(tuple.v2))
        }
    }

    return {
        nil: nil,
        cons: cons,
        car: head,
        cdr: tail,
        head: head,
        tail: tail,
        List: List,
        ArrayToList: ArrayToList,
        isEmpty: isEmpty,
        isAtom: isAtom,
        size: size,
        consToString: consToString,
        last: last,
        listInit: listInit,
        concat: concat,
        reverse: reverse,
        insert: insert,
        sort: sort,
        take: take,
        drop: drop,
        elementAt: elementAt,
        isMember: isMember,
        removeAt: removeAt,
        splitAt: splitAt,
        equalList: equalList,
        msort: msort
    }
}();
<commit_msg>Update geieslists_1.1.js<commit_after>/*
	GEIESLISTS - JS lists
	Author: Marco Faustinelli (contacts@faustinelli.net)
	Web: http://faustinelli.net/
	     http://faustinelli.wordpress.com/
	Version: 1.1

	The MIT License - Copyright (c) 2012-2015 Geieslists Project
*/
var L = function() {
    var EMPTY = function(x){return x;};
    var Nil = EMPTY
    var nil = EMPTY
    var NIL = EMPTY

    // cons returns an APPLICATOR OF BINARY FUNCTIONS
    function cons(x, y) {
        if (x === null || typeof x === "undefined") throw "cannot cons without head";
        if (typeof(y) !== "function")   // y must be a function at any cost (but this check is 99% safe)
            throw "cannot cons without a function in the tail";
        var result = function(w) {
            return w(x, y);
        };
        // we  can safely freeze the string representation because cons is immutable
        result.c = consToString(result)
        return result;
    };

    // car returns the APPLICATION of a binary function to an APPLICATOR of binary functions
    function head(cons) {
        return cons(function (x, y) { return x; });
    };

    // cdr returns the APPLICATION of a binary function to an APPLICATOR of binary functions
    function tail(cons) {
        return cons(function (x, y) { return y; });
    };

    // WARNING: contains mutable vars!
    function List() {
        var bigCons = EMPTY;
        for (var i = arguments.length; i--; ) {
            bigCons = cons(arguments[i], bigCons);
        }
        return bigCons
    };

    // WARNING: contains mutable vars!
    function ArrayToList(anArray) {
        var bigCons = EMPTY;
        for (var i = anArray.length; i--; ) {
            // string, number or boolean
            //if (isAtom(anArray[i]))
            if (!Array.isArray(anArray[i]))
                bigCons = cons(anArray[i], bigCons);
            // else array
            else bigCons = cons(ArrayToList(anArray[i]), bigCons)
        }
        return bigCons
    }

    function isEmpty(list){
        return (list === EMPTY);
    }

    function isAtom(sexpr){
        return (typeof(sexpr) === "string" || typeof(sexpr) === "number" || typeof(sexpr) === "boolean");
    }

    function size(list) {
        if (isEmpty(list))
            return 0
        else
            return 1 + size(tail(list))
    }

    // as alternative you may invoke cons.c
    function consToString(cons) {
        var adder = function (curCons, acc) {
            if (isEmpty(curCons))
                return acc + "]"
            else if (isAtom(head(curCons)))
                return adder(tail(curCons), acc + head(curCons) + (isEmpty(tail(curCons)) ? "" : ","))
            else
                return adder(tail(curCons), acc + consToString(head(curCons)) + (isEmpty(tail(curCons)) ? "" : ","))
        }
        return adder(cons, "[")
    }

    function last(list) {
        if (isEmpty(tail(list)))
            return head(list)
        else
            return last(tail(list))
    }

    // all elements except the last one
    function listInit(list) {
        if (isEmpty(tail(list))) {
            return EMPTY;
        } else {
            return cons(head(list), listInit(tail(list)));
        }
    }

    function concat(list1, list2) {
        if (isEmpty(list1)) return list2
        else if (isEmpty(list2)) return list1
        else if (isEmpty(tail(list1)))
            return cons(head(list1), list2)
        else
            return cons(head(list1), concat(tail(list1), list2))
    }

    function reverse(list) {
        if (isEmpty(tail(list)))
            return list
        else
            return concat(reverse(tail(list)), cons(head(list), EMPTY))
    }

    function insert(elem, orderedList) {
        if (isEmpty(orderedList))
            return cons(elem, EMPTY)
        else if (elem < head(orderedList))
            return cons(elem, orderedList)
        else
            return cons(head(orderedList), insert(elem, tail(orderedList)))
    }

    function sort(list) {
        if (isEmpty(tail(list)))
            return list
        else
            return insert(head(list), sort(tail(list)))
    }

    // take(2,List(a,b,c,d,e)) --> List(a,b)
    function take(elems, list) { // elems = absolute number of list elements
        if (isEmpty(list) || size(list) === elems) return list
        else return take(elems, listInit(list))
    }

    // drop(2,List(a,b,c,d,e)) --> List(c,d,e)
    function drop(elems, list) { // elems = absolute number of list elements
        if (isEmpty(list) || elems === 0) return list
        else return drop(elems - 1, tail(list))
    }

    // index starts from 0
    function elementAt(index, list) {
        if (isEmpty(list)) return list
        else if (index === 0) return head(list)
        else return elementAt(index - 1, tail(list))
    }

    function isMember(atom, list) {
        if (isEmpty(list)) return false;
        else return (head(list) === atom) || (isMember(atom, tail(list)));
    }

    // index starts from 0
    function removeAt(index, list) {
        if (index < 0 || index > size(list)) return list
        return concat(take(index, list), drop(index + 1, list))
    }

    // it means "split after given element"
    function splitAt(elem,list) {
        if (elem<1) {
            return ({v1:List(),v2:list});
        } else if (elem>size(list)) {
            return ({v1:list,v2:List()});
        } else {
        var splitT = function (tuple) {
            var xs = tuple.v1, ys = tuple.v2;
            if (size(xs) === elem) return ({ v1: xs, v2: ys })
            else return splitT({ v1: concat(xs, List(head(ys))), v2: tail(ys) })
        }
            return splitT({v1:List(),v2:list})
        }
    }

    // Marco's
    function equalList(listA,listB) {
        if (size(listA) !== size(listB)) return false;
        var innerEq = function(alist,blist) {
            if (head(alist) !== head(blist)) return false;
            else if (isEmpty(tail(alist)) && isEmpty(tail(blist))) return true;
            else return innerEq(tail(alist),tail(blist));
        }
        return innerEq(listA,listB)
    }

    // Dionyzis's
    function equalList2( listA, listB ) {
        return isEmpty( listA ) && isEmpty( listB )
            ||    !isEmpty( listB )
              && !isEmpty( listB )
              && head( listA ) === head( listB )
              && equalList( tail( listA ), tail( listB ) );
    }

    function msort(list) {
        var n = Math.floor(size(list) / 2)
        if (n === 0)
            return list
        else {
            var mergeT = function (xs, ys) {
                if (isEmpty(xs))
                    return ys
                else if (isEmpty(ys))
                    return xs
                else { // both lists have at least one element
                    if (head(xs) <= head(ys))
                        return cons(head(xs), mergeT(tail(xs), ys))
                    else
                        return cons(head(ys), mergeT(xs, tail(ys)))
                }
            }
            var tuple = splitAt(n, list)
            return mergeT(msort(tuple.v1), msort(tuple.v2))
        }
    }

    // fold right
    function fold(f, v, xs) { return isEmpty(xs) ? v : f(head(xs), fold(f, v, tail(xs))); }

    // fold left
    function foldl(s, a, xs) { return isEmpty(xs) ? a : foldl(s, s(a, head(xs)), tail(xs)); }

    function first(list) { return head(list); }
    function second(list) { return head(tail(list)); }
    function third(list) { return head(tail(tail(list))); }

    return {
        nil: nil,
        cons: cons,
        car: head,
        cdr: tail,
        head: head,
        tail: tail,
        List: List,
        ArrayToList: ArrayToList,
        isEmpty: isEmpty,
        isAtom: isAtom,
        size: size,
        consToString: consToString,
        last: last,
        listInit: listInit,
        concat: concat,
        reverse: reverse,
        insert: insert,
        sort: sort,
        take: take,
        drop: drop,
        elementAt: elementAt,
        isMember: isMember,
        removeAt: removeAt,
        splitAt: splitAt,
        equalList: equalList,
        msort: msort,
        fold: fold,
        foldl: foldl,
        first: first,
        second: second,
        third: third
    }
}();
<|endoftext|>


<commit_before>var HID = require('node-hid');

var VENDOR_ID = 0x27B8;
var PRODUCT_ID = 0x01ED;

var REPORT_ID = 1;
var REPORT_LENGTH = 9;

var _blink1HIDdevices = function() {
  return HID.devices(VENDOR_ID, PRODUCT_ID);
};

var devices = function() {
  var serialNumbers = [];

  _blink1HIDdevices().forEach(function(device) {
    serialNumbers.push(device.serialNumber);
  });

  return serialNumbers;
};

function Blink1(serialNumber) {
  var blink1HIDdevices = _blink1HIDdevices();

  if (blink1HIDdevices.length === 0) {
    throw new Error('No blink(1)\'s could be found');
  }

  var blink1HIDdevicePath = null;

  if (serialNumber === undefined) {
    serialNumber =  blink1HIDdevices[0].serialNumber;
  }

  blink1HIDdevices.some(function(blink1HIDdevice) {
    if (serialNumber === blink1HIDdevice.serialNumber) {
      blink1HIDdevicePath = blink1HIDdevice.path;
    }

    return (blink1HIDdevicePath !== null);
  });

  if (blink1HIDdevicePath === null) {
    throw new Error('No blink(1)\'s with serial number ' + serialNumber + ' could be found');
  }

  this.serialNumber = serialNumber;
  this.hidDevice = new HID.HID(blink1HIDdevicePath);
}

Blink1.prototype._sendCommand = function(/* command [, args ...]*/) {
  var featureReport = [REPORT_ID, 0, 0, 0, 0, 0, 0, 0, 0];

  featureReport[1] = arguments[0].charCodeAt(0);

  for (var i = 1; i < arguments.length; i++) {
    featureReport[i + 1] = arguments[i];
  }

  this.hidDevice.sendFeatureReport(featureReport);
};

Blink1.prototype._isValidCallback = function(callback) {
  return (typeof callback === 'function');
};

Blink1.prototype._validateNumber = function(number, name, min, max) {
  if (typeof number !== 'number') {
    throw new Error(name + ' must be a number');
  }

  if (number < min || number > max) {
    throw new Error(name + ' must be between ' + min + ' and ' + max);
  }
};

Blink1.prototype._validateAddress = function(address) {
  this._validateNumber(address, 'address', 0, 0xffff);
};

Blink1.prototype._validateValue = function(value) {
  this._validateNumber(value, 'value', 0, 0xff);
};

Blink1.prototype._validateCount = function(value) {
  this._validateNumber(value, 'count', 0, 0xff);
};

Blink1.prototype._validateFadeMillis = function(fadeMillis) {
  this._validateNumber(fadeMillis, 'fadeMillis', 0, 0x9FFF6);
};

Blink1.prototype._validateRGB = function(r, g, b) {
  this._validateNumber(r, 'r', 0, 0xff);
  this._validateNumber(g, 'g', 0, 0xff);
  this._validateNumber(b, 'b', 0, 0xff);
};

Blink1.prototype._validateMillis = function(millis) {
  this._validateNumber(millis, 'millis', 0, 0x9FFF6);
};

Blink1.prototype._validatePosition = function(position) {
  this._validateNumber(position, 'position', 0, 11);
};

Blink1.prototype._validateMk2Position = function(position) {
  this._validateNumber(position, 'position', 0, 31);
};

Blink1.prototype._validateIndex = function(index) {
  this._validateNumber(index, 'index', 0, 2);
};

Blink1.prototype._readResponse = function(callback) {
  if (this._isValidCallback(callback)) {
    callback.apply(this, [this.hidDevice.getFeatureReport(REPORT_ID, REPORT_LENGTH)]);
  }
};

Blink1.prototype.version = function(callback) {
  this._sendCommand('v');

  this._readResponse(function(response) {
    var version = String.fromCharCode(response[3]) + '.' + String.fromCharCode(response[4]);

    if(this._isValidCallback(callback)) {
      callback(version);
    }
  });
};

Blink1.prototype.eeRead = function(address, callback) {
  this._validateAddress(address);

  this._sendCommand('e', address);

  this._readResponse(function(response) {
    var value = response[3];

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.eeWrite = function(address, value, callback) {
  this._validateAddress(address);
  this._validateValue(value);

  this._sendCommand('E', address, value);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.degamma = function(n) {
  return Math.floor(((1 << Math.floor(n / 32)) - 1) +
          Math.floor((1 << Math.floor(n / 32)) * Math.floor((n % 32) + 1) + 15) / 32);
};

Blink1.prototype.fadeToRGB = function(fadeMillis, r, g, b, index, nogamma, callback) {
  this._validateFadeMillis(fadeMillis);
  this._validateRGB(r, g, b);

  var dms = fadeMillis / 10;

  // time component cant be 0
  if( dms === 0 )
	dms = 1;

  if (this._isValidCallback(index)) {
    // backwards compatible API, no index
    callback = index;
    index = 0;
  } else if (index === undefined) {
    index = 0;
  }

  this._validateIndex(index);

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('c', cr, cg, cb, dms >> 8, dms % 0xff, index);

  if(this._isValidCallback(callback)) {
    setTimeout(callback, fadeMillis);
  }
};

Blink1.prototype.setRGB = function(r, g, b, index, nogamma, callback) {
  this._validateRGB(r, g, b);
  this._validateIndex(index);

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('n', cr, cg, cb, 0, 0, index);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.rgb = function(index, callback) {
  if (this._isValidCallback(index)) {
    callback = index;
    index = 0;
  } else if (index === undefined) {
    index = 0;
  }

  this._sendCommand('r', index, 0, 0, 0, 0, index);

  this._readResponse(function(response) {
    var r = response[2];
    var g = response[3];
    var b = response[4];

    if(this._isValidCallback(callback)) {
      callback(r, g, b);
    }
  });
};

Blink1.prototype._serverDown = function(on, millis, callback) {
  var dms = millis / 10;

  this._sendCommand('D', on, dms >> 8, dms % 0xff);

  if(this._isValidCallback(callback)) {
    setTimeout(callback, millis);
  }
};

Blink1.prototype.enableServerDown = function(millis, callback) {
  this._validateMillis(millis);

  this._serverDown(1, millis, callback);
};

Blink1.prototype.disableServerDown = function(millis, callback) {
  this._validateMillis(millis);

  this._serverDown(0, millis, callback);
};

Blink1.prototype._play = function(play, position, callback) {
  this._sendCommand('p', play, position);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.play = function(position, callback) {
  this._validateMk2Position(position);

  this._play(1, position, callback);
};

Blink1.prototype._playLoop = function(play, position, endPosition, count, callback) {
  this._sendCommand('p', play, position, endPosition, count);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.playLoop = function(startPosition, endPosition, count, callback) {
  this._validateMk2Position(startPosition);
  this._validateMk2Position(endPosition);
  this._validateCount(count);

  this._playLoop(1, startPosition, endPosition, count, callback);
};

Blink1.prototype.pause = function(callback) {
  this._play(0, 0, callback);
};

Blink1.prototype.writePatternLine = function(fadeMillis, r, g, b, position, nogamma, callback) {
  this._validateFadeMillis(fadeMillis);
  this._validateRGB(r, g, b);
  this._validateMk2Position(position);

  var dms = fadeMillis / 10;

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('P', cr, cg, cb, dms >> 8, dms % 0xff, position, 0);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.readPatternLine = function(position, callback) {
  this._validateMk2Position(position);

  this._sendCommand('R', 0, 0, 0, 0, 0, position, 0);

  this._readResponse(function(response) {
    var value = {
      r: response[2],
      g: response[3],
      b: response[4],
      fadeMillis: ((response[5] << 8) + (response[6] & 0xff)) * 10,
      ledn: response[7]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.readCurrentColor = function(ledn, callback) {
  this._validateIndex(ledn);

  this._sendCommand('r', 0, 0, 0, 0, 0, ledn);

  this._readResponse(function(response) {
    var value = {
      r: response[2],
      g: response[3],
      b: response[4],
      ledn: response[7]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.readPlayState = function(callback) {
  this._sendCommand('S');

  this._readResponse(function(response) {
    var value = {
      playing: response[2],
      playstart: response[3],
      playend: response[4],
      playcount: response[5],
      playpos: response[6]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.setLed = function(ledn, callback) {
  this._validateIndex(ledn);
  this._sendCommand('l', ledn);
  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.close = function(callback) {
	this.hidDevice.close();

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.devices = devices;

module.exports = Blink1;
module.exports.Blink1 = Blink1; // backwards compatibility with older version

<commit_msg>remove code that is only for mk1<commit_after>var HID = require('node-hid');

var VENDOR_ID = 0x27B8;
var PRODUCT_ID = 0x01ED;

var REPORT_ID = 1;
var REPORT_LENGTH = 9;

var _blink1HIDdevices = function() {
  return HID.devices(VENDOR_ID, PRODUCT_ID);
};

var devices = function() {
  var serialNumbers = [];

  _blink1HIDdevices().forEach(function(device) {
    serialNumbers.push(device.serialNumber);
  });

  return serialNumbers;
};

function Blink1(serialNumber) {
  var blink1HIDdevices = _blink1HIDdevices();

  if (blink1HIDdevices.length === 0) {
    throw new Error('No blink(1)\'s could be found');
  }

  var blink1HIDdevicePath = null;

  if (serialNumber === undefined) {
    serialNumber =  blink1HIDdevices[0].serialNumber;
  }

  blink1HIDdevices.some(function(blink1HIDdevice) {
    if (serialNumber === blink1HIDdevice.serialNumber) {
      blink1HIDdevicePath = blink1HIDdevice.path;
    }

    return (blink1HIDdevicePath !== null);
  });

  if (blink1HIDdevicePath === null) {
    throw new Error('No blink(1)\'s with serial number ' + serialNumber + ' could be found');
  }

  this.serialNumber = serialNumber;
  this.hidDevice = new HID.HID(blink1HIDdevicePath);
}

Blink1.prototype._sendCommand = function(/* command [, args ...]*/) {
  var featureReport = [REPORT_ID, 0, 0, 0, 0, 0, 0, 0, 0];

  featureReport[1] = arguments[0].charCodeAt(0);

  for (var i = 1; i < arguments.length; i++) {
    featureReport[i + 1] = arguments[i];
  }

  this.hidDevice.sendFeatureReport(featureReport);
};

Blink1.prototype._isValidCallback = function(callback) {
  return (typeof callback === 'function');
};

Blink1.prototype._validateNumber = function(number, name, min, max) {
  if (typeof number !== 'number') {
    throw new Error(name + ' must be a number');
  }

  if (number < min || number > max) {
    throw new Error(name + ' must be between ' + min + ' and ' + max);
  }
};

Blink1.prototype._validateAddress = function(address) {
  this._validateNumber(address, 'address', 0, 0xffff);
};

Blink1.prototype._validateValue = function(value) {
  this._validateNumber(value, 'value', 0, 0xff);
};

Blink1.prototype._validateCount = function(value) {
  this._validateNumber(value, 'count', 0, 0xff);
};

Blink1.prototype._validateFadeMillis = function(fadeMillis) {
  this._validateNumber(fadeMillis, 'fadeMillis', 0, 0x9FFF6);
};

Blink1.prototype._validateRGB = function(r, g, b) {
  this._validateNumber(r, 'r', 0, 0xff);
  this._validateNumber(g, 'g', 0, 0xff);
  this._validateNumber(b, 'b', 0, 0xff);
};

Blink1.prototype._validateMillis = function(millis) {
  this._validateNumber(millis, 'millis', 0, 0x9FFF6);
};

Blink1.prototype._validateMk2Position = function(position) {
  this._validateNumber(position, 'position', 0, 31);
};

Blink1.prototype._validateIndex = function(index) {
  this._validateNumber(index, 'index', 0, 2);
};

Blink1.prototype._readResponse = function(callback) {
  if (this._isValidCallback(callback)) {
    callback.apply(this, [this.hidDevice.getFeatureReport(REPORT_ID, REPORT_LENGTH)]);
  }
};

Blink1.prototype.version = function(callback) {
  this._sendCommand('v');

  this._readResponse(function(response) {
    var version = String.fromCharCode(response[3]) + '.' + String.fromCharCode(response[4]);

    if(this._isValidCallback(callback)) {
      callback(version);
    }
  });
};

Blink1.prototype.degamma = function(n) {
  return Math.floor(((1 << Math.floor(n / 32)) - 1) +
          Math.floor((1 << Math.floor(n / 32)) * Math.floor((n % 32) + 1) + 15) / 32);
};

Blink1.prototype.fadeToRGB = function(fadeMillis, r, g, b, index, nogamma, callback) {
  this._validateFadeMillis(fadeMillis);
  this._validateRGB(r, g, b);

  var dms = fadeMillis / 10;

  // time component cant be 0
  if( dms === 0 )
	dms = 1;

  if (this._isValidCallback(index)) {
    // backwards compatible API, no index
    callback = index;
    index = 0;
  } else if (index === undefined) {
    index = 0;
  }

  this._validateIndex(index);

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('c', cr, cg, cb, dms >> 8, dms % 0xff, index);

  if(this._isValidCallback(callback)) {
    setTimeout(callback, fadeMillis);
  }
};

Blink1.prototype.setRGB = function(r, g, b, index, nogamma, callback) {
  this._validateRGB(r, g, b);
  this._validateIndex(index);

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('n', cr, cg, cb, 0, 0, index);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.rgb = function(index, callback) {
  if (this._isValidCallback(index)) {
    callback = index;
    index = 0;
  } else if (index === undefined) {
    index = 0;
  }

  this._sendCommand('r', index, 0, 0, 0, 0, index);

  this._readResponse(function(response) {
    var r = response[2];
    var g = response[3];
    var b = response[4];

    if(this._isValidCallback(callback)) {
      callback(r, g, b);
    }
  });
};

Blink1.prototype._serverDown = function(on, millis, callback) {
  var dms = millis / 10;

  this._sendCommand('D', on, dms >> 8, dms % 0xff);

  if(this._isValidCallback(callback)) {
    setTimeout(callback, millis);
  }
};

Blink1.prototype.enableServerDown = function(millis, callback) {
  this._validateMillis(millis);

  this._serverDown(1, millis, callback);
};

Blink1.prototype.disableServerDown = function(millis, callback) {
  this._validateMillis(millis);

  this._serverDown(0, millis, callback);
};

Blink1.prototype._play = function(play, position, callback) {
  this._sendCommand('p', play, position);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.play = function(position, callback) {
  this._validateMk2Position(position);

  this._play(1, position, callback);
};

Blink1.prototype._playLoop = function(play, position, endPosition, count, callback) {
  this._sendCommand('p', play, position, endPosition, count);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.playLoop = function(startPosition, endPosition, count, callback) {
  this._validateMk2Position(startPosition);
  this._validateMk2Position(endPosition);
  this._validateCount(count);

  this._playLoop(1, startPosition, endPosition, count, callback);
};

Blink1.prototype.pause = function(callback) {
  this._play(0, 0, callback);
};

Blink1.prototype.writePatternLine = function(fadeMillis, r, g, b, position, nogamma, callback) {
  this._validateFadeMillis(fadeMillis);
  this._validateRGB(r, g, b);
  this._validateMk2Position(position);

  var dms = fadeMillis / 10;

  var cr = nogamma ? r : this.degamma(r);
  var cg = nogamma ? g : this.degamma(g);
  var cb = nogamma ? b : this.degamma(b);

  this._sendCommand('P', cr, cg, cb, dms >> 8, dms % 0xff, position, 0);

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.readPatternLine = function(position, callback) {
  this._validateMk2Position(position);

  this._sendCommand('R', 0, 0, 0, 0, 0, position, 0);

  this._readResponse(function(response) {
    var value = {
      r: response[2],
      g: response[3],
      b: response[4],
      fadeMillis: ((response[5] << 8) + (response[6] & 0xff)) * 10,
      ledn: response[7]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.readCurrentColor = function(ledn, callback) {
  this._validateIndex(ledn);

  this._sendCommand('r', 0, 0, 0, 0, 0, ledn);

  this._readResponse(function(response) {
    var value = {
      r: response[2],
      g: response[3],
      b: response[4],
      ledn: response[7]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.readPlayState = function(callback) {
  this._sendCommand('S');

  this._readResponse(function(response) {
    var value = {
      playing: response[2],
      playstart: response[3],
      playend: response[4],
      playcount: response[5],
      playpos: response[6]
    };

    if(this._isValidCallback(callback)) {
      callback(value);
    }
  });
};

Blink1.prototype.setLed = function(ledn, callback) {
  this._validateIndex(ledn);
  this._sendCommand('l', ledn);
  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.prototype.close = function(callback) {
	this.hidDevice.close();

  if(this._isValidCallback(callback)) {
    callback();
  }
};

Blink1.devices = devices;

module.exports = Blink1;
module.exports.Blink1 = Blink1; // backwards compatibility with older version

<|endoftext|>


<commit_before>import React from 'react';
import {storiesOf} from '@kadira/storybook';

import {Board} from '../src';

const data = require('./data.json');

function handleDragStart(cardId, laneId) {
  console.log('drag started')
  console.log(`cardId: ${cardId}`)
  console.log(`laneId: ${laneId}`)
}

function handleDragEnd(cardId, sourceLaneId, targetLaneId) {
  console.log('drag ended')
  console.log(`cardId: ${cardId}`)
  console.log(`sourceLaneId: ${sourceLaneId}`)
  console.log(`targetLaneId: ${targetLaneId}`)
}

storiesOf('react-trello', module)

  .add('Drag-n-Drop',
    () => (
      <Board
        data={data}
        draggable={true}
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
      />
    ))

<commit_msg>Show source in DragNDrop story<commit_after>import React from 'react';
import {storiesOf} from '@kadira/storybook';

import {Board} from '../src';

const data = require('./data.json');

storiesOf('react-trello', module)

  .addWithInfo('Drag-n-Drop',
    'A demonstration of onDragStart and onDragEnd hooks',
    () => {

      function handleDragStart(cardId, laneId) {
        console.log('drag started')
        console.log(`cardId: ${cardId}`)
        console.log(`laneId: ${laneId}`)
      }

      function handleDragEnd(cardId, sourceLaneId, targetLaneId) {
        console.log('drag ended')
        console.log(`cardId: ${cardId}`)
        console.log(`sourceLaneId: ${sourceLaneId}`)
        console.log(`targetLaneId: ${targetLaneId}`)
      }

      return <Board
        data={data}
        draggable={true}
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
      />
    }
  )

<|endoftext|>


<commit_before>(function($){
  var settings = {
    particle: 'star.png'
  , partoffset: 100
  };

  var methods = {
    init : function (options) {
      settings = $.extend(settings, options);
      return this;
    }
  , create_part: function () {
      tmp = $('<img />').addClass('jquery-particle');
      tmp.attr('src', settings.particle);
      this.append(tmp);
      x = Math.floor(Math.random() * settings.partoffset * 2) - settings.partoffset;
      y = Math.floor(Math.random() * settings.partoffset * 2) - settings.partoffset;
      tmp.animate(
        {'margin-top': x + 'px', 'margin-left': y + 'px', 'opacity': 1}
      , {
          'duration': Math.floor(Math.random() * 1000) + 1000
        , 'complete': function () {
            $(this).animate(
                {'opacity': 0}
              , {'complete': function () { $(this).remove(); }}
            )
          }
        }
      );
      return this;
    }
  , burst_part: function (i) {
      if (i > 0) {
        $this = this;
        methods['create_part'].apply($this);
        setTimeout(function () {
          methods['burst_part'].apply($this, [--i])
        }, Math.floor(Math.random() * 200));
      }
      return this;
    }
  };

  $.fn.pburst = function (method) {
    if (methods[method]) {
      return methods[method].apply( this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || ! method) {
      return methods.init.apply(this, arguments);
    } else {
      $.error('Method ' + method + ' does not exist on jQuery.particles.burst');
    }
  };

})(jQuery);

<commit_msg>Updated indentation with 4 spaces<commit_after>(function($){
    var settings = {
        particle: 'star.png'
      , partoffset: 100
    };

    var methods = {
        init : function (options) {
            settings = $.extend(settings, options);
            return this;
        }
      , create_part: function () {
            tmp = $('<img />').addClass('jquery-particle');
            tmp.attr('src', settings.particle);
            this.append(tmp);
            x = Math.floor(Math.random() * settings.partoffset * 2) - settings.partoffset;
            y = Math.floor(Math.random() * settings.partoffset * 2) - settings.partoffset;
            tmp.animate(
                {'margin-top': x + 'px', 'margin-left': y + 'px', 'opacity': 1}
              , {
                   'duration': Math.floor(Math.random() * 1000) + 1000
                 , 'complete': function () {
                       $(this).animate(
                           {'opacity': 0}
                         , {'complete': function () { $(this).remove(); }}
                       )
                   }
                }
            );
            return this;
        }
      , burst_part: function (i) {
          if (i > 0) {
              $this = this;
              methods['create_part'].apply($this);
              setTimeout(function () {
                  methods['burst_part'].apply($this, [--i])
              }, Math.floor(Math.random() * 200));
          }
          return this;
        }
    };

    $.fn.pburst = function (method) {
        if (methods[method]) {
            return methods[method].apply( this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || ! method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.particles.burst');
        }
    };

})(jQuery);

<|endoftext|>


<commit_before>const jwt = require('jsonwebtoken');
const api = require('../api');
const permissionsHelper = require('./permissions');

const rolesDisplayName = {
    'teacher': 'Lehrer',
    'student': 'Schüler',
    'administrator': 'Administrator',
    'superhero': 'Schul-Cloud Admin',
    'demo': 'Demo',
    'demoTeacher': 'Demo',
    'demoStudent': 'Demo',
    'helpdesk': 'Helpdesk',
    'betaTeacher': 'Beta',
};

const isJWT = (req) => {
    return (req && req.cookies && req.cookies.jwt);
};

const isAuthenticated = (req) => {
    if(!isJWT(req)) {
        return Promise.resolve(false);
    }

    return api(req).post('/authentication', {json: {
        strategy: 'jwt',
        accessToken: req.cookies.jwt
    }}).then(_ => {
        return true;
    }).catch(_ => {
        return false;
    });
};

const authChecker = (req, res, next) => {
    isAuthenticated(req)
        .then(isAuthenticated => {
            if(isAuthenticated) {

                // fetch user profile
                populateCurrentUser(req, res)
                    .then(_ => {
                        return checkConsent(req, res);
                    })
                    .then(_ => {
                        return restrictSidebar(req, res);
                    })
                    .then(_ => {
                        next();
                    })
					.catch(err=>{
						if(err=="firstLogin was not completed, redirecting..."){
							//print message?
							res.redirect('/firstLogin');
						}else{
							res.redirect('/login/');
						}
					});
            } else {
                res.redirect('/login/');
            }
        });
};

const populateCurrentUser = (req, res) => {
    let payload = {};
    if(isJWT(req)) {
        payload = (jwt.decode(req.cookies.jwt, {complete: true}) || {}).payload;
        res.locals.currentPayload = payload;
    }

    if(payload.userId) {
        return api(req).get('/users/' + payload.userId,{ qs: {
            $populate: ['roles']
        }}).then(data => {
            res.locals.currentUser = data;
            res.locals.currentRole = rolesDisplayName[data.roles[0].name];
            return api(req).get('/schools/' + res.locals.currentUser.schoolId, { qs: {
                $populate: ['federalState']
            }}).then(data => {
                res.locals.currentSchool = res.locals.currentUser.schoolId;
                res.locals.currentSchoolData = data;
                return data;
            });
        });
    }

    return Promise.resolve();
};

const checkConsent = (req, res) => {
    if (
    ((res.locals.currentUser||{}).preferences||{}).firstLogin ||	//do not exist if 3. system login
    req.path == "/login/success" ||
    req.baseUrl == "/firstLogin") {
        return Promise.resolve();
    }else{
		return Promise.reject("firstLogin was not completed, redirecting...");
	}
};

const restrictSidebar = (req, res) => {
    res.locals.sidebarItems = res.locals.sidebarItems.filter(item => {
        if(!item.permission) return true;

        return permissionsHelper.userHasPermission(res.locals.currentUser, item.permission);
    });
};

module.exports = {
    isJWT,
    authChecker,
    isAuthenticated,
    restrictSidebar,
    populateCurrentUser
};
<commit_msg>Fix login issue<commit_after>const jwt = require('jsonwebtoken');
const api = require('../api');
const permissionsHelper = require('./permissions');

const rolesDisplayName = {
    'teacher': 'Lehrer',
    'student': 'Schüler',
    'administrator': 'Administrator',
    'superhero': 'Schul-Cloud Admin',
    'demo': 'Demo',
    'demoTeacher': 'Demo',
    'demoStudent': 'Demo',
    'helpdesk': 'Helpdesk',
    'betaTeacher': 'Beta',
};

const isJWT = (req) => {
    return (req && req.cookies && req.cookies.jwt);
};

const isAuthenticated = (req) => {
    if(!isJWT(req)) {
        return Promise.resolve(false);
    }

    return api(req).post('/authentication', {json: {
        strategy: 'jwt',
        accessToken: req.cookies.jwt
    }}).then(_ => {
        return true;
    }).catch(_ => {
        return false;
    });
};

const authChecker = (req, res, next) => {
    isAuthenticated(req)
        .then(isAuthenticated => {
            if(isAuthenticated) {

                // fetch user profile
                populateCurrentUser(req, res)
                    .then(_ => {
                        return checkConsent(req, res);
                    })
                    .then(_ => {
                        return restrictSidebar(req, res);
                    })
                    .then(_ => {
                        next();
                    })
					.catch(err=>{
						if(err=="firstLogin was not completed, redirecting..."){
							//print message?
							res.redirect('/firstLogin');
						}else{
							res.redirect('/login/');
						}
					});
            } else {
                res.redirect('/login/');
            }
        });
};

const populateCurrentUser = (req, res) => {
    let payload = {};
    if(isJWT(req)) {
        payload = (jwt.decode(req.cookies.jwt, {complete: true}) || {}).payload;
        res.locals.currentPayload = payload;
    }

    if(payload.userId) {
        return api(req).get('/users/' + payload.userId,{ qs: {
            $populate: ['roles']
        }}).then(data => {
            res.locals.currentUser = data;
            res.locals.currentRole = rolesDisplayName[data.roles[0].name];
            return api(req).get('/schools/' + res.locals.currentUser.schoolId, { qs: {
                $populate: ['federalState']
            }}).then(data => {
                res.locals.currentSchool = res.locals.currentUser.schoolId;
                res.locals.currentSchoolData = data;
                return data;
            });
        });
    }

    return Promise.resolve();
};

const checkConsent = (req, res) => {
    if (
    ((res.locals.currentUser||{}).preferences||{}).firstLogin ||	//do not exist if 3. system login
    req.path.startsWith("/login/success") ||
    req.baseUrl.startsWith("/firstLogin")) {
        return Promise.resolve();
    }else{
		return Promise.reject("firstLogin was not completed, redirecting...");
	}
};

const restrictSidebar = (req, res) => {
    res.locals.sidebarItems = res.locals.sidebarItems.filter(item => {
        if(!item.permission) return true;

        return permissionsHelper.userHasPermission(res.locals.currentUser, item.permission);
    });
};

module.exports = {
    isJWT,
    authChecker,
    isAuthenticated,
    restrictSidebar,
    populateCurrentUser
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Language Technology Group and Interactive Graphics Systems Group, Technische Universität Darmstadt, Germany
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

define([
    'angular',
    'jquery-json',
    'ui-bootstrap',
    'ngAnimate',
    'ngFileSaver',
    'bootstrapFileField'
], function(angular) {
    'use strict';

    angular.module("myApp.history", ['ngFileSaver', 'ui.bootstrap', 'ngAnimate', 'bootstrap.fileField'])
        .config(function($uibTooltipProvider) {
        })
        .factory('historyFactory', [
            function() {
                return {
                    // See https://material.io/icons/
                    icons: {
                        'entity' : 'filter',
                        'metadata': 'description',
                        'time': 'schedule',
                        // TODO: Rename to timeExpression
                        'timeX': 'timeline',
                        // TODO: Merge and hide are not tracked as filter atm
                        "merge": 'supervisor_account',
                        "hide": 'visibility_off',
                        "edit": 'create',
                        "annotate": 'comment',
                        "fulltext": 'search',
                        "delete": 'not_interested',
                        "openDoc": 'book'
                    },
                    typeDescriptions: {
                      'entity': 'Entity Filter',
                      'metadata': 'Metadata Filter',
                      'time': 'Time Range',
                      'annotate': 'Entity Annotated',
                      'fulltext': 'Fulltext Search',
                      'openDoc': 'Document opened',
                      'edit': "Entity edited"
                    },
                    actions: {
                        'added': 'add',
                        'removed': 'remove',
                        'replaced': 'loop'
                    },
                    popover: {
                        template: 'tooltip_tmpl',
                        placement: 'bottom',
                        trigger: 'None',
                        isOpen: [],
                        promises: []
                    },
                    getIcon: function(type) {
                        return this.icons[type];
                    },
                    getActionIcon: function(type) {
                        return this.actions[type];
                    }
                }
            }
        ])
        .controller('HistoryController',
            [
                '$scope',
                '$timeout',
                'FileSaver',
                'ObserverService',
                'historyFactory',
                function ($scope, $timeout, FileSaver, ObserverService, historyFactory) {
                    $scope.observer = ObserverService;
                    $scope.factory = historyFactory;

                    $scope.observer_subscribe = function(history) { $scope.history = history; };
                    $scope.observer_subscribe_items = function(items) { $scope.historyItems = items; };
                    $scope.observer.subscribeHistory($scope.observer_subscribe);
                    $scope.observer.subscribeAllItems($scope.observer_subscribe_items);

                    $scope.observer.subscribeReset(function() {
                        //$scope.history.length = 0;
                    });

                    $scope.removeItem = function(item) {
                        $scope.observer.removeItem(item.id, item.type);
                    };

                    $scope.removeItem = function(filter) {
                        $scope.observer.removeItem(filter.id, filter.type);
                    };

                    $scope.hidePopover = function(id) {
                        $scope.factory.popover.promises[id] = $timeout(function() { $scope.hideFunction(id)}, 500);
                    };

                    $scope.showPopover = function(id) {
                        if($scope.factory.popover.promises[id] != undefined) $timeout.cancel($scope.factory.popover.promises[id]);
                        $scope.factory.popover.isOpen[id] = true;
                    };

                    $scope.hideFunction = function(x) {
                        $scope.factory.popover.isOpen[x] = false;
                    };

                    $scope.getTypeDescription = function(x) {
                        return $scope.factory.typeDescriptions[x];
                    };

                    $scope.setFilterState = function() {
                        //FileSaver.saveAs(new Blob([$.toJSON(savedata)], {type: 'text/plain;charset=UTF-8'}), "filters_" + Date.now() + ".txt")
                    };

                    $scope.saveHistory =  function() {
                        console.log("save state");
                        var json = JSON.stringify({
                            history: $scope.history,
                            items: $scope.historyItems
                        },null, 4);
                        var data = new Blob([json],
                        { type: 'application/json;charset=utf-8' });
                        FileSaver.saveAs(data, "saver.json");
                    };

                    $scope.loadHistory = function() {
                        console.log("load state");
                        $scope.reader = new FileReader();
                        $scope.reader.onload = function(){
                            $scope.observer.loadState(jQuery.parseJSON(angular.copy($scope.reader.result)));
                            $scope.uploadFile = undefined;
                        };
                        $scope.waitForFile = setInterval(function() {
                            if($scope.uploadFile) {
                                clearInterval($scope.waitForFile);
                                $scope.reader.readAsText($scope.uploadFile);
                            }
                        }, 500);

                    }
                }
            ]
        )
});<commit_msg>fixed hostory reset bug<commit_after>/*
 * Copyright (C) 2016 Language Technology Group and Interactive Graphics Systems Group, Technische Universität Darmstadt, Germany
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

define([
    'angular',
    'jquery-json',
    'ui-bootstrap',
    'ngAnimate',
    'ngFileSaver',
    'bootstrapFileField'
], function(angular) {
    'use strict';

    angular.module("myApp.history", ['ngFileSaver', 'ui.bootstrap', 'ngAnimate', 'bootstrap.fileField'])
        .config(function($uibTooltipProvider) {
        })
        .factory('historyFactory', [
            function() {
                return {
                    // See https://material.io/icons/
                    icons: {
                        'entity' : 'filter',
                        'metadata': 'description',
                        'time': 'schedule',
                        // TODO: Rename to timeExpression
                        'timeX': 'timeline',
                        // TODO: Merge and hide are not tracked as filter atm
                        "merge": 'supervisor_account',
                        "hide": 'visibility_off',
                        "edit": 'create',
                        "annotate": 'comment',
                        "fulltext": 'search',
                        "delete": 'not_interested',
                        "openDoc": 'book'
                    },
                    typeDescriptions: {
                      'entity': 'Entity Filter',
                      'metadata': 'Metadata Filter',
                      'time': 'Time Range',
                      'annotate': 'Entity Annotated',
                      'fulltext': 'Fulltext Search',
                      'openDoc': 'Document opened',
                      'edit': "Entity edited"
                    },
                    actions: {
                        'added': 'add',
                        'removed': 'remove',
                        'replaced': 'loop'
                    },
                    popover: {
                        template: 'tooltip_tmpl',
                        placement: 'bottom',
                        trigger: 'None',
                        isOpen: [],
                        promises: []
                    },
                    getIcon: function(type) {
                        return this.icons[type];
                    },
                    getActionIcon: function(type) {
                        return this.actions[type];
                    }
                }
            }
        ])
        .controller('HistoryController',
            [
                '$scope',
                '$timeout',
                'FileSaver',
                'ObserverService',
                'historyFactory',
                function ($scope, $timeout, FileSaver, ObserverService, historyFactory) {
                    $scope.observer = ObserverService;
                    $scope.factory = historyFactory;

                    $scope.observer_subscribe = function(history) { $scope.history = history; };
                    $scope.observer_subscribe_items = function(items) { $scope.historyItems = items; };
                    $scope.observer.subscribeHistory($scope.observer_subscribe);
                    $scope.observer.subscribeAllItems($scope.observer_subscribe_items);

                    $scope.observer.subscribeReset(function() {
                        $scope.history.splice(0);
                    });

                    $scope.removeItem = function(item) {
                        $scope.observer.removeItem(item.id, item.type);
                    };

                    $scope.removeItem = function(filter) {
                        $scope.observer.removeItem(filter.id, filter.type);
                    };

                    $scope.hidePopover = function(id) {
                        $scope.factory.popover.promises[id] = $timeout(function() { $scope.hideFunction(id)}, 500);
                    };

                    $scope.showPopover = function(id) {
                        if($scope.factory.popover.promises[id] != undefined) $timeout.cancel($scope.factory.popover.promises[id]);
                        $scope.factory.popover.isOpen[id] = true;
                    };

                    $scope.hideFunction = function(x) {
                        $scope.factory.popover.isOpen[x] = false;
                    };

                    $scope.getTypeDescription = function(x) {
                        return $scope.factory.typeDescriptions[x];
                    };

                    $scope.setFilterState = function() {
                        //FileSaver.saveAs(new Blob([$.toJSON(savedata)], {type: 'text/plain;charset=UTF-8'}), "filters_" + Date.now() + ".txt")
                    };

                    $scope.saveHistory =  function() {
                        console.log("save state");
                        var json = JSON.stringify({
                            history: $scope.history,
                            items: $scope.historyItems
                        },null, 4);
                        var data = new Blob([json],
                        { type: 'application/json;charset=utf-8' });
                        FileSaver.saveAs(data, "saver.json");
                    };

                    $scope.loadHistory = function() {
                        console.log("load state");
                        $scope.reader = new FileReader();
                        $scope.reader.onload = function(){
                            $scope.observer.loadState(jQuery.parseJSON(angular.copy($scope.reader.result)));
                            $scope.uploadFile = undefined;
                        };
                        $scope.waitForFile = setInterval(function() {
                            if($scope.uploadFile) {
                                clearInterval($scope.waitForFile);
                                $scope.reader.readAsText($scope.uploadFile);
                            }
                        }, 500);

                    }
                }
            ]
        )
});<|endoftext|>


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

  var document = node.ownerDocument;

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

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

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

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

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

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

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

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

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

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

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

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

  var document = node.ownerDocument;

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

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

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

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

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

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

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

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

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

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

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

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


<commit_before>// Install JSPrintSetup
function installjsPrintSetup() {
    //if (confirm("You don't have printer plugin.\nDo you want to install the Printer Plugin now?")) {
    if (confirm("No tienes instalado el plugin de la impresora.\nQuieres instalarlo ahora?")) {
        var xpi = new Object();
        xpi['jsprintsetup'] = '/bundles/inodataflora/downloads/jsprintsetup-0.9.2.xpi';
        InstallTrigger.install(xpi);
    }
}

//Define paper size
//39 : {PD:39, PN: 'na_fanfold-us',PWG:'na_fanfold-us_11x14.875in',Name: 'US Std Fanfold', W: 11, H: 14.875, M: kPaperSizeInches}
function definePaperSizes(){
  //note
  jsPrintSetup.definePaperSize(2, 2, 'na_letter', 'na_letter_8.5x11in', 'US Letter', 8.5, 5.5, jsPrintSetup.kPaperSizeInches);
  //card
  jsPrintSetup.definePaperSize(99, 99, 'na_letter', 'na_letter_8.5x11in', 'US Letter', 4.7, 5.5, jsPrintSetup.kPaperSizeInches);
}

function setupGlobalOptions(){
  //check if jsPrintSetup is installed
  if (typeof(jsPrintSetup) == 'undefined') {
          installjsPrintSetup();
  } else {
    // set page orientation.
    jsPrintSetup.setOption('orientation', jsPrintSetup.kPortraitOrientation);
    //jsPrintSetup.setOption('orientation', jsPrintSetup.kLandscapeOrientation);

    // set margins (in millimeters, firefox defaults 12.7mm).
    jsPrintSetup.setOption('marginTop', 0);
    jsPrintSetup.setOption('marginBottom', 0);
    jsPrintSetup.setOption('marginLeft', 0);
    jsPrintSetup.setOption('marginRight', 0);

    // set page header
    jsPrintSetup.setOption('headerStrLeft', '');
    jsPrintSetup.setOption('headerStrCenter', '');
    jsPrintSetup.setOption('headerStrRight', '');
    // set empty page footer
    jsPrintSetup.setOption('footerStrLeft', '');
    jsPrintSetup.setOption('footerStrCenter', '');
    jsPrintSetup.setOption('footerStrRight', '');

    definePaperSizes();

    // clears user preferences always silent print value
    // to enable using 'printSilent' option
    jsPrintSetup.clearSilentPrint();
    // Suppress print dialog (for this context only)
    jsPrintSetup.setOption('printSilent', 1);

  }
}

// Do Print
// When print is submitted it is executed asynchronous and
// script flow continues after print independently of completetion of print process!
//  jsPrintSetup.print();
function printCard(){
  setupGlobalOptions();
  jsPrintSetup.setPrinter('hpcolor');
  jsPrintSetup.setPaperSizeData(99);
  jsPrintSetup.print();
}

function printNote(){
  setupGlobalOptions();

  jsPrintSetup.setPrinter('hpcolor');
  jsPrintSetup.setPaperSizeData(2);
  jsPrintSetup.print();
}<commit_msg>Actualiza nombre de impresoras en produccion<commit_after>// Install JSPrintSetup
function installjsPrintSetup() {
    //if (confirm("You don't have printer plugin.\nDo you want to install the Printer Plugin now?")) {
    if (confirm("No tienes instalado el plugin de la impresora.\nQuieres instalarlo ahora?")) {
        var xpi = new Object();
        xpi['jsprintsetup'] = '/bundles/inodataflora/downloads/jsprintsetup-0.9.2.xpi';
        InstallTrigger.install(xpi);
    }
}

//Define paper size
//39 : {PD:39, PN: 'na_fanfold-us',PWG:'na_fanfold-us_11x14.875in',Name: 'US Std Fanfold', W: 11, H: 14.875, M: kPaperSizeInches}
function definePaperSizes(){
  //note
  jsPrintSetup.definePaperSize(2, 2, 'na_letter', 'na_letter_8.5x11in', 'US Letter', 8.5, 5.5, jsPrintSetup.kPaperSizeInches);
  //card
  jsPrintSetup.definePaperSize(99, 99, 'na_letter', 'na_letter_8.5x11in', 'US Letter', 4.7, 5.5, jsPrintSetup.kPaperSizeInches);
}

function setupGlobalOptions(){
  //check if jsPrintSetup is installed
  if (typeof(jsPrintSetup) == 'undefined') {
          installjsPrintSetup();
  } else {
    // set page orientation.
    jsPrintSetup.setOption('orientation', jsPrintSetup.kPortraitOrientation);
    //jsPrintSetup.setOption('orientation', jsPrintSetup.kLandscapeOrientation);

    // set margins (in millimeters, firefox defaults 12.7mm).
    jsPrintSetup.setOption('marginTop', 0);
    jsPrintSetup.setOption('marginBottom', 0);
    jsPrintSetup.setOption('marginLeft', 0);
    jsPrintSetup.setOption('marginRight', 0);

    // set page header
    jsPrintSetup.setOption('headerStrLeft', '');
    jsPrintSetup.setOption('headerStrCenter', '');
    jsPrintSetup.setOption('headerStrRight', '');
    // set empty page footer
    jsPrintSetup.setOption('footerStrLeft', '');
    jsPrintSetup.setOption('footerStrCenter', '');
    jsPrintSetup.setOption('footerStrRight', '');

    definePaperSizes();

    // clears user preferences always silent print value
    // to enable using 'printSilent' option
    jsPrintSetup.clearSilentPrint();
    // Suppress print dialog (for this context only)
    jsPrintSetup.setOption('printSilent', 1);

  }
}

// Do Print
// When print is submitted it is executed asynchronous and
// script flow continues after print independently of completetion of print process!
//  jsPrintSetup.print();
function printCard(){
  setupGlobalOptions();
  jsPrintSetup.setPrinter('Epson_xp001');
  jsPrintSetup.setPaperSizeData(99);
  jsPrintSetup.print();
}

function printNote(){
  setupGlobalOptions();

  jsPrintSetup.setPrinter('Epson_xp002');
  jsPrintSetup.setPaperSizeData(2);
  jsPrintSetup.print();
}<|endoftext|>


<commit_before>import {css} from 'aphrodite'
import sharedStyles from './shared-styles'
export default Links

function Links() {
  return (

      {getLinks().map((link, i) => (

          {link.title}

      ))}

  )
}

function getLinks() {
  return [
    {
      href: 'http://suggest.javascriptair.com',
      title: 'Suggest Episodes',
    },
    {
      href: 'mailto:javascriptair+website@gmail.com',
      alt: 'Email JavaScript Air',
      title: 'Contact us',
    },
    {
      href: '/guests',
      alt: 'Guests',
      title: 'All Show Guests',
    },
    {
      href: 'http://jsair.io/email',
      alt: 'Show Notes Email Registration',
      title: 'Show Notes Email Registration',
    },
    {
      href: '/deals',
      alt: 'Deals',
      title: 'Deals',
    },
  ]
}
<commit_msg>updated footer links to include All Links, Tips, and Picks (#107)<commit_after>import {css} from 'aphrodite'
import sharedStyles from './shared-styles'
export default Links

function Links() {
  return (

      {getLinks().map((link, i) => (

          {link.title}

      ))}

  )
}

function getLinks() {
  return [
    {
      href: 'http://suggest.javascriptair.com',
      title: 'Suggest Episodes',
    },
    {
      href: 'mailto:javascriptair+website@gmail.com',
      alt: 'Email JavaScript Air',
      title: 'Contact us',
    },
    {
      href: '/guests',
      alt: 'Guests',
      title: 'All Show Guests',
    },
    {
      href: 'http://jsair.io/email',
      alt: 'Show Notes Email Registration',
      title: 'Show Notes Email Registration',
    },
    {
      href: '/deals',
      alt: 'Deals',
      title: 'Deals',
    },
    {
      href: '/links-tips-picks',
      alt: 'All Links, Tips, and Picks ',
      title: 'All Links, Tips, and Picks ',
    },
  ]
}
<|endoftext|>


<commit_before>APP.controllers_loggedin.crowd_campaigns = (function() {

    function init() {
        if ($("section.crowdfunding-form").exists()) initCrowdfundingForm();
    }

    function initCrowdfundingForm() {

      APP.components.formValidation.init();
      APP.components.districtGraetzlInput();
      APP.components.addressInput();
      APP.components.search.userAutocomplete();

      $("textarea").autoResize();

      $('input[name="crowd_campaign[benefit]"]').on("change", function() {
        if ($(this).is(':checked')) {
          $(".benefit-fields").show();
        }
        else {
          $(".benefit-fields").hide();
        }
      }).change();

      $('.startdate').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        format: 'ddd, dd mmm, yyyy',
        hiddenName: true,
        min: true,
        onSet: function(context) {
          if (typeof context.select !== 'undefined') {
            var mindate = new Date(context.select);
            var maxdate = new Date(context.select);
            mindate.setDate(mindate.getDate() + 14); // Minimum 14 Days after Startdate
            maxdate.setMonth(maxdate.getMonth() + 2); // Maximum 2 Months after Startdate
            $('.enddate').pickadate('picker').set('min', mindate);
            $('.enddate').pickadate('picker').set('max', maxdate);
            if ($('input[name="crowd_campaign[enddate]"]').val() == '') {
              var enddate = new Date(context.select);
              enddate.setMonth(enddate.getMonth() + 1);
              $('.enddate').pickadate('picker').set('select', enddate); // Default 1 Monath after Startdate
            }
          }
        },
      });

      $('.enddate').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        format: 'ddd, dd mmm, yyyy',
        hiddenName: true,
        min: 15,
      });

      $('.crowdfunding-form').on('cocoon:after-insert', function(e, insertedItem, originalEvent) {
        $('.datepicker').pickadate({
          formatSubmit: 'yyyy-mm-dd',
          hiddenName: true,
          min: true
        });
      }).trigger('cocoon:after-insert');

      // max categories
      $(".crowd-categories input").on("change", function() {
        APP.components.formHelper.maxCategories($(this).parents(".cb-columns"), 3); // init on Change
      }).trigger('change');

      // Preview Project  - Save Form and Open Preview Modal
      $(".save-and-preview").on("click", function() {
        var form = $(".crowdfunding_form");
        var submit_url = form.attr('action');
        var submit_params = form.serialize();

        if (typeof formXhr !== 'undefined') { formXhr.abort(); }

        formXhr = $.ajax({
            type: "POST",
            url: submit_url,
            data: submit_params,
            success: function(){
              previewModal.open();
            }
        });
      });

      // PreviewModal and ModalPreviewSize
      var iframewidth = $(window).width() + 'px';
      var iframeheight = $(window).height() - 100 + 'px';
      if($(window).width() > 1050) {
        var iframewidth = '1050px';
      }
      var previewModal = new jBox('Modal', {
        addClass:'jBox jBoxCrowdPreview',
        content: $('#cf-preview'),
        closeOnEsc:true,
        closeOnClick:true,
        blockScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
        onOpen: function() {
          var iframe = document.getElementById("cfpreview");
          iframe.src = $("#cfpreview").data('url');
          iframe.style.width = iframewidth;
          iframe.style.height = iframeheight;
        },
      });

    }

    return {
      init: init
    };

})();
<commit_msg>isolateScroll<commit_after>APP.controllers_loggedin.crowd_campaigns = (function() {

    function init() {
        if ($("section.crowdfunding-form").exists()) initCrowdfundingForm();
    }

    function initCrowdfundingForm() {

      APP.components.formValidation.init();
      APP.components.districtGraetzlInput();
      APP.components.addressInput();
      APP.components.search.userAutocomplete();

      $("textarea").autoResize();

      $('input[name="crowd_campaign[benefit]"]').on("change", function() {
        if ($(this).is(':checked')) {
          $(".benefit-fields").show();
        }
        else {
          $(".benefit-fields").hide();
        }
      }).change();

      $('.startdate').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        format: 'ddd, dd mmm, yyyy',
        hiddenName: true,
        min: true,
        onSet: function(context) {
          if (typeof context.select !== 'undefined') {
            var mindate = new Date(context.select);
            var maxdate = new Date(context.select);
            mindate.setDate(mindate.getDate() + 14); // Minimum 14 Days after Startdate
            maxdate.setMonth(maxdate.getMonth() + 2); // Maximum 2 Months after Startdate
            $('.enddate').pickadate('picker').set('min', mindate);
            $('.enddate').pickadate('picker').set('max', maxdate);
            if ($('input[name="crowd_campaign[enddate]"]').val() == '') {
              var enddate = new Date(context.select);
              enddate.setMonth(enddate.getMonth() + 1);
              $('.enddate').pickadate('picker').set('select', enddate); // Default 1 Monath after Startdate
            }
          }
        },
      });

      $('.enddate').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        format: 'ddd, dd mmm, yyyy',
        hiddenName: true,
        min: 15,
      });

      $('.crowdfunding-form').on('cocoon:after-insert', function(e, insertedItem, originalEvent) {
        $('.datepicker').pickadate({
          formatSubmit: 'yyyy-mm-dd',
          hiddenName: true,
          min: true
        });
      }).trigger('cocoon:after-insert');

      // max categories
      $(".crowd-categories input").on("change", function() {
        APP.components.formHelper.maxCategories($(this).parents(".cb-columns"), 3); // init on Change
      }).trigger('change');

      // Preview Project  - Save Form and Open Preview Modal
      $(".save-and-preview").on("click", function() {
        var form = $(".crowdfunding_form");
        var submit_url = form.attr('action');
        var submit_params = form.serialize();

        if (typeof formXhr !== 'undefined') { formXhr.abort(); }

        formXhr = $.ajax({
            type: "POST",
            url: submit_url,
            data: submit_params,
            success: function(){
              previewModal.open();
            }
        });
      });

      // PreviewModal and ModalPreviewSize
      var iframewidth = $(window).width() + 'px';
      var iframeheight = $(window).height() - 100 + 'px';
      if($(window).width() > 1050) {
        var iframewidth = '1050px';
      }
      var previewModal = new jBox('Modal', {
        addClass:'jBox jBoxCrowdPreview',
        content: $('#cf-preview'),
        closeOnEsc:true,
        closeOnClick:true,
        blockScroll:true,
        isolateScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
        onOpen: function() {
          var iframe = document.getElementById("cfpreview");
          iframe.src = $("#cfpreview").data('url');
          iframe.style.width = iframewidth;
          iframe.style.height = iframeheight;
        },
      });

    }

    return {
      init: init
    };

})();
<|endoftext|>